Merge branch 'master' into 1.1
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 12 Nov 2010 15:15:29 +0000 (16:15 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 12 Nov 2010 15:15:29 +0000 (16:15 +0100)
Conflicts:
doc/tincd.8.in
lib/pidfile.c
src/graph.c
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/netutl.c
src/node.c
src/node.h
src/protocol_auth.c
src/protocol_key.c
src/tincd.c

33 files changed:
AUTHORS
THANKS
doc/tinc.conf.5.in
doc/tinc.texi
doc/tincd.8.in
have.h
m4/openssl.m4
src/bsd/device.c
src/conf.c
src/conf.h
src/connection.c
src/connection.h
src/cygwin/device.c
src/dummy/device.c
src/getopt.c
src/linux/device.c
src/logger.c
src/memcmp.c
src/mingw/device.c
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/process.c
src/process.h
src/protocol_auth.c
src/protocol_edge.c
src/protocol_key.c
src/raw_socket/device.c
src/solaris/device.c
src/tincd.c
src/uml_socket/device.c

diff --git a/AUTHORS b/AUTHORS
index 7c20a8d..3f1ebac 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -8,6 +8,8 @@ Significant contributions from:
 - Grzegorz Dymarek <gregd72002@googlemail.com>
 - Max Rijevski <maksuf@gmail.com>
 - Scott Lamb <slamb@slamb.org>
+- Julien Muchembled <jm@jmuchemb.eu>
+- Timothy Redaelli <timothy@redaelli.eu>
 
 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 08f17d5..601116e 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -17,6 +17,7 @@ We would like to thank the following people for their contributions to tinc:
 * Jason Harper
 * Jeroen Ubbink
 * Jerome Etienne
+* Julien Muchembled
 * Lubomír Bulej
 * Mads Kiilerich
 * Marc A. Lehmann
index bc82b17..2bfd5fe 100644 (file)
@@ -110,6 +110,13 @@ Note: it is not required that you put in the
 sign, but doing so improves readability.
 If you leave it out, remember to replace it with at least one space character.
 
+.Pp
+The server configuration is complemented with host specific configuration (see the next section).
+Although all configuration options for the local host listed in this document can also be put in
+.Pa @sysconfdir@/tinc/ Ns Ar NETNAME Ns Pa /tinc.conf ,
+it is recommended to put host specific configuration options in the host configuration file,
+as this makes it easy to exchange with other nodes.
+
 .Pp
 Here are all valid variables, listed in alphabetical order.
 The default value is given between parentheses.
index a5ef8e6..3dc9eca 100644 (file)
@@ -749,6 +749,13 @@ and carriage returns are ignored.  Note: it is not required that you put
 in the `=' sign, but doing so improves readability.  If you leave it
 out, remember to replace it with at least one space character.
 
+The server configuration is complemented with host specific configuration (see
+the next section). Although all host configuration options for the local node
+listed in this document can also be put in
+@file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf}, it is recommended to
+put host specific configuration options in the host configuration file, as this
+makes it easy to exchange with other nodes.
+
 In this section all valid variables are listed in alphabetical order.
 The default value is given between parentheses,
 other comments are between square brackets.
index 9995b4c..df6af14 100644 (file)
@@ -72,11 +72,11 @@ is omitted, the default is
 .It Fl -bypass-security
 Disables encryption and authentication of the meta protocol.
 Only useful for debugging.
-.It Fl -chroot
+.It Fl R, -chroot
 With this option tinc chroots into the directory where network
 config is located (@sysconfdir@/tinc/NETNAME if -n option is used,
 or to the directory specified with -c option) after initialization.
-.It Fl -user Ns = Ns Ar USER
+.It Fl U, -user Ns = Ns Ar USER
 setuid to the specified
 .Ar USER
 after initialization.
diff --git a/have.h b/have.h
index 89454fe..21c16ef 100644 (file)
--- a/have.h
+++ b/have.h
 #ifndef __TINC_HAVE_H__
 #define __TINC_HAVE_H__
 
+#ifdef HAVE_MINGW
+#ifdef WITH_WINDOWS2000
+#define WINVER Windows2000
+#else
+#define WINVER WindowsXP
+#endif
+#define WIN32_LEAN_AND_MEAN
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <unistd.h>
 
 #ifdef HAVE_MINGW
-#ifdef WITH_WINDOWS2000
-#define WINVER Windows2000
-#else
-#define WINVER WindowsXP
-#endif
-#define WIN32_LEAN_AND_MEAN
 #include <w32api.h>
 #include <windows.h>
 #include <ws2tcpip.h>
index a5cd039..f091300 100644 (file)
@@ -29,7 +29,7 @@ AC_DEFUN([tinc_OPENSSL],
 case $host_os in
   *mingw*)
     AC_CHECK_LIB(crypto, SHA1_version,
-      [LIBS="$LIBS -lcrypto -lgdi32"],
+      [LIBS="$LIBS -lcrypto -lgdi32 -lcrypt32"],
       [AC_MSG_ERROR([OpenSSL libraries not found.])]
     )
   ;;
index a9e39d4..993b982 100644 (file)
@@ -47,8 +47,8 @@ int device_fd = -1;
 char *device = NULL;
 char *iface = NULL;
 static char *device_info = NULL;
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 #if defined(TUNEMU)
 static device_type_t device_type = DEVICE_TYPE_TUNEMU;
 #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD)
@@ -64,7 +64,7 @@ bool setup_device(void) {
                device = xstrdup(DEFAULT_DEVICE);
 
        if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
-               iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
+               iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
 
        if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
                if(!strcasecmp(type, "tun"))
@@ -353,6 +353,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index d5bc916..faff003 100644 (file)
@@ -2,7 +2,8 @@
     conf.c -- configuration code
     Copyright (C) 1998 Robert van der Meulen
                   1998-2005 Ivo Timmermans
-                  2000-2009 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2010 Julien Muchembled <jm@jmuchemb.eu>
                  2000 Cris van Pelt
 
     This program is free software; you can redistribute it and/or modify
@@ -23,6 +24,7 @@
 #include "system.h"
 
 #include "splay_tree.h"
+#include "connection.h"
 #include "conf.h"
 #include "logger.h"
 #include "netutl.h"                            /* for str2address */
@@ -36,6 +38,8 @@ int pinginterval = 0;                 /* seconds between pings */
 int pingtimeout = 0;                   /* seconds to wait for response */
 char *confbase = NULL;                 /* directory in which all config files are */
 char *netname = NULL;                  /* name of the vpn network */
+list_t *cmdline_conf = NULL;   /* global/host configuration values given at the command line */
+
 
 static int config_compare(const config_t *a, const config_t *b) {
        int result;
@@ -45,12 +49,17 @@ static int config_compare(const config_t *a, const config_t *b) {
        if(result)
                return result;
 
+       /* give priority to command line options */
+       result = !b->file - !a->file;
+       if (result)
+               return result;
+
        result = a->line - b->line;
 
        if(result)
                return result;
        else
-               return strcmp(a->file, b->file);
+               return a->file ? strcmp(a->file, b->file) : 0;
 }
 
 void init_configuration(splay_tree_t ** config_tree) {
@@ -87,7 +96,7 @@ config_t *lookup_config(splay_tree_t *config_tree, char *variable) {
        config_t cfg, *found;
 
        cfg.variable = variable;
-       cfg.file = "";
+       cfg.file = NULL;
        cfg.line = 0;
 
        found = splay_search_closest_greater(config_tree, &cfg);
@@ -233,17 +242,54 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
        return buf;
 }
 
+config_t *parse_config_line(char *line, const char *fname, int lineno) {
+       config_t *cfg;
+       int len;
+       char *variable, *value, *eol;
+       variable = value = line;
+
+       eol = line + strlen(line);
+       while(strchr("\t ", *--eol))
+               *eol = '\0';
+
+       len = strcspn(value, "\t =");
+       value += len;
+       value += strspn(value, "\t ");
+       if(*value == '=') {
+               value++;
+               value += strspn(value, "\t ");
+       }
+       variable[len] = '\0';
+
+       if(!*value) {
+               const char err[] = "No value for variable";
+               if (fname)
+                       logger(LOG_ERR, "%s `%s' on line %d while reading config file %s",
+                               err, variable, lineno, fname);
+               else
+                       logger(LOG_ERR, "%s `%s' in command line option %d",
+                               err, variable, lineno);
+               return NULL;
+       }
+
+       cfg = new_config();
+       cfg->variable = xstrdup(variable);
+       cfg->value = xstrdup(value);
+       cfg->file = fname ? xstrdup(fname) : NULL;
+       cfg->line = lineno;
+
+       return cfg;
+}
+
 /*
   Parse a configuration file and put the results in the configuration tree
   starting at *base.
 */
-int read_config_file(splay_tree_t *config_tree, const char *fname) {
+bool read_config_file(splay_tree_t *config_tree, const char *fname) {
        FILE *fp;
        char buffer[MAX_STRING_SIZE];
        char *line;
-       char *variable, *value, *eol;
        int lineno = 0;
-       int len;
        bool ignore = false;
        config_t *cfg;
        bool result = false;
@@ -280,34 +326,9 @@ int read_config_file(splay_tree_t *config_tree, const char *fname) {
                        continue;
                }
 
-               variable = value = line;
-
-               eol = line + strlen(line);
-               while(strchr("\t ", *--eol))
-                       *eol = '\0';
-
-               len = strcspn(value, "\t =");
-               value += len;
-               value += strspn(value, "\t ");
-               if(*value == '=') {
-                       value++;
-                       value += strspn(value, "\t ");
-               }
-               variable[len] = '\0';
-
-       
-               if(!*value) {
-                       logger(LOG_ERR, "No value for variable `%s' on line %d while reading config file %s",
-                                  variable, lineno, fname);
+               cfg = parse_config_line(line, fname, lineno);
+               if (!cfg)
                        break;
-               }
-
-               cfg = new_config();
-               cfg->variable = xstrdup(variable);
-               cfg->value = xstrdup(value);
-               cfg->file = xstrdup(fname);
-               cfg->line = lineno;
-
                config_add(config_tree, cfg);
        }
 
@@ -316,10 +337,32 @@ int read_config_file(splay_tree_t *config_tree, const char *fname) {
        return result;
 }
 
+void read_config_options(splay_tree_t *config_tree, const char *prefix) {
+       list_node_t *node, *next;
+       size_t prefix_len = prefix ? strlen(prefix) : 0;
+
+       for(node = cmdline_conf->tail; node; node = next) {
+               config_t *cfg = (config_t *)node->data;
+               next = node->prev;
+
+               if(!prefix && strchr(cfg->variable, '.'))
+                       continue;
+
+               if(prefix && (strncmp(prefix, cfg->variable, prefix_len) || cfg->variable[prefix_len] != '.'))
+                       continue;
+
+               config_add(config_tree, cfg);
+               node->data = NULL;
+               list_unlink_node(cmdline_conf, node);
+       }
+}
+
 bool read_server_config() {
        char *fname;
        bool x;
 
+       read_config_options(config_tree, NULL);
+
        xasprintf(&fname, "%s/tinc.conf", confbase);
        x = read_config_file(config_tree, fname);
 
@@ -332,6 +375,19 @@ bool read_server_config() {
        return x;
 }
 
+bool read_connection_config(connection_t *c) {
+       char *fname;
+       bool x;
+
+       read_config_options(c->config_tree, c->name);
+
+       xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
+       x = read_config_file(c->config_tree, fname);
+       free(fname);
+
+       return x;
+}
+
 bool disable_old_keys(FILE *f) {
        char buf[100];
        long pos;
@@ -340,24 +396,33 @@ bool disable_old_keys(FILE *f) {
        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';
-                       fseek(f, pos, SEEK_SET);
-                       fputs(buf, f);
+                       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';
-                       fseek(f, pos, SEEK_SET);
-                       fputs(buf, f);
+                       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 be70c24..cc57e82 100644 (file)
@@ -22,6 +22,7 @@
 #define __TINC_CONF_H__
 
 #include "splay_tree.h"
+#include "list.h"
 
 typedef struct config_t {
        char *variable;
@@ -40,6 +41,7 @@ extern int maxtimeout;
 extern bool bypass_security;
 extern char *confbase;
 extern char *netname;
+extern list_t *cmdline_conf;
 
 extern void init_configuration(splay_tree_t **);
 extern void exit_configuration(splay_tree_t **);
@@ -54,8 +56,11 @@ extern bool get_config_string(const config_t *, char **);
 extern bool get_config_address(const config_t *, struct addrinfo **);
 extern bool get_config_subnet(const config_t *, struct subnet_t **);
 
-extern int read_config_file(splay_tree_t *, const char *);
+extern config_t *parse_config_line(char *, const char *, int);
+extern bool read_config_file(splay_tree_t *, const char *);
+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 FILE *ask_and_open(const char *, const char *, const char *);
 extern bool is_safe_path(const char *);
 extern bool disable_old_keys(FILE *);
index 18c03c7..fecb48d 100644 (file)
@@ -106,14 +106,3 @@ bool dump_connections(connection_t *cdump) {
 
        return send_request(cdump, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
 }
-
-bool read_connection_config(connection_t *c) {
-       char *fname;
-       bool x;
-
-       xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
-       x = read_config_file(c->config_tree, fname);
-       free(fname);
-
-       return x;
-}
index 0f2b1d6..0fc49ef 100644 (file)
@@ -100,6 +100,5 @@ extern void free_connection(connection_t *);
 extern void connection_add(connection_t *);
 extern void connection_del(connection_t *);
 extern bool dump_connections(struct connection_t *);
-extern bool read_connection_config(connection_t *);
 
 #endif                                                 /* __TINC_CONNECTION_H__ */
index 0058076..5c227fd 100644 (file)
@@ -38,8 +38,8 @@ char *device = NULL;
 char *iface = NULL;
 static char *device_info = NULL;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 static pid_t reader_pid;
 static int sp[2];
@@ -261,6 +261,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index a9600b2..c84e899 100644 (file)
@@ -27,8 +27,8 @@ char *device = "dummy";
 char *iface = "dummy";
 static char *device_info = "dummy device";
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 bool setup_device(void) {
        logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
@@ -49,6 +49,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index b2f88b4..a6782ed 100644 (file)
@@ -44,6 +44,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include <stdio.h>
 
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
 /* Comment out all this code if we are using the GNU C Library, and are not
    actually compiling the library itself.  This code is part of the GNU C
    Library, but also included in many other GNU distributions.  Compiling
@@ -688,16 +692,18 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
              else
                {
                  if (opterr)
-                  if (argv[optind - 1][1] == '-')
-                   /* --option */
-                   fprintf (stderr,
-                    "%s: option `--%s' doesn't allow an argument\n",
-                    argv[0], pfound->name);
-                  else
-                   /* +option or -option */
-                   fprintf (stderr,
-                    "%s: option `%c%s' doesn't allow an argument\n",
-                    argv[0], argv[optind - 1][0], pfound->name);
+                   {
+                    if (argv[optind - 1][1] == '-')
+                     /* --option */
+                     fprintf (stderr,
+                      "%s: option `--%s' doesn't allow an argument\n",
+                      argv[0], pfound->name);
+                    else
+                     /* +option or -option */
+                     fprintf (stderr,
+                      "%s: option `%c%s' doesn't allow an argument\n",
+                      argv[0], argv[optind - 1][0], pfound->name);
+                   }
 
                  nextchar += strlen (nextchar);
 
index 72becd7..4dbe38d 100644 (file)
@@ -47,8 +47,8 @@ char *iface = NULL;
 static char ifrname[IFNAMSIZ];
 static char *device_info;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 bool setup_device(void) {
        struct ifreq ifr;
@@ -61,7 +61,7 @@ bool setup_device(void) {
                if (netname != NULL)
                        iface = xstrdup(netname);
 #else
-               iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
+               iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
 #endif
        device_fd = open(device, O_RDWR | O_NONBLOCK);
 
@@ -105,7 +105,7 @@ bool setup_device(void) {
                device_type = DEVICE_TYPE_ETHERTAP;
                if(iface)
                        free(iface);
-               iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
+               iface = xstrdup(strrchr(device, '/') ? strrchr(device, '/') + 1 : device);
        }
 
        logger(LOG_INFO, "%s is a %s", device, device_info);
@@ -205,6 +205,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index 35a6a38..4c0d231 100644 (file)
@@ -85,7 +85,7 @@ void logger(int priority, const char *format, ...) {
 #ifdef HAVE_MINGW
                        {
                                char message[4096];
-                               char *messages[] = {message};
+                               const char *messages[] = {message};
                                vsnprintf(message, sizeof message, format, ap);
                                ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL);
                        }
index 9d80833..8103e1a 100644 (file)
@@ -107,8 +107,8 @@ static int
 memcmp_bytes (a, b)
      op_t a, b;
 {
-  long int srcp1 = (long int) &a;
-  long int srcp2 = (long int) &b;
+  intptr_t srcp1 = (intptr_t) &a;
+  intptr_t srcp2 = (intptr_t) &b;
   op_t a0, b0;
 
   do
@@ -123,7 +123,7 @@ memcmp_bytes (a, b)
 }
 #endif
 
-static int memcmp_common_alignment __P((long, long, size_t));
+static int memcmp_common_alignment __P((intptr_t, intptr_t, size_t));
 
 /* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
    objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
@@ -133,8 +133,8 @@ __inline
 #endif
 static int
 memcmp_common_alignment (srcp1, srcp2, len)
-     long int srcp1;
-     long int srcp2;
+     intptr_t srcp1;
+     intptr_t srcp2;
      size_t len;
 {
   op_t a0, a1;
@@ -213,7 +213,7 @@ memcmp_common_alignment (srcp1, srcp2, len)
   return 0;
 }
 
-static int memcmp_not_common_alignment __P((long, long, size_t));
+static int memcmp_not_common_alignment __P((intptr_t, intptr_t, size_t));
 
 /* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
    `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
@@ -223,8 +223,8 @@ __inline
 #endif
 static int
 memcmp_not_common_alignment (srcp1, srcp2, len)
-     long int srcp1;
-     long int srcp2;
+     intptr_t srcp1;
+     intptr_t srcp2;
      size_t len;
 {
   op_t a0, a1, a2, a3;
@@ -332,8 +332,8 @@ rpl_memcmp (s1, s2, len)
 {
   op_t a0;
   op_t b0;
-  long int srcp1 = (long int) s1;
-  long int srcp2 = (long int) s2;
+  intptr_t srcp1 = (intptr_t) s1;
+  intptr_t srcp2 = (intptr_t) s2;
   op_t res;
 
   if (len >= OP_T_THRES)
index b67d0d3..c6eb908 100644 (file)
@@ -38,8 +38,8 @@ char *device = NULL;
 char *iface = NULL;
 static char *device_info = NULL;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 extern char *myport;
 
@@ -247,6 +247,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index 0e58236..7d44d17 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -36,6 +36,9 @@
 #include "subnet.h"
 #include "xalloc.h"
 
+int contradicting_add_edge = 0;
+int contradicting_del_edge = 0;
+
 /* Purge edges and subnets of unreachable nodes. Use carefully. */
 
 void purge(void) {
@@ -189,6 +192,19 @@ static void timeout_handler(int fd, short events, void *event) {
                }
        }
 
+       if(contradicting_del_edge && contradicting_add_edge) {
+               logger(LOG_WARNING, "Possible node with same Name as us!");
+
+               if(rand() % 3 == 0) {
+                       logger(LOG_ERR, "Shutting down, check configuration of all nodes for duplicate Names!");
+                       event_loopexit(NULL);
+                       return;
+               }
+
+               contradicting_add_edge = 0;
+               contradicting_del_edge = 0;
+       }
+
        event_add(event, &(struct timeval){pingtimeout, 0});
 }
 
@@ -275,6 +291,7 @@ int reload_configuration(void) {
        if(strictsubnets) {
                subnet_t *subnet;
 
+
                for(node = subnet_tree->head; node; node = node->next) {
                        subnet = node->data;
                        subnet->expires = 1;
index cd97e30..f53c27a 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -114,6 +114,8 @@ extern int listen_sockets;
 extern int keylifetime;
 extern bool do_prune;
 extern char *myport;
+extern int contradicting_add_edge;
+extern int contradicting_del_edge;
 
 /* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
 #include "connection.h"
index 46d4e1a..b444bc9 100644 (file)
@@ -2,6 +2,7 @@
     net_packet.c -- Handles in- and outgoing VPN packets
     Copyright (C) 1998-2005 Ivo Timmermans,
                   2000-2010 Guus Sliepen <guus@tinc-vpn.org>
+                  2010      Timothy Redaelli <timothy@redaelli.eu>
 
     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
@@ -356,7 +357,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        vpn_packet_t *outpkt;
        int origlen;
        size_t outlen;
+#if defined(SOL_IP) && defined(IP_TOS)
        static int priority = 0;
+#endif
        int origpriority;
        int sock;
 
index 198da3d..9c18895 100644 (file)
@@ -89,7 +89,7 @@ bool read_rsa_private_key() {
        /* First, check for simple PrivateKey statement */
 
        if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) {
-               if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &n)) {
+               if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
                        logger(LOG_ERR, "PrivateKey used but no PublicKey found!");
                        free(d);
                        return false;
@@ -223,6 +223,7 @@ bool setup_myself(void) {
        config_t *cfg;
        subnet_t *subnet;
        char *name, *hostname, *mode, *afname, *cipher, *digest;
+       char *fname = NULL;
        char *address = NULL;
        char *envp[5];
        struct addrinfo *ai, *aip, hint = {0};
@@ -231,7 +232,6 @@ bool setup_myself(void) {
 
        myself = new_node();
        myself->connection = new_connection();
-       init_configuration(&myself->connection->config_tree);
 
        myself->hostname = xstrdup("MYSELF");
        myself->connection->hostname = xstrdup("MYSELF");
@@ -252,17 +252,15 @@ bool setup_myself(void) {
 
        myself->name = name;
        myself->connection->name = xstrdup(name);
-
-       if(!read_connection_config(myself->connection)) {
-               logger(LOG_ERR, "Cannot open host configuration file for myself!");
-               return false;
-       }
+       xasprintf(&fname, "%s/hosts/%s", confbase, name);
+       read_config_options(config_tree, name);
+       read_config_file(config_tree, fname);
+       free(fname);
 
        if(!read_rsa_private_key())
                return false;
 
-       if(!get_config_string(lookup_config(config_tree, "Port"), &myport)
-                       && !get_config_string(lookup_config(myself->connection->config_tree, "Port"), &myport))
+       if(!get_config_string(lookup_config(config_tree, "Port"), &myport))
                myport = xstrdup("655");
 
        if(!atoi(myport)) {
@@ -277,7 +275,7 @@ bool setup_myself(void) {
 
        /* Read in all the subnets specified in the host configuration file */
 
-       cfg = lookup_config(myself->connection->config_tree, "Subnet");
+       cfg = lookup_config(config_tree, "Subnet");
 
        while(cfg) {
                if(!get_config_subnet(cfg, &subnet))
@@ -285,7 +283,7 @@ bool setup_myself(void) {
 
                subnet_add(myself, subnet);
 
-               cfg = lookup_config_next(myself->connection->config_tree, cfg);
+               cfg = lookup_config_next(config_tree, cfg);
        }
 
        /* Check some options */
@@ -296,12 +294,6 @@ bool setup_myself(void) {
        if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
                myself->options |= OPTION_TCPONLY;
 
-       if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice) && choice)
-               myself->options |= OPTION_INDIRECT;
-
-       if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
-               myself->options |= OPTION_TCPONLY;
-
        if(myself->options & OPTION_TCPONLY)
                myself->options |= OPTION_INDIRECT;
 
@@ -339,14 +331,12 @@ bool setup_myself(void) {
        }
 
        choice = true;
-       get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice);
        get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice);
        if(choice)
                myself->options |= OPTION_PMTU_DISCOVERY;
 
        choice = true;
        get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice);
-       get_config_bool(lookup_config(myself->connection->config_tree, "ClampMSS"), &choice);
        if(choice)
                myself->options |= OPTION_CLAMP_MSS;
 
@@ -386,7 +376,7 @@ bool setup_myself(void) {
 
        /* Generate packet encryption key */
 
-       if(!get_config_string(lookup_config(myself->connection->config_tree, "Cipher"), &cipher))
+       if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher))
                cipher = xstrdup("blowfish");
 
        if(!cipher_open_by_name(&myself->incipher, cipher)) {
@@ -405,7 +395,7 @@ bool setup_myself(void) {
                digest = xstrdup("sha1");
 
        int maclength = 4;
-       get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &maclength);
+       get_config_int(lookup_config(config_tree, "MACLength"), &maclength);
 
        if(maclength < 0) {
                logger(LOG_ERR, "Bogus MAC length!");
@@ -419,7 +409,7 @@ bool setup_myself(void) {
 
        /* Compression */
 
-       if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->incompression)) {
+       if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) {
                if(myself->incompression < 0 || myself->incompression > 11) {
                        logger(LOG_ERR, "Bogus compression level!");
                        return false;
index 4fe6516..44d7f77 100644 (file)
@@ -69,12 +69,12 @@ static void configure_tcp(connection_t *c) {
 
 #if defined(SOL_TCP) && defined(TCP_NODELAY)
        option = 1;
-       setsockopt(c->socket, SOL_TCP, TCP_NODELAY, &option, sizeof option);
+       setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option);
 #endif
 
 #if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
        option = IPTOS_LOWDELAY;
-       setsockopt(c->socket, SOL_IP, IP_TOS, &option, sizeof option);
+       setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option);
 #endif
 }
 
@@ -94,7 +94,7 @@ static bool bind_to_interface(int sd) {
        strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
        ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
 
-       status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));
+       status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
        if(status) {
                logger(LOG_ERR, "Can't bind to interface %s: %s", iface,
                                strerror(errno));
@@ -180,11 +180,11 @@ int setup_listen_socket(const sockaddr_t *sa) {
        /* Optimize TCP settings */
 
        option = 1;
-       setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
+       setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
 
 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
        if(sa->sa.sa_family == AF_INET6)
-               setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option);
+               setsockopt(nfd, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
 #endif
 
        if(get_config_string
@@ -195,7 +195,7 @@ int setup_listen_socket(const sockaddr_t *sa) {
                memset(&ifr, 0, sizeof ifr);
                strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
 
-               if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof ifr)) {
+               if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof ifr)) {
                        closesocket(nfd);
                        logger(LOG_ERR, "Can't bind to interface %s: %s", iface,
                                   strerror(sockerrno));
@@ -258,11 +258,11 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
 #endif
 
        option = 1;
-       setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof option);
+       setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
 
 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
        if(sa->sa.sa_family == AF_INET6)
-               setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, &option, sizeof option);
+               setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
 #endif
 
 #if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
@@ -272,12 +272,12 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
 #if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
        if(myself->options & OPTION_PMTU_DISCOVERY) {
                option = IP_PMTUDISC_DO;
-               setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
+               setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, (void *)&option, sizeof(option));
        }
 #elif defined(IPPROTO_IP) && defined(IP_DONTFRAGMENT)
        if(myself->options & OPTION_PMTU_DISCOVERY) {
                option = 1;
-               setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, &option, sizeof(option));
+               setsockopt(nfd, IPPROTO_IP, IP_DONTFRAGMENT, (void *)&option, sizeof(option));
        }
 #else
 #warning No way to disable IPv4 fragmentation
@@ -286,12 +286,12 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
 #if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
        if(myself->options & OPTION_PMTU_DISCOVERY) {
                option = IPV6_PMTUDISC_DO;
-               setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
+               setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, (void *)&option, sizeof(option));
        }
 #elif defined(IPPROTO_IPV6) && defined(IPV6_DONTFRAG)
        if(myself->options & OPTION_PMTU_DISCOVERY) {
                option = 1;
-               setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, &option, sizeof(option));
+               setsockopt(nfd, IPPROTO_IPV6, IPV6_DONTFRAG, (void *)&option, sizeof(option));
        }
 #else
 #warning No way to disable IPv6 fragmentation
@@ -409,7 +409,7 @@ begin:
 #if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
        int option = 1;
        if(c->address.sa.sa_family == AF_INET6)
-               setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, &option, sizeof option);
+               setsockopt(c->socket, SOL_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
 #endif
 
        bind_to_interface(c->socket);
index 09fd63e..77454f7 100644 (file)
@@ -40,7 +40,9 @@ extern char *identname;
 extern char **g_argv;
 extern bool use_logfile;
 
+#ifndef HAVE_MINGW
 sigset_t emptysigset;
+#endif
 
 static void memory_full(int size) {
        logger(LOG_ERR, "Memory exhausted (couldn't allocate %d bytes), exitting.", size);
index 740f7c7..ea7815e 100644 (file)
@@ -29,4 +29,8 @@ extern bool execute_script(const char *, char **);
 extern bool detach(void);
 extern bool kill_other(int);
 
+#ifdef HAVE_MINGW
+extern bool init_service(void);
+#endif
+
 #endif                                                 /* __TINC_PROCESS_H__ */
index ca9e86b..6059096 100644 (file)
@@ -452,7 +452,7 @@ bool ack_h(connection_t *c, char *request) {
        if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
                n->mtu = mtu;
 
-       if(get_config_int(lookup_config(myself->connection->config_tree, "PMTU"), &mtu) && mtu < n->mtu)
+       if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu)
                n->mtu = mtu;
 
        if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) {
index 4aad53f..1dd68d5 100644 (file)
@@ -133,6 +133,7 @@ bool add_edge_h(connection_t *c, char *request) {
        } else if(from == myself) {
                ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself which does not exist",
                                   "ADD_EDGE", c->name, c->hostname);
+               contradicting_add_edge++;
                e = new_edge();
                e->from = from;
                e->to = to;
@@ -229,6 +230,7 @@ bool del_edge_h(connection_t *c, char *request) {
        if(e->from == myself) {
                ifdebug(PROTOCOL) logger(LOG_WARNING, "Got %s from %s (%s) for ourself",
                                   "DEL_EDGE", c->name, c->hostname);
+               contradicting_del_edge++;
                send_add_edge(c, e);    /* Send back a correction */
                return true;
        }
index 4187538..f57dc2e 100644 (file)
@@ -216,7 +216,7 @@ bool ans_key_h(connection_t *c, char *request) {
                        return true;
                }
 
-               if(!*address) {
+               if(!*address && from->address.sa.sa_family != AF_UNSPEC) {
                        char *address, *port;
                        ifdebug(PROTOCOL) logger(LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
                        sockaddr2str(&from->address, &address, &port);
index 0ee7cc2..66d6348 100644 (file)
@@ -35,8 +35,8 @@ char *iface = NULL;
 static char ifrname[IFNAMSIZ];
 static char *device_info;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 bool setup_device(void) {
        struct ifreq ifr;
@@ -123,6 +123,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index 8221b9f..d257ffd 100644 (file)
@@ -38,8 +38,8 @@ char *device = NULL;
 char *iface = NULL;
 static char *device_info = NULL;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 bool setup_device(void) {
        int ip_fd = -1, if_fd = -1;
@@ -163,6 +163,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }
index 2162364..c4750da 100644 (file)
@@ -4,6 +4,8 @@
                   2000-2010 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>
+                  2010      Timothy Redaelli <timothy@redaelli.eu>
 
     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
@@ -111,6 +113,7 @@ static struct option const long_options[] = {
 #ifdef HAVE_MINGW
 static struct WSAData wsa_state;
 CRITICAL_SECTION mutex;
+int main2(int argc, char **argv);
 #endif
 
 static void usage(bool status) {
@@ -127,6 +130,7 @@ static void usage(bool status) {
                                "      --logfile[=FILENAME]      Write log entries to a logfile.\n"
                                "      --controlcookie=FILENAME  Write control socket cookie to FILENAME.\n"
                                "      --bypass-security         Disables meta protocol security, for debugging.\n"
+                               "  -o [HOST.]KEY=VALUE           Set global/host configuration value.\n"
                                "  -R, --chroot                  chroot to NET dir at startup.\n"
                                "  -U, --user=USER               setuid to given USER at startup.\n"                            "      --help                    Display this help and exit.\n"
                                "      --version                 Output version information and exit.\n\n");
@@ -135,10 +139,14 @@ static void usage(bool status) {
 }
 
 static bool parse_options(int argc, char **argv) {
+       config_t *cfg;
        int r;
        int option_index = 0;
+       int lineno = 0;
 
-       while((r = getopt_long(argc, argv, "c:DLd::n:RU:", long_options, &option_index)) != EOF) {
+       cmdline_conf = list_alloc((list_action_t)free_config);
+
+       while((r = getopt_long(argc, argv, "c:DLd::n:o:RU:", long_options, &option_index)) != EOF) {
                switch (r) {
                        case 0:                         /* long option */
                                break;
@@ -168,7 +176,16 @@ static bool parse_options(int argc, char **argv) {
                                break;
 
                        case 'n':                               /* net name given */
-                               netname = xstrdup(optarg);
+                               /* netname "." is special: a "top-level name" */
+                               netname = strcmp(optarg, ".") != 0 ?
+                                               xstrdup(optarg) : NULL;
+                               break;
+
+                       case 'o':                               /* option */
+                               cfg = parse_config_line(optarg, NULL, ++lineno);
+                               if (!cfg)
+                                       return false;
+                               list_insert_tail(cmdline_conf, cfg);
                                break;
 
                        case 'R':                               /* chroot to NETNAME dir */
@@ -431,13 +448,25 @@ int main2(int argc, char **argv) {
         char *priority = 0;
 
         if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
-                if(!strcasecmp(priority, "Normal"))
-                        setpriority(NORMAL_PRIORITY_CLASS);
-                else if(!strcasecmp(priority, "Low"))
-                        setpriority(BELOW_NORMAL_PRIORITY_CLASS);
-                else if(!strcasecmp(priority, "High"))
-                        setpriority(HIGH_PRIORITY_CLASS);
-                else {
+                if(!strcasecmp(priority, "Normal")) {
+                        if (setpriority(NORMAL_PRIORITY_CLASS) != 0) {
+                                logger(LOG_ERR, "System call `%s' failed: %s",
+                                       "setpriority", strerror(errno));
+                                goto end;
+                        }
+                } else if(!strcasecmp(priority, "Low")) {
+                        if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) {
+                                       logger(LOG_ERR, "System call `%s' failed: %s",
+                                       "setpriority", strerror(errno));
+                                goto end;
+                        }
+                } else if(!strcasecmp(priority, "High")) {
+                        if (setpriority(HIGH_PRIORITY_CLASS) != 0) {
+                                logger(LOG_ERR, "System call `%s' failed: %s",
+                                       "setpriority", strerror(errno));
+                                goto end;
+                        }
+                } else {
                         logger(LOG_ERR, "Invalid priority `%s`!", priority);
                         goto end;
                 }
index ddb4563..e9b0766 100644 (file)
@@ -41,8 +41,8 @@ static char *device_info;
 extern char *identname;
 extern bool running;
 
-static int device_total_in = 0;
-static int device_total_out = 0;
+static uint64_t device_total_in = 0;
+static uint64_t device_total_out = 0;
 
 enum request_type { REQ_NEW_CONTROL };
 
@@ -272,6 +272,6 @@ bool write_packet(vpn_packet_t *packet) {
 
 void dump_device_stats(void) {
        logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
-       logger(LOG_DEBUG, " total bytes in:  %10d", device_total_in);
-       logger(LOG_DEBUG, " total bytes out: %10d", device_total_out);
+       logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
+       logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
 }