]> git.meshlink.io Git - meshlink/commitdiff
Merge branch 'master' into 1.1
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 19 Nov 2010 12:22:48 +0000 (12:22 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 19 Nov 2010 12:22:48 +0000 (12:22 +0000)
Conflicts:
src/net_packet.c
src/openssl/rsagen.h
src/protocol_auth.c
src/protocol_key.c

13 files changed:
AUTHORS
THANKS
doc/tinc.conf.5.in
src/dropin.c
src/linux/device.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/node.c
src/node.h
src/process.c
src/protocol_key.c

diff --git a/AUTHORS b/AUTHORS
index 3f1ebacf3dc057d3c8ece1f9fd08aa55105b7612..e41899677dfc1b88639632f8bdd7f849648a20d9 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
diff --git a/THANKS b/THANKS
index 601116ef4de18c83d40f410ac00ead724f59dd6b..d312dadb1a57a332459eb70f5804590df3d4e5d1 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -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
index 2bfd5fef94f8b2f6f0afa5f47540ef49b54362ef..ce690308c05bec244d655b30e624ae47312a2a6a 100644 (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
index 89039da34c024b6427d110cfea15ccee3c08acf9..52fb5b8675bd3799eb8177e0df7222f4ecd5edbf 100644 (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
index 4dbe38d5d2858e876d32da2b2160e7a66a77a95e..0cfc546ee16557c037c3e5352cbe5eb7c12a4571 100644 (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);
 
index f53c27a411896d5cc58ffcb30fc76bf72a350af5..9b625a0d9873c7a32723e55210559157c9df8ffc 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -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;
index b444bc9310277605e4bec46108f25bd578eeba0f..7be466201eae816acca0d52ab3fd6ddcff545f92 100644 (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;
index 9c188957afa449c5fca8849f69d0884893cae642..c51c133631f8d800b06f2644d086628d65fc46c2 100644 (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;
index 44d7f77159c5d586ceb8fdb62438e5f6c5593538..e20076fbe00d9f97e71406f3c95c8193fddfa8c8 100644 (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);
index 0159f9dd965bc57c219805dac01868c5a614ee2a..862bd69693ca9707e2ebd01076806e0e1bec43cf 100644 (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);
 }
 
index a9322aa54256ca9698e582379bb133a6d66a6caa..4eb216f49014d2f8b9bb5520365d6ce5e8df7adc 100644 (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 */
index 77454f755d05dc46481ee8cf7ca735d407302e90..d588a3fd830f50e8d7510d5fb9cd9eb4493f7dd3 100644 (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);
index f57dc2ea059ff07d01d104c8e3df46b48c60287a..ec5a690f600810044dc81bf7afc90a2c7c44a311 100644 (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,