Merge branch 'master' of git://tinc-vpn.org/tinc into 1.1

Conflicts:
	NEWS
	README
	configure.in
	doc/tincd.8.in
	lib/pidfile.c
	src/bsd/device.c
	src/dropin.h
	src/net.c
	src/net_packet.c
	src/node.c
	src/process.c
	src/tincd.c
This commit is contained in:
Guus Sliepen 2011-05-09 21:35:14 +02:00
commit ce8775000a
24 changed files with 319 additions and 96 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
@ -51,7 +51,7 @@ 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;
@ -199,9 +199,8 @@ bool read_packet(vpn_packet_t *packet) {
if(device_type == DEVICE_TYPE_TUNEMU)
inlen = tunemu_read(device_fd, packet->data + 14, MTU - 14);
else
#else
inlen = read(device_fd, packet->data + 14, MTU - 14);
#endif
inlen = read(device_fd, packet->data + 14, MTU - 14);
if(inlen <= 0) {
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,

View file

@ -3,7 +3,7 @@
Copyright (C) 1998 Robert van der Meulen
1998-2005 Ivo Timmermans
2000-2010 Guus Sliepen <guus@tinc-vpn.org>
2010 Julien Muchembled <jm@jmuchemb.eu>
2010-2011 Julien Muchembled <jm@jmuchemb.eu>
2000 Cris van Pelt
This program is free software; you can redistribute it and/or modify
@ -342,18 +342,29 @@ void read_config_options(splay_tree_t *config_tree, const char *prefix) {
size_t prefix_len = prefix ? strlen(prefix) : 0;
for(node = cmdline_conf->tail; node; node = next) {
config_t *cfg = (config_t *)node->data;
config_t *orig_cfg, *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;
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);
node->data = NULL;
list_unlink_node(cmdline_conf, node);
}
}

View file

@ -1,7 +1,7 @@
/*
dropin.c -- a set of drop-in replacements for libc functions
Copyright (C) 2000-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
@ -164,9 +164,10 @@ int gettimeofday(struct timeval *tv, void *tz) {
}
#endif
#ifdef HAVE_MINGW
#ifndef HAVE_USLEEP
int usleep(long usec) {
Sleep(usec / 1000);
struct timeval tv = {usec / 1000000, (usec / 1000) % 1000};
select(0, NULL, NULL, NULL, &tv);
return 0;
}
#endif

View file

@ -1,7 +1,7 @@
/*
dropin.h -- header file for dropin.c
Copyright (C) 2000-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

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
@ -285,16 +285,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

@ -23,6 +23,10 @@
# include "config.h"
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#undef __ptr_t
#if defined __cplusplus || (defined __STDC__ && __STDC__)
# define __ptr_t void *

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
@ -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);

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

View file

@ -1,7 +1,7 @@
/*
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>
@ -87,16 +87,21 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
}
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)) {
@ -152,12 +157,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;
}
}
@ -552,7 +562,9 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
splay_node_t *node;
node_t *n, *found = NULL;
edge_t *e;
node_t *n = NULL;
bool hard = false;
static time_t last_hard_try = 0;
time_t now = time(NULL);
@ -561,19 +573,29 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
else
last_hard_try = now;
for(node = node_tree->head; node; node = node->next) {
n = node->data;
for(node = edge_weight_tree->head; node; node = node->next) {
e = node->data;
if(n == myself || !n->status.reachable || !digest_active(&n->indigest))
if(e->to == myself)
continue;
if(try_mac(n, pkt)) {
found = n;
break;
if(sockaddrcmp_noport(from, &e->address)) {
if(last_hard_try == now)
continue;
hard = true;
}
if(!try_mac(e->to, pkt))
continue;
n = e->to;
break;
}
return found;
if(hard)
last_hard_try = now;
return n;
}
void handle_incoming_vpn_data(int sock, short events, void *data) {

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
@ -142,6 +142,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;
}
splay_delete(node_udp_tree, n);
if(n->hostname)

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
@ -387,6 +387,7 @@ static struct {
{SIGILL, fatal_signal_handler},
{SIGPIPE, ignore_signal_handler},
{SIGCHLD, ignore_signal_handler},
{SIGABRT, SIG_DFL},
{0, NULL}
};
#endif

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
@ -275,7 +275,7 @@ bool ans_key_h(connection_t *c, char *request) {
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

@ -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,6 +34,7 @@
#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;
@ -42,7 +43,6 @@ 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);

View file

@ -1,7 +1,7 @@
/*
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>
@ -339,12 +339,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) {
@ -358,7 +358,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"

133
src/vde/device.c Normal file
View file

@ -0,0 +1,133 @@
/*
device.c -- VDE plug
Copyright (C) 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "system.h"
#include <libvdeplug_dyn.h>
#include "conf.h"
#include "net.h"
#include "logger.h"
#include "utils.h"
#include "route.h"
#include "xalloc.h"
int device_fd = -1;
static struct vdepluglib plug;
static struct vdeconn *conn = NULL;
static int port = 0;
static char *group = NULL;
char *device = NULL;
char *iface = NULL;
static char *device_info;
extern char *identname;
extern bool running;
static uint64_t device_total_in = 0;
static uint64_t device_total_out = 0;
bool setup_device(void) {
libvdeplug_dynopen(plug);
if(!plug.dl_handle) {
logger(LOG_ERR, "Could not open libvdeplug library!");
return false;
}
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
xasprintf(&device, LOCALSTATEDIR "/run/vde.ctl");
get_config_string(lookup_config(config_tree, "Interface"), &iface);
get_config_int(lookup_config(config_tree, "VDEPort"), &port);
get_config_string(lookup_config(config_tree, "VDEGroup"), &group);
device_info = "VDE socket";
struct vde_open_args args = {
.port = port,
.group = group,
.mode = 0700,
};
conn = plug.vde_open(device, identname, &args);
if(!conn) {
logger(LOG_ERR, "Could not open VDE socket %s", device);
return false;
}
device_fd = plug.vde_datafd(conn);
logger(LOG_INFO, "%s is a %s", device, device_info);
if(routing_mode == RMODE_ROUTER)
overwrite_mac = true;
return true;
}
void close_device(void) {
if(conn)
plug.vde_close(conn);
if(plug.dl_handle)
libvdeplug_dynclose(plug);
free(device);
free(iface);
}
bool read_packet(vpn_packet_t *packet) {
int lenin = plug.vde_recv(conn, packet->data, MTU, 0);
if(lenin <= 0) {
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info, device, strerror(errno));
running = false;
return false;
}
packet->len = lenin;
device_total_in += packet->len;
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s", packet->len, device_info);
return true;
}
bool write_packet(vpn_packet_t *packet) {
if(plug.vde_send(conn, packet->data, packet->len, 0) < 0) {
if(errno != EINTR && errno != EAGAIN) {
logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device, strerror(errno));
running = false;
}
return false;
}
device_total_out += packet->len;
return true;
}
void dump_device_stats(void) {
logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
logger(LOG_DEBUG, " total bytes in: %10"PRIu64, device_total_in);
logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
}