* Use splay trees instead of AVL trees.
-Version 1.0.14 not released yet
+Version 1.0.14 May 8 2011
* Fixed reading configuration files that do not end with a newline. Again.
+ * Allow arbitrary configuration options being specified on the command line.
+
+ * Allow all options in both tinc.conf and the local host config file.
+
+ * Configurable replay window, UDP send and receive buffers for performance tuning.
+
+ * Try harder to get UDP communication back after falling back to TCP.
+
+ * Initial support for attaching tinc to a VDE switch.
+
+ * DragonFly BSD support.
+
+ * Allow linking with OpenSSL 1.0.0.
+
+ Thanks to Brandon Black, Julien Muchembled, Michael Tokarev, Rumko and Timothy
+ Redaelli for their contributions to this version of tinc.
+
Version 1.0.13 Apr 11 2010
* Allow building tinc without LZO and/or Zlib.
This is the README file for tinc version 1.1-cvs. Installation
instructions may be found in the INSTALL file.
-tinc is Copyright (C) 1998-2010 by:
+tinc is Copyright (C) 1998-2011 by:
Ivo Timmermans,
Guus Sliepen <guus@tinc-vpn.org>,
manual in doc/tinc.texi contains more detailed information on how to
install this library.
-Since 1.0pre6, the zlib library is used for optional compression. You need this
-library whether or not you plan to enable the compression. You can find it at
-http://www.gzip.org/zlib/. Because of a possible exploit in earlier versions we
-recommand that you download version 1.1.4 or later.
+Since 1.0pre6, the zlib library is used for optional compression. You can
+find it at http://www.gzip.org/zlib/. Because of a possible exploit in
+earlier versions we recommend that you download version 1.1.4 or later.
-Since 1.0, the lzo library is also used for optional compression. You need this
-library whether or not you plan to enable compression. You can find it at
-http://www.oberhumer.com/opensource/lzo/.
+Since 1.0, the lzo library is also used for optional compression. You can
+find it at http://www.oberhumer.com/opensource/lzo/.
Since 1.1, the libevent library is used for the main event loop. You can find
it at http://monkey.org/~provos/libevent/.
* Nick Patavalis
* Paul Littlefield
* Robert van der Meulen
+* Rumko
* Scott Lamb
* Sven-Haegar Koch
* Teemu Kiviniemi
AC_GNU_SOURCE
AC_DEFINE([__USE_BSD], 1, [Enable BSD extensions])
-ALL_LINGUAS="nl"
-
dnl Checks for programs.
AC_PROG_CC_C99
AC_PROG_CPP
AC_DEFINE(HAVE_NETBSD, 1, [NetBSD])
[ rm -f src/device.c; ln -sf bsd/device.c src/device.c ]
;;
+ *dragonfly*)
+ AC_DEFINE(HAVE_DRAGONFLY, 1, [DragonFly])
+ [ rm -f src/device.c; ln -sf bsd/device.c src/device.c ]
+ ;;
*bsd*)
AC_MSG_WARN("Unknown BSD variant, tinc might not compile or work!")
AC_DEFINE(HAVE_BSD, 1, [Unknown BSD variant])
*mingw*)
AC_DEFINE(HAVE_MINGW, 1, [MinGW])
[ rm -f src/device.c; cp -f src/mingw/device.c src/device.c ]
- LIBS="$LIBS -lws2_32"
+ LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32"
;;
*)
AC_MSG_ERROR("Unknown operating system.")
dnl We do this in multiple stages, because unlike Linux all the other operating systems really suck and don't include their own dependencies.
AC_HEADER_STDC
-AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h])
-AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h],
+AC_CHECK_HEADERS([stdbool.h syslog.h sys/file.h sys/ioctl.h sys/mman.h sys/param.h sys/resource.h sys/socket.h sys/time.h sys/uio.h sys/un.h sys/wait.h netdb.h arpa/inet.h dirent.h])
+AC_CHECK_HEADERS([net/if.h net/if_types.h linux/if_tun.h net/if_tun.h net/tun/if_tun.h net/if_tap.h net/tap/if_tap.h net/ethernet.h net/if_arp.h netinet/in_systm.h netinet/in.h netinet/in6.h time.h],
[], [], [#include "have.h"]
)
AC_CHECK_HEADERS([netinet/if_ether.h netinet/ip.h netinet/ip6.h],
AC_FUNC_MEMCMP
AC_FUNC_ALLOCA
AC_TYPE_SIGNAL
-AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time unsetenv vsyslog writev],
+AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev],
[], [], [#include "have.h"]
)
AC_FUNC_MALLOC
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
-Copyright @copyright{} 1998-2010 Ivo Timmermans,
+Copyright @copyright{} 1998-2011 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
@cindex copyright
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
-Copyright @copyright{} 1998-2010 Ivo Timmermans,
+Copyright @copyright{} 1998-2011 Ivo Timmermans,
Guus Sliepen <guus@@tinc-vpn.org> and
Wessel Dankers <wsl@@tinc-vpn.org>.
This problem can be solved by using @emph{virtual} networks. Virtual
networks can live on top of other networks, but they use encapsulation to
keep using their private address space so they do not interfere with
-the Internet. Mostly, virtual networks appear like a singe LAN, even though
+the Internet. Mostly, virtual networks appear like a single LAN, even though
they can span the entire world. But virtual networks can't be secured
by using firewalls, because the traffic that flows through it has to go
through the Internet, where other people can look at it.
When this option is used the priority of the tincd process will be adjusted.
Increasing the priority may help to reduce latency and packet loss on the VPN.
+@cindex ReplayWindow
+@item ReplayWindow = <bytes> (16)
+This is the size of the replay tracking window for each remote node, in bytes.
+The window is a bitfield which tracks 1 packet per bit, so for example
+the default setting of 16 will track up to 128 packets in the window. In high
+bandwidth scenarios, setting this to a higher value can reduce packet loss from
+the interaction of replay tracking with underlying real packet loss and/or
+reordering. Setting this to zero will disable replay tracking completely and
+pass all traffic, but leaves tinc vulnerable to replay-based attacks on your
+traffic.
+
+
@cindex StrictSubnets
@item StrictSubnets <yes|no> (no) [experimental]
When this option is enabled tinc will only use Subnet statements which are
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory.
Setting this options also implicitly sets StrictSubnets.
+@cindex UDPRcvBuf
+@item UDPRcvBuf = <bytes> (OS default)
+Sets the socket receive buffer size for the UDP socket, in bytes.
+If unset, the default buffer size will be used by the operating system.
+
+@cindex UDPSndBuf
+@item UDPSndBuf = <bytes> Pq OS default
+Sets the socket send buffer size for the UDP socket, in bytes.
+If unset, the default buffer size will be used by the operating system.
+
@end table
logged. Everything goes via syslog.
@item -n, --net=@var{netname}
-Use configuration for net @var{netname}. @xref{Multiple networks}.
+Use configuration for net @var{netname}.
+This will let tinc read all configuration files from
+@file{@value{sysconfdir}/tinc/@var{netname}/}.
+Specifying . for @var{netname} is the same as not specifying any @var{netname}.
+@xref{Multiple networks}.
@item --controlsocket=@var{filename}
Open control socket at @var{filename}. If unspecified, the default is
-.Dd 2009-05-18
+.Dd 2011-01-02
.Dt TINCD 8
.\" Manual page created by:
.\" Ivo Timmermans
.It Fl n, -net Ns = Ns Ar NETNAME
Connect to net
.Ar NETNAME .
+This will let tinc read all configuration files from
+.Pa @sysconfdir@/tinc/ Ar NETNAME .
+Specifying
+.Li .
+for
+.Ar NETNAME
+is the same as not specifying any
+.Ar NETNAME .
.It Fl L, -mlock
Lock tinc into main memory.
This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
/*
have.h -- include headers which are known to exist
Copyright (C) 1998-2005 Ivo Timmermans
- 2003-2009 Guus Sliepen <guus@tinc-vpn.org>
+ 2003-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
#include <sys/param.h>
#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#include <net/if_tun.h>
#endif
+#ifdef HAVE_NET_TUN_IF_TUN_H
+#include <net/tun/if_tun.h>
+#endif
+
#ifdef HAVE_NET_IF_TAP_H
#include <net/if_tap.h>
#endif
+#ifdef HAVE_NET_TAP_IF_TAP_H
+#include <net/tap/if_tap.h>
+#endif
+
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
[AC_MSG_ERROR([OpenSSL header files not found.]); break]
)
+ AC_CHECK_LIB(crypto, EVP_EncryptInit_ex,
+ [LIBS="-lcrypto $LIBS"],
+ [AC_MSG_ERROR([OpenSSL libraries not found.])]
+ )
+
case $host_os in
*mingw*)
- AC_CHECK_LIB(crypto, SHA1_version,
- [LIBS="$LIBS -lcrypto -lgdi32 -lcrypt32"],
- [AC_MSG_ERROR([OpenSSL libraries not found.])]
- )
;;
*)
- AC_CHECK_LIB(crypto, SHA1_version,
- [LIBS="$LIBS -lcrypto"],
- [AC_MSG_ERROR([OpenSSL libraries not found.])]
- )
-
AC_CHECK_FUNC(dlopen,
[],
[AC_CHECK_LIB(dl, dlopen,
/*
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
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;
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,
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
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);
}
}
/*
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
}
#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
/*
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
/*
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
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))
# 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 *
/*
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
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);
/*
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
/*
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>
}
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)) {
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;
}
}
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);
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) {
/*
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
if(err) {
logger(LOG_ERR, "Error while translating addresses: %s",
gai_strerror(err));
- raise(SIGFPE);
- exit(0);
+ abort();
}
scopeid = strchr(address, '%');
default:
logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
- raise(SIGFPE);
- exit(0);
+ abort();
}
}
default:
logger(LOG_ERR, "sockaddrcmp() was called with unknown address family %d, exitting!",
a->sa.sa_family);
- raise(SIGFPE);
- exit(0);
+ abort();
}
}
/*
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
}
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)
/*
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
{SIGILL, fatal_signal_handler},
{SIGPIPE, ignore_signal_handler},
{SIGCHLD, ignore_signal_handler},
+ {SIGABRT, SIG_DFL},
{0, NULL}
};
#endif
/*
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
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;
/*
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
#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 uint64_t device_total_out = 0;
bool setup_device(void) {
- int ip_fd = -1, if_fd = -1;
int ppa;
char *ptr;
}
void close_device(void) {
+ close(if_fd);
+ close(ip_fd);
close(device_fd);
free(device);
/*
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>
}
#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) {
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"
--- /dev/null
+/*
+ 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);
+}