Merge branch 'master' into 1.1
Conflicts: src/net_packet.c src/openssl/rsagen.h src/protocol_auth.c src/protocol_key.c
This commit is contained in:
commit
886a6f61a1
13 changed files with 107 additions and 20 deletions
1
AUTHORS
1
AUTHORS
|
@ -10,6 +10,7 @@ Significant contributions from:
|
||||||
- Scott Lamb <slamb@slamb.org>
|
- Scott Lamb <slamb@slamb.org>
|
||||||
- Julien Muchembled <jm@jmuchemb.eu>
|
- Julien Muchembled <jm@jmuchemb.eu>
|
||||||
- Timothy Redaelli <timothy@redaelli.eu>
|
- Timothy Redaelli <timothy@redaelli.eu>
|
||||||
|
- Brandon Black <blblack@gmail.com>
|
||||||
|
|
||||||
These files are from other sources:
|
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
|
||||||
|
|
1
THANKS
1
THANKS
|
@ -4,6 +4,7 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Allesandro Gatti
|
* Allesandro Gatti
|
||||||
* Andreas van Cranenburgh
|
* Andreas van Cranenburgh
|
||||||
* Armijn Hemel
|
* Armijn Hemel
|
||||||
|
* Brandon Black
|
||||||
* Cris van Pelt
|
* Cris van Pelt
|
||||||
* Delf Eldkraft
|
* Delf Eldkraft
|
||||||
* dnk
|
* dnk
|
||||||
|
|
|
@ -255,6 +255,9 @@ a lookup if your DNS server is not responding.
|
||||||
This does not affect resolving hostnames to IP addresses from the
|
This does not affect resolving hostnames to IP addresses from the
|
||||||
host configuration files.
|
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
|
.It Va Interface Li = Ar interface
|
||||||
Defines the name of the interface corresponding to the virtual network device.
|
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.
|
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
|
||||||
|
@ -341,6 +344,16 @@ specified in the configuration file.
|
||||||
When this option is used the priority of the 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.
|
Increasing the priority may help to reduce latency and packet loss on the VPN.
|
||||||
|
|
||||||
|
.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
|
||||||
|
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.
|
||||||
|
|
||||||
.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental
|
.It Va StrictSubnets Li = yes | no Po no Pc Bq experimental
|
||||||
When this option is enabled tinc will only use Subnet statements which are
|
When this option is enabled tinc will only use Subnet statements which are
|
||||||
present in the host config files in the local
|
present in the host config files in the local
|
||||||
|
@ -353,6 +366,14 @@ and will only allow connections with nodes for which host config files are prese
|
||||||
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /hosts/
|
||||||
directory.
|
directory.
|
||||||
Setting this options also implicitly sets StrictSubnets.
|
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
|
.El
|
||||||
|
|
||||||
.Sh HOST CONFIGURATION FILES
|
.Sh HOST CONFIGURATION FILES
|
||||||
|
|
|
@ -163,3 +163,10 @@ int gettimeofday(struct timeval *tv, void *tz) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_MINGW
|
||||||
|
int usleep(long usec) {
|
||||||
|
Sleep(usec / 1000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@ static uint64_t device_total_out = 0;
|
||||||
|
|
||||||
bool setup_device(void) {
|
bool setup_device(void) {
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
bool t1q = false;
|
||||||
|
|
||||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||||
device = xstrdup(DEFAULT_DEVICE);
|
device = xstrdup(DEFAULT_DEVICE);
|
||||||
|
@ -84,6 +85,12 @@ bool setup_device(void) {
|
||||||
device_info = "Linux tun/tap device (tap mode)";
|
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;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(iface)
|
if(iface)
|
||||||
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
|
strncpy(ifr.ifr_name, iface, IFNAMSIZ);
|
||||||
|
|
||||||
|
|
|
@ -108,10 +108,13 @@ extern list_t *outgoing_list;
|
||||||
extern int maxoutbufsize;
|
extern int maxoutbufsize;
|
||||||
extern int seconds_till_retry;
|
extern int seconds_till_retry;
|
||||||
extern int addressfamily;
|
extern int addressfamily;
|
||||||
|
extern unsigned replaywin;
|
||||||
|
|
||||||
extern listen_socket_t listen_socket[MAXSOCKETS];
|
extern listen_socket_t listen_socket[MAXSOCKETS];
|
||||||
extern int listen_sockets;
|
extern int listen_sockets;
|
||||||
extern int keylifetime;
|
extern int keylifetime;
|
||||||
|
extern int udp_rcvbuf;
|
||||||
|
extern int udp_sndbuf;
|
||||||
extern bool do_prune;
|
extern bool do_prune;
|
||||||
extern char *myport;
|
extern char *myport;
|
||||||
extern int contradicting_add_edge;
|
extern int contradicting_add_edge;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||||
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
|
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
2010 Timothy Redaelli <timothy@redaelli.eu>
|
2010 Timothy Redaelli <timothy@redaelli.eu>
|
||||||
|
2010 Brandon Black <blblack@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -62,6 +63,8 @@ static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999
|
||||||
|
|
||||||
static void send_udppacket(node_t *, vpn_packet_t *);
|
static void send_udppacket(node_t *, vpn_packet_t *);
|
||||||
|
|
||||||
|
unsigned replaywin = 16;
|
||||||
|
|
||||||
#define MAX_SEQNO 1073741824
|
#define MAX_SEQNO 1073741824
|
||||||
|
|
||||||
// mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
|
// mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
|
||||||
|
@ -284,25 +287,32 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
|
||||||
inpkt->len -= sizeof inpkt->seqno;
|
inpkt->len -= sizeof inpkt->seqno;
|
||||||
inpkt->seqno = ntohl(inpkt->seqno);
|
inpkt->seqno = ntohl(inpkt->seqno);
|
||||||
|
|
||||||
if(inpkt->seqno != n->received_seqno + 1) {
|
if(replaywin) {
|
||||||
if(inpkt->seqno >= n->received_seqno + sizeof n->late * 8) {
|
if(inpkt->seqno != n->received_seqno + 1) {
|
||||||
logger(LOG_WARNING, "Lost %d packets from %s (%s)",
|
if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
|
||||||
inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
|
if(n->farfuture++ < replaywin >> 2) {
|
||||||
|
logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)",
|
||||||
memset(n->late, 0, sizeof n->late);
|
n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture);
|
||||||
} else if (inpkt->seqno <= n->received_seqno) {
|
return;
|
||||||
if((n->received_seqno >= sizeof n->late * 8 && inpkt->seqno <= n->received_seqno - sizeof n->late * 8) || !(n->late[(inpkt->seqno / 8) % sizeof n->late] & (1 << inpkt->seqno % 8))) {
|
}
|
||||||
logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
|
logger(LOG_WARNING, "Lost %d packets from %s (%s)",
|
||||||
n->name, n->hostname, inpkt->seqno, n->received_seqno);
|
inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
|
||||||
return;
|
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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
|
||||||
|
n->late[(i / 8) % replaywin] |= 1 << i % 8;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
|
|
||||||
n->late[(i / 8) % sizeof n->late] |= 1 << i % 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n->farfuture = 0;
|
||||||
|
n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
n->late[(inpkt->seqno / 8) % sizeof n->late] &= ~(1 << inpkt->seqno % 8);
|
|
||||||
|
|
||||||
if(inpkt->seqno > n->received_seqno)
|
if(inpkt->seqno > n->received_seqno)
|
||||||
n->received_seqno = inpkt->seqno;
|
n->received_seqno = inpkt->seqno;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
Copyright (C) 1998-2005 Ivo Timmermans,
|
Copyright (C) 1998-2005 Ivo Timmermans,
|
||||||
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
|
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
|
||||||
2006 Scott Lamb <slamb@slamb.org>
|
2006 Scott Lamb <slamb@slamb.org>
|
||||||
|
2010 Brandon Black <blblack@gmail.com>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -229,6 +230,7 @@ bool setup_myself(void) {
|
||||||
struct addrinfo *ai, *aip, hint = {0};
|
struct addrinfo *ai, *aip, hint = {0};
|
||||||
bool choice;
|
bool choice;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
int replaywin_int;
|
||||||
|
|
||||||
myself = new_node();
|
myself = new_node();
|
||||||
myself->connection = new_connection();
|
myself->connection = new_connection();
|
||||||
|
@ -358,6 +360,28 @@ bool setup_myself(void) {
|
||||||
} else
|
} else
|
||||||
maxtimeout = 900;
|
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(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
|
||||||
if(!strcasecmp(afname, "IPv4"))
|
if(!strcasecmp(afname, "IPv4"))
|
||||||
addressfamily = AF_INET;
|
addressfamily = AF_INET;
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
int addressfamily = AF_UNSPEC;
|
int addressfamily = AF_UNSPEC;
|
||||||
int maxtimeout = 900;
|
int maxtimeout = 900;
|
||||||
int seconds_till_retry = 5;
|
int seconds_till_retry = 5;
|
||||||
|
int udp_rcvbuf = 0;
|
||||||
|
int udp_sndbuf = 0;
|
||||||
|
|
||||||
listen_socket_t listen_socket[MAXSOCKETS];
|
listen_socket_t listen_socket[MAXSOCKETS];
|
||||||
int listen_sockets;
|
int listen_sockets;
|
||||||
|
@ -260,6 +262,12 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
|
||||||
option = 1;
|
option = 1;
|
||||||
setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (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)))
|
||||||
|
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(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno));
|
||||||
|
|
||||||
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
||||||
if(sa->sa.sa_family == AF_INET6)
|
if(sa->sa.sa_family == AF_INET6)
|
||||||
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
|
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
|
||||||
|
|
|
@ -62,6 +62,7 @@ void exit_nodes(void) {
|
||||||
node_t *new_node(void) {
|
node_t *new_node(void) {
|
||||||
node_t *n = xmalloc_and_zero(sizeof *n);
|
node_t *n = xmalloc_and_zero(sizeof *n);
|
||||||
|
|
||||||
|
if(replaywin) n->late = xmalloc_and_zero(replaywin);
|
||||||
n->subnet_tree = new_subnet_tree();
|
n->subnet_tree = new_subnet_tree();
|
||||||
n->edge_tree = new_edge_tree();
|
n->edge_tree = new_edge_tree();
|
||||||
n->mtu = MTU;
|
n->mtu = MTU;
|
||||||
|
@ -92,6 +93,9 @@ void free_node(node_t *n) {
|
||||||
if(n->name)
|
if(n->name)
|
||||||
free(n->name);
|
free(n->name);
|
||||||
|
|
||||||
|
if(n->late)
|
||||||
|
free(n->late);
|
||||||
|
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,8 @@ typedef struct node_t {
|
||||||
|
|
||||||
uint32_t sent_seqno; /* Sequence number last sent to this node */
|
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_seqno; /* Sequence number last received from this node */
|
||||||
unsigned char late[16]; /* Bitfield marking late packets */
|
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 mtu; /* Maximum size of packets to send to this node */
|
||||||
length_t minmtu; /* Probed minimum MTU */
|
length_t minmtu; /* Probed minimum MTU */
|
||||||
|
|
|
@ -263,7 +263,7 @@ bool detach(void) {
|
||||||
bool execute_script(const char *name, char **envp) {
|
bool execute_script(const char *name, char **envp) {
|
||||||
#ifdef HAVE_SYSTEM
|
#ifdef HAVE_SYSTEM
|
||||||
int status, len;
|
int status, len;
|
||||||
char *scriptname, *p;
|
char *scriptname;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifndef HAVE_MINGW
|
#ifndef HAVE_MINGW
|
||||||
|
@ -304,7 +304,7 @@ bool execute_script(const char *name, char **envp) {
|
||||||
for(i = 0; envp[i]; i++) {
|
for(i = 0; envp[i]; i++) {
|
||||||
char *e = strchr(envp[i], '=');
|
char *e = strchr(envp[i], '=');
|
||||||
if(e) {
|
if(e) {
|
||||||
p = alloca(e - envp[i] + 1);
|
char p[e - envp[i] + 1];
|
||||||
strncpy(p, envp[i], e - envp[i]);
|
strncpy(p, envp[i], e - envp[i]);
|
||||||
p[e - envp[i]] = '\0';
|
p[e - envp[i]] = '\0';
|
||||||
putenv(p);
|
putenv(p);
|
||||||
|
|
|
@ -156,7 +156,7 @@ bool send_ans_key(node_t *to) {
|
||||||
// Reset sequence number and late packet window
|
// Reset sequence number and late packet window
|
||||||
mykeyused = true;
|
mykeyused = true;
|
||||||
to->received_seqno = 0;
|
to->received_seqno = 0;
|
||||||
memset(to->late, 0, sizeof(to->late));
|
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 %zu %d", ANS_KEY,
|
||||||
myself->name, to->name, key,
|
myself->name, to->name, key,
|
||||||
|
|
Loading…
Reference in a new issue