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
This commit is contained in:
commit
86c2990327
31 changed files with 464 additions and 101 deletions
2
COPYING
2
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
|
||||
|
|
26
NEWS
26
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.
|
||||
|
|
2
README
2
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>,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
43
src/conf.c
43
src/conf.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
228
src/multicast_device.c
Normal file
228
src/multicast_device.c
Normal file
|
@ -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
|
13
src/net.c
13
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) {
|
|||
}
|
||||
}
|
||||
|
||||
free_connection_partially(c);
|
||||
|
||||
/* Check if this was our outgoing connection */
|
||||
|
||||
if(c->outgoing)
|
||||
retry_outgoing(c->outgoing);
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
72
src/subnet.c
72
src/subnet.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue