Import Upstream version 1.0.14

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:40 +02:00
parent 3f0ae998e8
commit d906f6f9b0
50 changed files with 1593 additions and 753 deletions

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction BSD tun/tap device
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2009 Guus Sliepen <guus@tinc-vpn.org>
2001-2011 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
This program is free software; you can redistribute it and/or modify
@ -47,11 +47,11 @@ 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)
#elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
#else
static device_type_t device_type = DEVICE_TYPE_TUN;
@ -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"))
@ -199,9 +199,8 @@ bool read_packet(vpn_packet_t *packet) {
if(device_type == DEVICE_TYPE_TUNEMU)
lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14);
else
#else
lenin = read(device_fd, packet->data + 14, MTU - 14);
#endif
lenin = read(device_fd, packet->data + 14, MTU - 14);
if(lenin <= 0) {
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
@ -353,6 +352,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);
}

View 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-2011 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 "avl_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(avl_tree_t ** config_tree) {
@ -87,7 +96,7 @@ config_t *lookup_config(avl_tree_t *config_tree, char *variable) {
config_t cfg, *found;
cfg.variable = variable;
cfg.file = "";
cfg.file = NULL;
cfg.line = 0;
found = avl_search_closest_greater(config_tree, &cfg);
@ -224,7 +233,7 @@ static char *readline(FILE * fp, char *buf, size_t buflen) {
newline = strchr(p, '\n');
if(!newline)
return NULL;
return buf;
*newline = '\0'; /* kill newline */
if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */
@ -233,6 +242,45 @@ 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.
@ -241,9 +289,7 @@ bool read_config_file(avl_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 @@ bool read_config_file(avl_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,43 @@ bool read_config_file(avl_tree_t *config_tree, const char *fname) {
return result;
}
void read_config_options(avl_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 *orig_cfg, *cfg = (config_t *)node->data;
next = node->prev;
if(!prefix) {
if(strchr(cfg->variable, '.'))
continue;
node->data = NULL;
list_unlink_node(cmdline_conf, node);
} else {
if(strncmp(prefix, cfg->variable, prefix_len) ||
cfg->variable[prefix_len] != '.')
continue;
/* Because host configuration is parsed again when
reconnecting, nodes must not be freed when a prefix
is given. */
orig_cfg = cfg;
cfg = new_config();
cfg->variable = xstrdup(orig_cfg->variable + prefix_len + 1);
cfg->value = xstrdup(orig_cfg->value);
cfg->file = NULL;
cfg->line = orig_cfg->line;
}
config_add(config_tree, cfg);
}
}
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 +386,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;
}
FILE *ask_and_open(const char *filename, const char *what) {
FILE *r;
char *directory;
@ -400,24 +467,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;

View file

@ -22,6 +22,7 @@
#define __TINC_CONF_H__
#include "avl_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(avl_tree_t **);
extern void exit_configuration(avl_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 config_t *parse_config_line(char *, const char *, int);
extern bool read_config_file(avl_tree_t *, const char *);
extern void read_config_options(avl_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 *);
extern bool is_safe_path(const char *);
extern bool disable_old_keys(FILE *);

View file

@ -127,14 +127,3 @@ void dump_connections(void) {
logger(LOG_DEBUG, "End of 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;
}

View file

@ -111,6 +111,5 @@ extern void free_connection(connection_t *);
extern void connection_add(connection_t *);
extern void connection_del(connection_t *);
extern void dump_connections(void);
extern bool read_connection_config(connection_t *);
#endif /* __TINC_CONNECTION_H__ */

View 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);
}

View file

@ -1,6 +1,6 @@
/*
graph.c -- graph algorithms
Copyright (C) 2001-2010 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2001-2011 Guus Sliepen <guus@tinc-vpn.org>,
2001-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -199,16 +199,12 @@ void sssp_bfs(void) {
n->address is set to the e->address of the edge left of n to n.
We are currently examining the edge e right of n from n:
- If e->reverse->address != n->address, then e->to is probably
not reachable for the nodes left of n. We do as if the indirectdata
flag is set on edge e.
- If edge e provides for better reachability of e->to, update
e->to and (re)add it to the todo_list to (re)examine the reachability
of nodes behind it.
*/
indirect = n->status.indirect || e->options & OPTION_INDIRECT
|| ((n != myself) && sockaddrcmp(&n->address, &e->reverse->address));
indirect = n->status.indirect || e->options & OPTION_INDIRECT;
if(e->to->status.visited
&& (!e->to->status.indirect || indirect))

View file

@ -47,11 +47,12 @@ 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;
bool t1q = false;
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
device = xstrdup(DEFAULT_DEVICE);
@ -61,7 +62,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);
@ -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);
@ -105,7 +112,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 +212,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);
}

View 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);
}

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction with Windows tap driver in a MinGW environment
Copyright (C) 2002-2005 Ivo Timmermans,
2002-2009 Guus Sliepen <guus@tinc-vpn.org>
2002-2011 Guus Sliepen <guus@tinc-vpn.org>
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
@ -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;
@ -95,17 +95,9 @@ bool setup_device(void) {
bool found = false;
int sock, err;
int err;
HANDLE thread;
struct addrinfo *ai;
struct addrinfo hint = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = 0,
};
get_config_string(lookup_config(config_tree, "Device"), &device);
get_config_string(lookup_config(config_tree, "Interface"), &iface);
@ -247,6 +239,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);
}

View file

@ -1,7 +1,7 @@
/*
net.c -- most of the network code
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
This program is free software; you can redistribute it and/or modify
@ -44,6 +44,8 @@ bool do_purge = false;
volatile bool running = false;
time_t now = 0;
int contradicting_add_edge = 0;
int contradicting_del_edge = 0;
/* Purge edges and subnets of unreachable nodes. Use carefully. */
@ -278,12 +280,21 @@ static void check_network_activity(fd_set * readset, fd_set * writeset) {
int result, i;
socklen_t len = sizeof(result);
vpn_packet_t packet;
static int errors = 0;
/* check input from kernel */
if(device_fd >= 0 && FD_ISSET(device_fd, readset)) {
if(read_packet(&packet)) {
errors = 0;
packet.priority = 0;
route(myself, &packet);
} else {
usleep(errors * 50000);
errors++;
if(errors > 10) {
logger(LOG_ERR, "Too many errors from %s, exiting!", device);
running = false;
}
}
}
@ -297,7 +308,7 @@ static void check_network_activity(fd_set * readset, fd_set * writeset) {
if(FD_ISSET(c->socket, readset)) {
if(c->status.connecting) {
c->status.connecting = false;
getsockopt(c->socket, SOL_SOCKET, SO_ERROR, &result, &len);
getsockopt(c->socket, SOL_SOCKET, SO_ERROR, (void *)&result, &len);
if(!result)
finish_connecting(c);
@ -415,6 +426,19 @@ int main_loop(void) {
send_key_changed(broadcast, myself);
keyexpires = now + keylifetime;
}
if(contradicting_del_edge > 10 && contradicting_add_edge > 10) {
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!");
running = false;
break;
}
contradicting_add_edge = 0;
contradicting_del_edge = 0;
}
}
if(sigalrm) {

View file

@ -106,15 +106,20 @@ 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 keyexpires;
extern int keylifetime;
extern int udp_rcvbuf;
extern int udp_sndbuf;
extern bool do_prune;
extern bool do_purge;
extern char *myport;
extern time_t now;
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"

View file

@ -1,7 +1,9 @@
/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 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
@ -59,6 +61,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
@ -81,16 +85,21 @@ void send_mtu_probe(node_t *n) {
}
if(n->mtuprobes > 32) {
if(!n->minmtu) {
n->mtuprobes = 31;
timeout = pinginterval;
goto end;
}
ifdebug(TRAFFIC) logger(LOG_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
n->mtuprobes = 1;
n->minmtu = 0;
n->maxmtu = MTU;
}
if(n->mtuprobes >= 10 && !n->minmtu) {
if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
ifdebug(TRAFFIC) logger(LOG_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
n->mtuprobes = 0;
return;
n->mtuprobes = 31;
}
if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
@ -144,12 +153,17 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
packet->data[0] = 1;
send_udppacket(n, packet);
} else {
if(n->mtuprobes > 30) {
if(n->minmtu)
n->mtuprobes = 30;
else
n->mtuprobes = 1;
}
if(len > n->maxmtu)
len = n->maxmtu;
if(n->minmtu < len)
n->minmtu = len;
if(n->mtuprobes > 30)
n->mtuprobes = 30;
}
}
@ -292,25 +306,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;
@ -365,7 +386,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
vpn_packet_t *outpkt;
int origlen;
int outlen, outpad;
#if defined(SOL_IP) && defined(IP_TOS)
static int priority = 0;
#endif
int origpriority;
int sock;
@ -552,20 +575,21 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
avl_node_t *node;
edge_t *e;
node_t *n = NULL;
bool hard = false;
static time_t last_hard_try = 0;
for(node = edge_weight_tree->head; node; node = node->next) {
e = node->data;
if(e->to == myself)
continue;
if(sockaddrcmp_noport(from, &e->address)) {
if(last_hard_try == now)
continue;
last_hard_try = now;
hard = true;
}
if(!n)
n = e->to;
if(!try_mac(e->to, pkt))
continue;
@ -573,6 +597,9 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
break;
}
if(hard)
last_hard_try = now;
return n;
}

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
@ -149,7 +150,7 @@ bool read_rsa_private_key(void) {
struct stat s;
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &pubkey)) {
if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) {
logger(LOG_ERR, "PrivateKey used but no PublicKey found!");
return false;
}
@ -270,15 +271,16 @@ 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};
bool choice;
int i, err;
int replaywin_int;
myself = new_node();
myself->connection = new_connection();
init_configuration(&myself->connection->config_tree);
myself->hostname = xstrdup("MYSELF");
myself->connection->hostname = xstrdup("MYSELF");
@ -299,17 +301,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)) {
@ -324,7 +324,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))
@ -332,7 +332,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 */
@ -343,12 +343,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;
@ -386,14 +380,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;
@ -415,6 +407,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;
@ -434,7 +448,7 @@ bool setup_myself(void) {
/* Generate packet encryption key */
if(get_config_string
(lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
(lookup_config(config_tree, "Cipher"), &cipher)) {
if(!strcasecmp(cipher, "none")) {
myself->incipher = NULL;
} else {
@ -462,7 +476,7 @@ bool setup_myself(void) {
/* Check if we want to use message authentication codes... */
if(get_config_string(lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) {
if(!strcasecmp(digest, "none")) {
myself->indigest = NULL;
} else {
@ -478,7 +492,7 @@ bool setup_myself(void) {
myself->connection->outdigest = EVP_sha1();
if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->inmaclength)) {
if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) {
if(myself->indigest) {
if(myself->inmaclength > myself->indigest->md_size) {
logger(LOG_ERR, "MAC length exceeds size of digest!");
@ -495,7 +509,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;

View file

@ -44,6 +44,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;
@ -70,12 +72,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
}
@ -95,7 +97,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));
@ -181,11 +183,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
@ -196,7 +198,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));
@ -259,11 +261,17 @@ 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(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, &option, sizeof option);
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
#endif
#if defined(IP_DONTFRAG) && !defined(IP_DONTFRAGMENT)
@ -273,12 +281,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
@ -287,12 +295,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
@ -410,7 +418,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);

View file

@ -1,7 +1,7 @@
/*
netutl.c -- some supporting network utility code
Copyright (C) 1998-2005 Ivo Timmermans
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 Guus Sliepen <guus@tinc-vpn.org>
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
@ -93,8 +93,7 @@ void sockaddr2str(const sockaddr_t *sa, char **addrstr, char **portstr) {
if(err) {
logger(LOG_ERR, "Error while translating addresses: %s",
gai_strerror(err));
raise(SIGFPE);
exit(0);
abort();
}
scopeid = strchr(address, '%');
@ -155,8 +154,7 @@ int sockaddrcmp_noport(const sockaddr_t *a, const sockaddr_t *b) {
default:
logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
raise(SIGFPE);
exit(0);
abort();
}
}
@ -199,8 +197,7 @@ int sockaddrcmp(const sockaddr_t *a, const sockaddr_t *b) {
default:
logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
raise(SIGFPE);
exit(0);
abort();
}
}

View file

@ -1,6 +1,6 @@
/*
node.c -- node tree management
Copyright (C) 2001-2009 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2001-2011 Guus Sliepen <guus@tinc-vpn.org>,
2001-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -54,6 +54,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();
EVP_CIPHER_CTX_init(&n->inctx);
@ -91,6 +92,9 @@ void free_node(node_t *n) {
if(n->name)
free(n->name);
if(n->late)
free(n->late);
free(n);
}
@ -137,6 +141,11 @@ node_t *lookup_node_udp(const sockaddr_t *sa) {
}
void update_node_udp(node_t *n, const sockaddr_t *sa) {
if(n == myself) {
logger(LOG_WARNING, "Trying to update UDP address of myself!\n");
return;
}
avl_delete(node_udp_tree, n);
if(n->hostname)

View file

@ -77,7 +77,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

@ -1,7 +1,7 @@
/*
process.c -- process management functions
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 Guus Sliepen <guus@tinc-vpn.org>
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
@ -43,7 +43,9 @@ extern char **g_argv;
extern bool use_logfile;
extern volatile bool running;
#ifndef HAVE_MINGW
sigset_t emptysigset;
#endif
static int saved_debug_level = -1;
@ -354,7 +356,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
@ -395,7 +397,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);
@ -544,6 +546,7 @@ static struct {
{SIGCHLD, ignore_signal_handler},
{SIGALRM, sigalrm_handler},
{SIGWINCH, sigwinch_handler},
{SIGABRT, SIG_DFL},
{0, NULL}
};
#endif

View file

@ -30,4 +30,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__ */

View file

@ -109,15 +109,13 @@ bool id_h(connection_t *c) {
}
bool send_metakey(connection_t *c) {
char *buffer;
int len;
bool x;
len = RSA_size(c->rsa_key);
int len = RSA_size(c->rsa_key);
/* Allocate buffers for the meta key */
buffer = alloca(2 * len + 1);
char buffer[2 * len + 1];
c->outkey = xrealloc(c->outkey, len);
@ -287,16 +285,13 @@ bool metakey_h(connection_t *c) {
}
bool send_challenge(connection_t *c) {
char *buffer;
int len;
/* CHECKME: what is most reasonable value for len? */
len = RSA_size(c->rsa_key);
int len = RSA_size(c->rsa_key);
/* Allocate buffers for the challenge */
buffer = alloca(2 * len + 1);
char buffer[2 * len + 1];
c->hischallenge = xrealloc(c->hischallenge, len);
@ -539,7 +534,7 @@ bool ack_h(connection_t *c) {
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)) {

View file

@ -133,6 +133,7 @@ bool add_edge_h(connection_t *c) {
} 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) {
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;
}

View file

@ -1,7 +1,7 @@
/*
protocol_key.c -- handle the meta-protocol, key exchange
Copyright (C) 1999-2005 Ivo Timmermans,
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 Guus Sliepen <guus@tinc-vpn.org>
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
@ -145,8 +145,6 @@ bool req_key_h(connection_t *c) {
}
bool send_ans_key(node_t *to) {
char *key;
// Set key parameters
to->incipher = myself->incipher;
to->inkeylength = myself->inkeylength;
@ -165,10 +163,10 @@ 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);
// Convert to hexadecimal and send
key = alloca(2 * to->inkeylength + 1);
char key[2 * to->inkeylength + 1];
bin2hex(to->inkey, key, to->inkeylength);
key[to->inkeylength * 2] = '\0';
@ -229,7 +227,7 @@ bool ans_key_h(connection_t *c) {
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);
@ -312,7 +310,7 @@ bool ans_key_h(connection_t *c) {
update_node_udp(from, &sa);
}
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes)
if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuevent)
send_mtu_probe(from);
return true;

View 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);
}

View file

@ -1,7 +1,7 @@
/*
device.c -- Interaction with Solaris tun device
Copyright (C) 2001-2005 Ivo Timmermans,
2001-2009 Guus Sliepen <guus@tinc-vpn.org>
2001-2011 Guus Sliepen <guus@tinc-vpn.org>
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
@ -34,15 +34,15 @@
#define DEFAULT_DEVICE "/dev/tun"
int device_fd = -1;
int ip_fd = -1, if_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;
bool setup_device(void) {
int ip_fd = -1, if_fd = -1;
int ppa;
char *ptr;
@ -105,6 +105,8 @@ bool setup_device(void) {
}
void close_device(void) {
close(if_fd);
close(ip_fd);
close(device_fd);
free(device);
@ -163,6 +165,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);
}

View file

@ -1,9 +1,11 @@
/*
tincd.c -- the main file for tincd
Copyright (C) 1998-2005 Ivo Timmermans
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2000-2011 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
@ -118,6 +120,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) {
@ -135,6 +138,7 @@ static void usage(bool status) {
" -L, --mlock Lock tinc into main memory.\n"
" --logfile[=FILENAME] Write log entries to a logfile.\n"
" --pidfile=FILENAME Write PID to FILENAME.\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"
@ -144,10 +148,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::k::n:K::RU:", long_options, &option_index)) != EOF) {
cmdline_conf = list_alloc((list_action_t)free_config);
while((r = getopt_long(argc, argv, "c:DLd::k::n:o:K::RU:", long_options, &option_index)) != EOF) {
switch (r) {
case 0: /* long option */
break;
@ -195,6 +203,8 @@ static bool parse_options(int argc, char **argv) {
kill_tincd = SIGINT;
else if(!strcasecmp(optarg, "ALRM"))
kill_tincd = SIGALRM;
else if(!strcasecmp(optarg, "ABRT"))
kill_tincd = SIGABRT;
else {
kill_tincd = atoi(optarg);
@ -213,7 +223,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 'K': /* generate public/private keypair */
@ -350,6 +369,7 @@ static bool keygen(int bits) {
fchmod(fileno(f), 0600);
#endif
fputc('\n', f);
PEM_write_RSAPrivateKey(f, rsa_key, NULL, NULL, 0, NULL, NULL);
fclose(f);
free(filename);
@ -367,6 +387,7 @@ static bool keygen(int bits) {
if(disable_old_keys(f))
fprintf(stderr, "Warning: old key(s) found and disabled.\n");
fputc('\n', f);
PEM_write_RSAPublicKey(f, rsa_key);
fclose(f);
free(filename);
@ -483,12 +504,12 @@ static bool drop_privs() {
}
#ifdef HAVE_MINGW
# define setpriority(level) SetPriorityClass(GetCurrentProcess(), level)
# define setpriority(level) SetPriorityClass(GetCurrentProcess(), (level))
#else
# define NORMAL_PRIORITY_CLASS 0
# define BELOW_NORMAL_PRIORITY_CLASS 10
# define HIGH_PRIORITY_CLASS -10
# define setpriority(level) nice(level)
# define setpriority(level) (setpriority(PRIO_PROCESS, 0, (level)))
#endif
int main(int argc, char **argv) {
@ -502,7 +523,7 @@ int main(int argc, char **argv) {
if(show_version) {
printf("%s version %s (built %s %s, protocol %d)\n", PACKAGE,
VERSION, __DATE__, __TIME__, PROT_CURRENT);
printf("Copyright (C) 1998-2010 Ivo Timmermans, Guus Sliepen and others.\n"
printf("Copyright (C) 1998-2011 Ivo Timmermans, Guus Sliepen and others.\n"
"See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"
@ -594,13 +615,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;
}

View 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);
}