- 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
* Jason Harper
* Jeroen Ubbink
* Jerome Etienne
+* Julien Muchembled
* LubomÃr Bulej
* Mads Kiilerich
* Marc A. Lehmann
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.
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.
.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.
#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>
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.])]
)
;;
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)
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"))
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);
}
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
#include "system.h"
#include "splay_tree.h"
+#include "connection.h"
#include "conf.h"
#include "logger.h"
#include "netutl.h" /* for str2address */
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;
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) {
config_t cfg, *found;
cfg.variable = variable;
- cfg.file = "";
+ cfg.file = NULL;
cfg.line = 0;
found = splay_search_closest_greater(config_tree, &cfg);
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;
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);
}
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);
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;
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;
#define __TINC_CONF_H__
#include "splay_tree.h"
+#include "list.h"
typedef struct config_t {
char *variable;
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 **);
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 *);
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;
-}
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__ */
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];
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);
}
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);
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);
}
#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
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);
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;
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);
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);
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);
}
#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);
}
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
}
#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
#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;
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
#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;
{
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)
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;
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);
}
#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) {
}
}
+ 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});
}
if(strictsubnets) {
subnet_t *subnet;
+
for(node = subnet_tree->head; node; node = node->next) {
subnet = node->data;
subnet->expires = 1;
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"
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
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;
/* 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;
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};
myself = new_node();
myself->connection = new_connection();
- init_configuration(&myself->connection->config_tree);
myself->hostname = xstrdup("MYSELF");
myself->connection->hostname = xstrdup("MYSELF");
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)) {
/* 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))
subnet_add(myself, subnet);
- cfg = lookup_config_next(myself->connection->config_tree, cfg);
+ cfg = lookup_config_next(config_tree, cfg);
}
/* Check some options */
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;
}
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;
/* 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)) {
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!");
/* 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;
#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
}
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));
/* 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
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));
#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)
#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
#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
#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);
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);
extern bool detach(void);
extern bool kill_other(int);
+#ifdef HAVE_MINGW
+extern bool init_service(void);
+#endif
+
#endif /* __TINC_PROCESS_H__ */
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)) {
} 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;
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;
}
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);
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;
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);
}
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;
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);
}
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
#ifdef HAVE_MINGW
static struct WSAData wsa_state;
CRITICAL_SECTION mutex;
+int main2(int argc, char **argv);
#endif
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");
}
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;
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 */
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;
}
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 };
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);
}