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:
Guus Sliepen 2010-11-19 12:22:48 +00:00
commit 886a6f61a1
13 changed files with 107 additions and 20 deletions

View file

@ -10,6 +10,7 @@ Significant contributions from:
- Scott Lamb <slamb@slamb.org>
- Julien Muchembled <jm@jmuchemb.eu>
- Timothy Redaelli <timothy@redaelli.eu>
- Brandon Black <blblack@gmail.com>
These files are from other sources:
* lib/pidfile.h and lib/pidfile.c are by Martin Schulze, taken from

1
THANKS
View file

@ -4,6 +4,7 @@ We would like to thank the following people for their contributions to tinc:
* Allesandro Gatti
* Andreas van Cranenburgh
* Armijn Hemel
* Brandon Black
* Cris van Pelt
* Delf Eldkraft
* dnk

View file

@ -255,6 +255,9 @@ a lookup if your DNS server is not responding.
This does not affect resolving hostnames to IP addresses from the
host configuration files.
.It Va IffOneQueue Li = yes | no Po no Pc Bq experimental
(Linux only) Set IFF_ONE_QUEUE flag on TUN/TAP devices.
.It Va Interface Li = Ar interface
Defines the name of the interface corresponding to the virtual network device.
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
@ -341,6 +344,16 @@ specified in the configuration file.
When this option is used the priority of the tincd process will be adjusted.
Increasing the priority may help to reduce latency and packet loss on the VPN.
.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
When this option is enabled tinc will only use Subnet statements which are
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/
directory.
Setting this options also implicitly sets StrictSubnets.
.It Va UDPRcvBuf Li = Ar bytes Pq OS default
Sets the socket receive buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
.It Va UDPSndBuf Li = Ar bytes Pq OS default
Sets the socket send buffer size for the UDP socket, in bytes.
If unset, the default buffer size will be used by the operating system.
.El
.Sh HOST CONFIGURATION FILES

View file

@ -163,3 +163,10 @@ int gettimeofday(struct timeval *tv, void *tz) {
return 0;
}
#endif
#ifdef HAVE_MINGW
int usleep(long usec) {
Sleep(usec / 1000);
return 0;
}
#endif

View file

@ -52,6 +52,7 @@ static uint64_t device_total_out = 0;
bool setup_device(void) {
struct ifreq ifr;
bool t1q = false;
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = xstrdup(DEFAULT_DEVICE);
@ -84,6 +85,12 @@ bool setup_device(void) {
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)
strncpy(ifr.ifr_name, iface, IFNAMSIZ);

View file

@ -108,10 +108,13 @@ extern list_t *outgoing_list;
extern int maxoutbufsize;
extern int seconds_till_retry;
extern int addressfamily;
extern unsigned replaywin;
extern listen_socket_t listen_socket[MAXSOCKETS];
extern int listen_sockets;
extern int keylifetime;
extern int udp_rcvbuf;
extern int udp_sndbuf;
extern bool do_prune;
extern char *myport;
extern int contradicting_add_edge;

View file

@ -3,6 +3,7 @@
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
This 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 +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 *);
unsigned replaywin = 16;
#define MAX_SEQNO 1073741824
// 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->seqno = ntohl(inpkt->seqno);
if(inpkt->seqno != n->received_seqno + 1) {
if(inpkt->seqno >= n->received_seqno + sizeof n->late * 8) {
logger(LOG_WARNING, "Lost %d packets from %s (%s)",
inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
memset(n->late, 0, sizeof n->late);
} else if (inpkt->seqno <= n->received_seqno) {
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",
n->name, n->hostname, inpkt->seqno, n->received_seqno);
return;
if(replaywin) {
if(inpkt->seqno != n->received_seqno + 1) {
if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
if(n->farfuture++ < replaywin >> 2) {
logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)",
n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture);
return;
}
logger(LOG_WARNING, "Lost %d packets from %s (%s)",
inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
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)
n->received_seqno = inpkt->seqno;

View file

@ -3,6 +3,7 @@
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2010 Guus Sliepen <guus@tinc-vpn.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
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};
bool choice;
int i, err;
int replaywin_int;
myself = new_node();
myself->connection = new_connection();
@ -358,6 +360,28 @@ bool setup_myself(void) {
} else
maxtimeout = 900;
if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) {
if(udp_rcvbuf <= 0) {
logger(LOG_ERR, "UDPRcvBuf cannot be negative!");
return false;
}
}
if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) {
if(udp_sndbuf <= 0) {
logger(LOG_ERR, "UDPSndBuf cannot be negative!");
return false;
}
}
if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) {
if(replaywin_int < 0) {
logger(LOG_ERR, "ReplayWindow cannot be negative!");
return false;
}
replaywin = (unsigned)replaywin_int;
}
if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) {
if(!strcasecmp(afname, "IPv4"))
addressfamily = AF_INET;

View file

@ -43,6 +43,8 @@
int addressfamily = AF_UNSPEC;
int maxtimeout = 900;
int seconds_till_retry = 5;
int udp_rcvbuf = 0;
int udp_sndbuf = 0;
listen_socket_t listen_socket[MAXSOCKETS];
int listen_sockets;
@ -260,6 +262,12 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
option = 1;
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(sa->sa.sa_family == AF_INET6)
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);

View file

@ -62,6 +62,7 @@ void exit_nodes(void) {
node_t *new_node(void) {
node_t *n = xmalloc_and_zero(sizeof *n);
if(replaywin) n->late = xmalloc_and_zero(replaywin);
n->subnet_tree = new_subnet_tree();
n->edge_tree = new_edge_tree();
n->mtu = MTU;
@ -92,6 +93,9 @@ void free_node(node_t *n) {
if(n->name)
free(n->name);
if(n->late)
free(n->late);
free(n);
}

View file

@ -69,7 +69,8 @@ typedef struct node_t {
uint32_t sent_seqno; /* Sequence number last sent to this node */
uint32_t received_seqno; /* Sequence number last received from this node */
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 minmtu; /* Probed minimum MTU */

View file

@ -263,7 +263,7 @@ bool detach(void) {
bool execute_script(const char *name, char **envp) {
#ifdef HAVE_SYSTEM
int status, len;
char *scriptname, *p;
char *scriptname;
int i;
#ifndef HAVE_MINGW
@ -304,7 +304,7 @@ bool execute_script(const char *name, char **envp) {
for(i = 0; envp[i]; i++) {
char *e = strchr(envp[i], '=');
if(e) {
p = alloca(e - envp[i] + 1);
char p[e - envp[i] + 1];
strncpy(p, envp[i], e - envp[i]);
p[e - envp[i]] = '\0';
putenv(p);

View file

@ -156,7 +156,7 @@ bool send_ans_key(node_t *to) {
// Reset sequence number and late packet window
mykeyused = true;
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,
myself->name, to->name, key,