]> git.meshlink.io Git - meshlink/commitdiff
Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1
authorGuus Sliepen <guus@tinc-vpn.org>
Sun, 25 Mar 2012 22:35:31 +0000 (23:35 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 25 Mar 2012 22:35:31 +0000 (23:35 +0100)
Conflicts:
NEWS
README
configure.in
src/Makefile.am
src/conf.c
src/conf.h
src/connection.c
src/net.c
src/tincd.c

31 files changed:
COPYING
NEWS
README
doc/tinc.conf.5.in
doc/tinc.texi
src/Makefile.am
src/conf.c
src/conf.h
src/connection.c
src/connection.h
src/device.h
src/graph.c
src/graph.h
src/ipv4.h
src/ipv6.h
src/multicast_device.c [new file with mode: 0644]
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/node.h
src/protocol.c
src/protocol_auth.c
src/protocol_edge.c
src/protocol_key.c
src/protocol_misc.c
src/route.c
src/route.h
src/subnet.c
src/tincd.c
src/vde_device.c

diff --git a/COPYING b/COPYING
index 74fe22a07f10902dc399c25913ccd809b46e8e2b..85c729f1b956cfb051fb6176d440dc7e647affab 100644 (file)
--- 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/NEWS b/NEWS
index 36f50606cd4bddad0c8cf063143dadd8b734560d..a3850477a70ce6b8df7a2d00c1273bbf6e98e09c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,32 @@ 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.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.
diff --git a/README b/README
index 09f6e6e9e60cbaee09d7ed5b7cefb58f226e6a74..f978028b806d5644a1ba3a20df06cc3ab31fa326 100644 (file)
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
 This is the README file for tinc version 1.1pre2. 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 <guus@tinc-vpn.org>,
index 99b987772ad0157ded52790323888eb1c1bd1000..8f19de068ba90d4caaa29d09eab5356f836bccb4 100644 (file)
@@ -129,7 +129,7 @@ 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 Oo Ar port Oc 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.
@@ -137,7 +137,16 @@ 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 .
 .Pp
 This option may not work on all platforms.
 
@@ -171,13 +180,15 @@ 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 yes Pc
+.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.
@@ -210,6 +221,16 @@ 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 ,
@@ -467,7 +488,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.
@@ -558,12 +579,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
index 526a6c96e5ced1ec8fc3b5561b734752d99f9615..b4fb1f130ca02040308295e007b962a1f7060996 100644 (file)
@@ -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 <guus@@tinc-vpn.org> and
 Wessel Dankers <wsl@@tinc-vpn.org>.
 
@@ -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 <guus@@tinc-vpn.org> and
 Wessel Dankers <wsl@@tinc-vpn.org>.
 
@@ -779,12 +779,16 @@ 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}>] [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
@@ -813,12 +817,14 @@ tinc won't try to connect to other daemons at all,
 and will instead just listen for incoming connections.
 
 @cindex DecrementTTL
-@item DecrementTTL = <yes | no> (yes)
+@item DecrementTTL = <yes | no> (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.
@@ -849,6 +855,14 @@ 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
@@ -1186,12 +1200,11 @@ 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
@@ -2606,7 +2619,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}
@@ -2628,6 +2640,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
index 255ce3407f154f38e9021c0e4e6f4e63e3152081..e383e1f48eea7ed9e5ac3e8149e37398d046a206 100644 (file)
@@ -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 tincd.c \
-       dummy_device.c raw_socket_device.c
+       dummy_device.c raw_socket_device.c multicast_device.c
        
 if UML
 tincd_SOURCES += uml_device.c
index d7df4e96893e240a9ae4616dfa53177be5989dd0..f580a203d9275ce99e057deca263f4d1ea25ff29 100644 (file)
@@ -2,7 +2,7 @@
     conf.c -- configuration code
     Copyright (C) 1998 Robert van der Meulen
                   1998-2005 Ivo Timmermans
-                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2010-2011 Julien Muchembled <jm@jmuchemb.eu>
                  2000 Cris van Pelt
 
@@ -413,47 +413,8 @@ bool append_config_file(const char *name, const char *key, const char *value) {
                fclose(fp);
        }
 
+
        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;
-}
index 1ae5b73541c4b1a4ff9ffb8b9c2e480355ed2850..743851a70b9b7cade29f0802c23393c08c4b4af3 100644 (file)
@@ -1,7 +1,7 @@
 /*
     conf.h -- header for conf.c
     Copyright (C) 1998-2005 Ivo Timmermans
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -62,6 +62,5 @@ 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 append_config_file(const char *, const char *, const char *);
-extern bool disable_old_keys(FILE *);
 
 #endif                                                 /* __TINC_CONF_H__ */
index ee44e539acabadccf7a5818519a593eaec0b5495..dd5244860bfea4df1ff31d0f8cb9711b8409f027 100644 (file)
@@ -1,6 +1,6 @@
 /*
     connection.c -- connection list management
-    Copyright (C) 2000-2009 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
                   2000-2005 Ivo Timmermans
                   2008      Max Rijevski <maksuf@gmail.com>
 
@@ -54,16 +54,7 @@ connection_t *new_connection(void) {
        return xmalloc_and_zero(sizeof(connection_t));
 }
 
-void free_connection(connection_t *c) {
-       if(!c)
-               return;
-
-       if(c->name)
-               free(c->name);
-
-       if(c->hostname)
-               free(c->hostname);
-
+void free_connection_partially(connection_t *c) {
        cipher_close(&c->incipher);
        digest_close(&c->indigest);
        cipher_close(&c->outcipher);
@@ -76,9 +67,6 @@ void free_connection(connection_t *c) {
        if(c->hischallenge)
                free(c->hischallenge);
 
-       if(c->config_tree)
-               exit_configuration(&c->config_tree);
-
        buffer_clear(&c->inbuf);
        buffer_clear(&c->outbuf);
        
@@ -91,6 +79,21 @@ void free_connection(connection_t *c) {
        if(c->socket > 0)
                closesocket(c->socket);
 
+       c->socket = -1;
+}
+
+void free_connection(connection_t *c) {
+       if(!c)
+               return;
+
+       free_connection_partially(c);
+
+       free(c->name);
+       free(c->hostname);
+
+       if(c->config_tree)
+               exit_configuration(&c->config_tree);
+
        free(c);
 }
 
index 58eea4e694742ab26d0af94b39177493bbb41bbb..2b6870e41c60d90260c0f2e561f237268c9fdd89 100644 (file)
@@ -107,6 +107,7 @@ 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 free_connection_partially(connection_t *);
 extern void connection_add(connection_t *);
 extern void connection_del(connection_t *);
 extern bool dump_connections(struct connection_t *);
index 993d4ce82698a49bba569b3c03bd024ab9790422..e28647db8b83427ee2b828330b31795c2f3d6284 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.h -- generic header for device.c
     Copyright (C) 2001-2005 Ivo Timmermans
-                  2001-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2001-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -43,6 +43,7 @@ typedef struct 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 uml_devops;
 extern const devops_t vde_devops;
 extern devops_t devops;
index 4a9af9bc3cd5fa080fdb7ac184c73465163d02a4..d432023e496f4eb790804d545262a91ddfc07034 100644 (file)
@@ -1,6 +1,6 @@
 /*
     graph.c -- graph algorithms
-    Copyright (C) 2001-2011 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
                   2001-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
index fb4109614c67e4f9742a9bcb425ea419d5e610f4..fa521f53fbf2b81767b0f8ac28e0d6ad799d469d 100644 (file)
@@ -1,6 +1,6 @@
 /*
     graph.h -- header for graph.c
-    Copyright (C) 2001-2006 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
                   2001-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
index 57d236d33115f901ce2087834917b4214bf42826..bd63ad04785e559c93eb18b53ed6fc0482ff3643 100644 (file)
@@ -1,7 +1,7 @@
 /*
     ipv4.h -- missing IPv4 related definitions
     Copyright (C) 2005 Ivo Timmermans
-                  2006 Guus Sliepen <guus@tinc-vpn.org>
+                  2006-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index d98001d6a0c2569ad26358a0d43fd5f0f561eec2..6a4466f11d37e652121a11037e11eab4b09d1c77 100644 (file)
@@ -1,7 +1,7 @@
 /*
     ipv6.h -- missing IPv6 related definitions
     Copyright (C) 2005 Ivo Timmermans
-                  2006 Guus Sliepen <guus@tinc-vpn.org>
+                  2006-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -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/multicast_device.c b/src/multicast_device.c
new file mode 100644 (file)
index 0000000..e5e9a3f
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+    device.c -- multicast socket
+    Copyright (C) 2002-2005 Ivo Timmermans,
+                  2002-2012 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "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;
+       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);
+               return false;
+       }
+
+       host = xstrdup(device);
+       space = strchr(host, ' ');
+       if(!space) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Port number required for %s", device_info);
+               return false;
+       }
+
+       *space++ = 0;
+       port = space;
+       space = strchr(port, ' ');
+
+       if(space) {
+               *space++ = 0;
+               ttl = atoi(space);
+       }
+
+       ai = str2addrinfo(host, port, SOCK_DGRAM);
+       if(!ai)
+               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));
+               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(DEBUG_ALWAYS, LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno));
+               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(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
+                               closesocket(device_fd);
+                               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(DEBUG_ALWAYS, LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
+                               closesocket(device_fd);
+                               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(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family);
+                       closesocket(device_fd);
+                       return false;
+       }
+
+       logger(DEBUG_ALWAYS, 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, 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
index 10a2d20645951081fef4c68e70fdf4e97f8df111..db5743af2e9179915aca7686ac5c7fa497050746 100644 (file)
--- 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-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2006      Scott Lamb <slamb@slamb.org>
                  2011      Loïc Grenié <loic.grenie@gmail.com>
 
@@ -139,12 +139,13 @@ void terminate_connection(connection_t *c, bool report) {
                }
        }
 
-       /* Check if this was our outgoing connection */
+       free_connection_partially(c);
 
-       if(c->outgoing)
-               retry_outgoing(c->outgoing);
+       /* Check if this was our outgoing connection */
 
-       connection_del(c);
+       if(c->outgoing) {
+               do_outgoing_connection(c);      
+       }
 }
 
 /*
@@ -171,7 +172,7 @@ static void timeout_handler(int fd, short events, void *event) {
                        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, now - c->last_ping_time);
+                                                          c->name, c->hostname, (long)now - c->last_ping_time);
                                        terminate_connection(c, true);
                                        continue;
                                } else if(c->last_ping_time + pinginterval <= now) {
index 6ca13d488a307cdea812521c88c4568009fcdfa8..27b5eb5b5a8e31ed5c53acbb643b5960fbb6e535 100644 (file)
--- 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 <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index ac3b0cc59d1db6139cf5d33e10658783dc8dd67f..ca6aff3d9890e66051c227a8dcccb251bb420524 100644 (file)
@@ -1,7 +1,7 @@
 /*
     net_packet.c -- Handles in- and outgoing VPN packets
     Copyright (C) 1998-2005 Ivo Timmermans,
-                  2000-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2010      Timothy Redaelli <timothy@redaelli.eu>
                   2010      Brandon Black <blblack@gmail.com>
 
index 28e086440ee168c1a305cd217f262e3e577e9cf8..c181df9472e78c07f0e1ea6efae2d27259d9d574 100644 (file)
@@ -596,6 +596,8 @@ static bool setup_myself(void) {
                        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;
@@ -645,12 +647,25 @@ static bool setup_myself(void) {
                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;
 
-               err = getaddrinfo(address, myport, &hint, &ai);
+               err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai);
                free(address);
 
                if(err || !ai) {
index e86aa6a012e58523c4b9c74b7f71c5024d9d602d..62ed3acd575fe66d92c8a46b8f2738286c7e882e 100644 (file)
@@ -1,6 +1,6 @@
 /*
     node.h -- header for node.c
-    Copyright (C) 2001-2010 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
                   2001-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
index 8b62916b523505cebb6c4f10a06c0eef11bbfc8f..52ea69029b18286a96a19473018b0bee780dfaec 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol.c -- handle the meta-protocol, basic functions
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index 3bf18b21cb2dbf4747b038b4ef52106fa1eedd22..406ec4f9baffdf7593b052a1b5a2b598e036b987 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_auth.c -- handle the meta-protocol, authentication
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index bf283dd667949caad12e90f79c7f22ba4e9ae039..e8b3326b752b29f6077044943850421353692553 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_edge.c -- handle the meta-protocol, edges
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2009      Michael Tokarev <mjt@corpit.ru>
 
     This program is free software; you can redistribute it and/or modify
index c62c04814412774d60a8182ff03dda5b4fd3e064..7e645d487e8dc85a271f464701a492191acb28a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_key.c -- handle the meta-protocol, key exchange
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index 37bc110aaba0cb69ece85cc316acd2afd0ee2de4..0f95b0beeb4d0ba60df147ac8390b745e68af3f7 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_misc.c -- handle the meta-protocol, miscellaneous functions
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -107,8 +107,14 @@ bool pong_h(connection_t *c, char *request) {
 
        /* 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;
 }
index c76046689352dbdf72700844ff77dad5bc22d34c..5bf6e926724a664618b9fe0707125dc3318ddd87 100644 (file)
@@ -1,7 +1,7 @@
 /*
     route.c -- routing
     Copyright (C) 2000-2005 Ivo Timmermans,
-                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@
 
 rmode_t routing_mode = RMODE_ROUTER;
 fmode_t forwarding_mode = FMODE_INTERNAL;
-bool decrement_ttl = true;
+bool decrement_ttl = false;
 bool directonly = false;
 bool priorityinheritance = false;
 int macexpire = 600;
index 44023fdb3efff73dfd9dd474fa41a9c3c8527cd4..46dc3bdb44e2cfe1cb39d96a72d125c9892652c0 100644 (file)
@@ -1,7 +1,7 @@
 /*
     route.h -- header file for route.c
     Copyright (C) 2000-2005 Ivo Timmermans
-                  2000-2006 Guus Sliepen <guus@tinc-vpn.org>         
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>         
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
index e1de1012337987eb2760f41b169ec8d7366dc479..63d169fe2e4abac6ec263827b6e11b536b401be4 100644 (file)
@@ -269,6 +269,78 @@ bool str2net(subnet_t *subnet, const char *subnetstr) {
                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;
 }
 
index a78ca0c4a7e1bdc5bae92c7353a397efcf8085ee..1008f88aaec0865a5c604594f586f277a83f9f60 100644 (file)
@@ -1,7 +1,7 @@
 /*
     tincd.c -- the main file for tincd
     Copyright (C) 1998-2005 Ivo Timmermans
-                  2000-2011 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
                   2008      Max Rijevski <maksuf@gmail.com>
                   2009      Michael Tokarev <mjt@tls.msk.ru>
                   2010      Julien Muchembled <jm@jmuchemb.eu>
@@ -359,7 +359,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-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"
index ab2ffdcd70617bc174dddb490f1982cd1f13eb3d..815b956fbeae12f417fde3633f3f870196a484be 100644 (file)
@@ -99,7 +99,7 @@ static void close_device(void) {
 }
 
 static bool read_packet(vpn_packet_t *packet) {
-       int lenin = plug.vde_recv(conn, packet->data, 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));
                running = false;
@@ -114,7 +114,7 @@ static bool read_packet(vpn_packet_t *packet) {
 }
 
 static bool write_packet(vpn_packet_t *packet) {
-       if(plug.vde_send(conn, packet->data, 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));
                        running = false;