Allow linking with multiple device drivers.
Apart from the platform specific tun/tap driver, link with the dummy and raw_socket devices, and optionally with support for UML and VDE devices. At runtime, the DeviceType option can be used to select which driver to use.
This commit is contained in:
parent
5672863e59
commit
178e52f76e
19 changed files with 281 additions and 96 deletions
17
configure.in
17
configure.in
|
@ -72,6 +72,21 @@ case $host_os in
|
|||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(uml,
|
||||
AS_HELP_STRING([--enable-uml], [enable support for User Mode Linux]),
|
||||
[ AC_DEFINE(ENABLE_UML, 1, [Support for UML])
|
||||
uml=true
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(vde,
|
||||
AS_HELP_STRING([--enable-vde], [enable support for Virtual Distributed Ethernet]),
|
||||
[ AC_CHECK_HEADERS(libvdeplug_dyn.h, [], [AC_MSG_ERROR([VDE plug header files not found.]); break])
|
||||
AC_DEFINE(ENABLE_VDE, 1, [Support for VDE])
|
||||
vde=true
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(tunemu,
|
||||
AS_HELP_STRING([--enable-tunemu], [enable support for the tunemu driver]),
|
||||
[ AC_DEFINE(ENABLE_TUNEMU, 1, [Support for tunemu])
|
||||
|
@ -84,6 +99,8 @@ AC_ARG_WITH(windows2000,
|
|||
[AC_DEFINE(WITH_WINDOWS2000, 1, [Compile with support for Windows 2000])]
|
||||
)
|
||||
|
||||
AM_CONDITIONAL(UML, test "$uml" = true)
|
||||
AM_CONDITIONAL(VDE, test "$vde" = true)
|
||||
AM_CONDITIONAL(TUNEMU, test "$tunemu" = true)
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
|
|
@ -177,30 +177,65 @@ instead of
|
|||
The info pages of the tinc package contain more information
|
||||
about configuring the virtual network device.
|
||||
|
||||
.It Va DeviceType Li = tun | tunnohead | tunifhead | tap Po only supported on BSD platforms Pc
|
||||
.It Va DeviceType Li = Ar type Pq platform dependent
|
||||
The type of the virtual network device.
|
||||
Tinc will normally automatically select the right type, and this option should not be used.
|
||||
However, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
using this option might help.
|
||||
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
|
||||
However, this option can be used to select one of the special interface types, if support for them is compiled in.
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It tun
|
||||
.It dummy
|
||||
Use a dummy interface.
|
||||
No packets are ever read or written to a virtual network device.
|
||||
Useful for testing, or when setting up a node that only forwards packets for other nodes.
|
||||
|
||||
.It raw_socket
|
||||
Open a raw socket, and bind it to a pre-existing
|
||||
.Va Interface
|
||||
(eth0 by default).
|
||||
All packets are read from this interface.
|
||||
Packets received for the local node are written to the raw socket.
|
||||
However, at least on Linux, the operating system does not process IP packets destined for the local host.
|
||||
|
||||
.It uml Pq not compiled in by default
|
||||
Create a UNIX socket with the filename specified by
|
||||
.Va Device ,
|
||||
or
|
||||
.Pa @localstatedir@/run/ Ns Ar NETNAME Ns Pa .umlsocket
|
||||
if not specified.
|
||||
.Nm tinc
|
||||
will wait for a User Mode Linux instance to connect to this socket.
|
||||
|
||||
.It vde Pq not compiled in by default
|
||||
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
||||
using the UNIX socket specified by
|
||||
.Va Device ,
|
||||
or
|
||||
.Pa @localstatedir@/run/vde.ctl
|
||||
if not specified.
|
||||
.El
|
||||
|
||||
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
it can be used to change the way packets are interpreted:
|
||||
|
||||
.Bl -tag -width indent
|
||||
|
||||
.It tun Pq BSD only
|
||||
Set type to tun.
|
||||
Depending on the platform, this can either be with or without an address family header (see below).
|
||||
|
||||
.It tunnohead
|
||||
.It tunnohead Pq BSD only
|
||||
Set type to tun without an address family header.
|
||||
Tinc will expect packets read from the virtual network device to start with an IP header.
|
||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||
|
||||
.It tunifhead
|
||||
.It tunifhead Pq BSD only
|
||||
Set type to tun with an address family header.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with a four byte header containing the address family,
|
||||
followed by an IP header.
|
||||
This mode should support both IPv4 and IPv6 packets.
|
||||
|
||||
.It tap
|
||||
.It tap Pq BSD only
|
||||
Set type to tap.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with an Ethernet header.
|
||||
|
|
|
@ -794,32 +794,64 @@ Note that you can only use one device per daemon.
|
|||
See also @ref{Device files}.
|
||||
|
||||
@cindex DeviceType
|
||||
@item DeviceType = <tun|tunnohead|tunifhead|tap> (only supported on BSD platforms)
|
||||
@item DeviceType = <@var{type}> (platform dependent)
|
||||
The type of the virtual network device.
|
||||
Tinc will normally automatically select the right type, and this option should not be used.
|
||||
However, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
using this option might help.
|
||||
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
|
||||
However, this option can be used to select one of the special interface types, if support for them is compiled in.
|
||||
|
||||
@table @asis
|
||||
@item tun
|
||||
@cindex dummy
|
||||
@item dummy
|
||||
Use a dummy interface.
|
||||
No packets are ever read or written to a virtual network device.
|
||||
Useful for testing, or when setting up a node that only forwards packets for other nodes.
|
||||
|
||||
@cindex raw_socket
|
||||
@item raw_socket
|
||||
Open a raw socket, and bind it to a pre-existing
|
||||
@var{Interface} (eth0 by default).
|
||||
All packets are read from this interface.
|
||||
Packets received for the local node are written to the raw socket.
|
||||
However, at least on Linux, the operating system does not process IP packets destined for the local host.
|
||||
|
||||
@cindex UML
|
||||
@item uml (not compiled in by default)
|
||||
Create a UNIX socket with the filename specified by
|
||||
@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket}
|
||||
if not specified.
|
||||
Tinc will wait for a User Mode Linux instance to connect to this socket.
|
||||
|
||||
@cindex VDE
|
||||
@item vde (not compiled in by default)
|
||||
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
||||
using the UNIX socket specified by
|
||||
@var{Device}, or @file{@value{localstatedir}/run/vde.ctl}
|
||||
if not specified.
|
||||
@end table
|
||||
|
||||
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
||||
it can be used to change the way packets are interpreted:
|
||||
|
||||
@table @asis
|
||||
@item tun (BSD only)
|
||||
Set type to tun.
|
||||
Depending on the platform, this can either be with or without an address family header (see below).
|
||||
|
||||
@cindex tunnohead
|
||||
@item tunnohead
|
||||
@item tunnohead (BSD only)
|
||||
Set type to tun without an address family header.
|
||||
Tinc will expect packets read from the virtual network device to start with an IP header.
|
||||
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
||||
|
||||
@cindex tunifhead
|
||||
@item tunifhead
|
||||
@item tunifhead (BSD only)
|
||||
Set type to tun with an address family header.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with a four byte header containing the address family,
|
||||
followed by an IP header.
|
||||
This mode should support both IPv4 and IPv6 packets.
|
||||
|
||||
@item tap
|
||||
@item tap (BSD only)
|
||||
Set type to tap.
|
||||
Tinc will expect packets read from the virtual network device
|
||||
to start with an Ethernet header.
|
||||
|
|
|
@ -2,11 +2,20 @@
|
|||
|
||||
sbin_PROGRAMS = tincd
|
||||
|
||||
EXTRA_DIST = linux/device.c bsd/device.c solaris/device.c cygwin/device.c mingw/device.c mingw/common.h raw_socket/device.c uml_socket/device.c vde/device.c
|
||||
EXTRA_DIST = linux/device.c bsd/device.c solaris/device.c cygwin/device.c mingw/device.c mingw/common.h
|
||||
|
||||
tincd_SOURCES = conf.c connection.c edge.c event.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
|
||||
net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
|
||||
protocol_key.c protocol_subnet.c route.c subnet.c tincd.c
|
||||
protocol_key.c protocol_subnet.c route.c subnet.c tincd.c \
|
||||
dummy_device.c raw_socket_device.c
|
||||
|
||||
if UML
|
||||
tincd_SOURCES += uml_device.c
|
||||
endif
|
||||
|
||||
if VDE
|
||||
tincd_SOURCES += vde_device.c
|
||||
endif
|
||||
|
||||
if TUNEMU
|
||||
tincd_SOURCES += bsd/tunemu.c
|
||||
|
|
|
@ -58,7 +58,7 @@ static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
|
|||
static device_type_t device_type = DEVICE_TYPE_TUN;
|
||||
#endif
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
char *type;
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device))
|
||||
|
@ -175,7 +175,7 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
switch(device_type) {
|
||||
#ifdef HAVE_TUNEMU
|
||||
case DEVICE_TYPE_TUNEMU:
|
||||
|
@ -190,7 +190,7 @@ void close_device(void) {
|
|||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
switch(device_type) {
|
||||
|
@ -282,7 +282,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
|
||||
|
@ -351,8 +351,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t os_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Windows tap driver in a Cygwin 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
|
||||
|
@ -45,7 +45,7 @@ static uint64_t device_total_out = 0;
|
|||
static pid_t reader_pid;
|
||||
static int sp[2];
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
HKEY key, key2;
|
||||
int i, err;
|
||||
|
||||
|
@ -214,7 +214,7 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
close(sp[0]);
|
||||
close(sp[1]);
|
||||
CloseHandle(device_handle);
|
||||
|
@ -225,7 +225,7 @@ void close_device(void) {
|
|||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
if((lenin = read(sp[0], packet->data, MTU)) <= 0) {
|
||||
|
@ -244,7 +244,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
long lenout;
|
||||
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
|
@ -260,8 +260,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t os_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
|
23
src/device.h
23
src/device.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net.h -- generic header for device.c
|
||||
device.h -- generic header for device.c
|
||||
Copyright (C) 2001-2005 Ivo Timmermans
|
||||
2001-2006 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
|
||||
|
@ -28,10 +28,19 @@ extern char *device;
|
|||
|
||||
extern char *iface;
|
||||
|
||||
extern bool setup_device(void);
|
||||
extern void close_device(void);
|
||||
extern bool read_packet(struct vpn_packet_t *);
|
||||
extern bool write_packet(struct vpn_packet_t *);
|
||||
extern void dump_device_stats(void);
|
||||
typedef struct devops_t {
|
||||
bool (*setup)(void);
|
||||
void (*close)(void);
|
||||
bool (*read)(struct vpn_packet_t *);
|
||||
bool (*write)(struct vpn_packet_t *);
|
||||
void (*dump_stats)(void);
|
||||
} devops_t;
|
||||
|
||||
extern const devops_t os_devops;
|
||||
extern const devops_t dummy_devops;
|
||||
extern const devops_t raw_socket_devops;
|
||||
extern const devops_t uml_devops;
|
||||
extern const devops_t vde_devops;
|
||||
extern devops_t devops;
|
||||
|
||||
#endif /* __TINC_DEVICE_H__ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
device.c -- Dummy device
|
||||
Copyright (C) 2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
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
|
||||
|
@ -23,33 +23,40 @@
|
|||
#include "logger.h"
|
||||
#include "net.h"
|
||||
|
||||
int device_fd = -1;
|
||||
char *device = "dummy";
|
||||
char *iface = "dummy";
|
||||
static char *device_info = "dummy device";
|
||||
|
||||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
device = "dummy";
|
||||
iface = "dummy";
|
||||
logger(LOG_INFO, "%s (%s) is a %s", device, iface, device_info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
device_total_out += packet->len;
|
||||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t dummy_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- Interaction with Linux ethertap and 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>
|
||||
|
||||
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
|
||||
|
@ -51,7 +51,7 @@ static char *device_info;
|
|||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
struct ifreq ifr;
|
||||
bool t1q = false;
|
||||
|
||||
|
@ -121,14 +121,14 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
switch(device_type) {
|
||||
|
@ -175,7 +175,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
|
||||
|
@ -211,8 +211,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t os_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
|
|
@ -83,7 +83,7 @@ static DWORD WINAPI tapreader(void *bla) {
|
|||
}
|
||||
}
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
HKEY key, key2;
|
||||
int i;
|
||||
|
||||
|
@ -210,18 +210,18 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
CloseHandle(device_handle);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
long lenout;
|
||||
OVERLAPPED overlapped = {0};
|
||||
|
||||
|
@ -238,8 +238,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t os_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
|
|
@ -289,7 +289,7 @@ static void check_network_activity(fd_set * readset, fd_set * writeset) {
|
|||
|
||||
/* check input from kernel */
|
||||
if(device_fd >= 0 && FD_ISSET(device_fd, readset)) {
|
||||
if(read_packet(&packet)) {
|
||||
if(devops.read(&packet)) {
|
||||
errors = 0;
|
||||
packet.priority = 0;
|
||||
route(myself, &packet);
|
||||
|
|
|
@ -518,7 +518,7 @@ void send_packet(const node_t *n, vpn_packet_t *packet) {
|
|||
if(n == myself) {
|
||||
if(overwrite_mac)
|
||||
memcpy(packet->data, mymac.x, ETH_ALEN);
|
||||
write_packet(packet);
|
||||
devops.write(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
net_setup.c -- Setup.
|
||||
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>
|
||||
2010 Brandon Black <blblack@gmail.com>
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include "xalloc.h"
|
||||
|
||||
char *myport;
|
||||
devops_t devops;
|
||||
|
||||
bool read_rsa_public_key(connection_t *c) {
|
||||
FILE *fp;
|
||||
|
@ -276,7 +277,7 @@ void load_all_subnets(void) {
|
|||
static bool setup_myself(void) {
|
||||
config_t *cfg;
|
||||
subnet_t *subnet;
|
||||
char *name, *hostname, *mode, *afname, *cipher, *digest;
|
||||
char *name, *hostname, *mode, *afname, *cipher, *digest, *type;
|
||||
char *fname = NULL;
|
||||
char *address = NULL;
|
||||
char *envp[5];
|
||||
|
@ -539,7 +540,28 @@ static bool setup_myself(void) {
|
|||
|
||||
/* Open device */
|
||||
|
||||
if(!setup_device())
|
||||
if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
|
||||
if(!strcasecmp(type, "dummy"))
|
||||
devops = dummy_devops;
|
||||
else if(!strcasecmp(type, "raw_socket"))
|
||||
devops = raw_socket_devops;
|
||||
#ifdef ENABLE_UML
|
||||
else if(!strcasecmp(type, "uml"))
|
||||
devops = uml_devops;
|
||||
#endif
|
||||
#ifdef ENABLE_VDE
|
||||
else if(!strcasecmp(type, "vde"))
|
||||
devops = vde_devops;
|
||||
#endif
|
||||
else {
|
||||
logger(LOG_ERR, "Unknown device type %s!", type);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
devops = os_devops;
|
||||
}
|
||||
|
||||
if(!devops.setup())
|
||||
return false;
|
||||
|
||||
/* Run tinc-up script to further initialize the tap interface */
|
||||
|
@ -702,7 +724,7 @@ void close_network_connections(void) {
|
|||
for(i = 0; i < 4; i++)
|
||||
free(envp[i]);
|
||||
|
||||
close_device();
|
||||
devops.close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -511,7 +511,7 @@ static RETSIGTYPE sigusr1_handler(int a) {
|
|||
}
|
||||
|
||||
static RETSIGTYPE sigusr2_handler(int a) {
|
||||
dump_device_stats();
|
||||
devops.dump_stats();
|
||||
dump_nodes();
|
||||
dump_edges();
|
||||
dump_subnets();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- raw socket
|
||||
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
|
||||
|
@ -30,16 +30,12 @@
|
|||
#include "route.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
int device_fd = -1;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char ifrname[IFNAMSIZ];
|
||||
static char *device_info;
|
||||
|
||||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_ll sa;
|
||||
|
||||
|
@ -81,14 +77,14 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
|
||||
|
@ -107,7 +103,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
|
||||
|
@ -122,8 +118,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t raw_socket_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
|
@ -35,7 +35,7 @@
|
|||
#define DEFAULT_DEVICE "/dev/tun"
|
||||
|
||||
int device_fd = -1;
|
||||
int ip_fd = -1, if_fd = -1;
|
||||
static int ip_fd = -1, if_fd = -1;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char *device_info = NULL;
|
||||
|
@ -43,7 +43,7 @@ static char *device_info = NULL;
|
|||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
int ppa;
|
||||
char *ptr;
|
||||
|
||||
|
@ -105,7 +105,7 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
close(if_fd);
|
||||
close(ip_fd);
|
||||
close(device_fd);
|
||||
|
@ -114,7 +114,7 @@ void close_device(void) {
|
|||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
if((lenin = read(device_fd, packet->data + 14, MTU - 14)) <= 0) {
|
||||
|
@ -149,7 +149,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
|
||||
|
@ -164,8 +164,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t os_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
|
|
@ -650,7 +650,7 @@ int main2(int argc, char **argv) {
|
|||
/* Shutdown properly. */
|
||||
|
||||
ifdebug(CONNECTIONS)
|
||||
dump_device_stats();
|
||||
devops.dump_stats();
|
||||
|
||||
close_network_connections();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.c -- UML network socket
|
||||
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
|
||||
|
@ -30,14 +30,11 @@
|
|||
#include "route.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
int device_fd = -1;
|
||||
static int listen_fd = -1;
|
||||
static int request_fd = -1;
|
||||
static int data_fd = -1;
|
||||
static int write_fd = -1;
|
||||
static int state = 0;
|
||||
char *device = NULL;
|
||||
char *iface = NULL;
|
||||
static char *device_info;
|
||||
|
||||
extern char *identname;
|
||||
|
@ -57,7 +54,7 @@ static struct request {
|
|||
|
||||
static struct sockaddr_un data_sun;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
struct sockaddr_un listen_sun;
|
||||
static const int one = 1;
|
||||
struct {
|
||||
|
@ -170,7 +167,7 @@ void close_device(void) {
|
|||
if(iface) free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
switch(state) {
|
||||
|
@ -252,7 +249,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
}
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
if(state != 2) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Dropping packet of %d bytes to %s: not connected to UML yet",
|
||||
packet->len, device_info);
|
||||
|
@ -276,8 +273,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t uml_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
|
@ -29,13 +29,10 @@
|
|||
#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;
|
||||
|
@ -44,7 +41,7 @@ extern volatile bool running;
|
|||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
bool setup_device(void) {
|
||||
static bool setup_device(void) {
|
||||
libvdeplug_dynopen(plug);
|
||||
|
||||
if(!plug.dl_handle) {
|
||||
|
@ -85,7 +82,7 @@ bool setup_device(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void close_device(void) {
|
||||
static void close_device(void) {
|
||||
if(conn)
|
||||
plug.vde_close(conn);
|
||||
|
||||
|
@ -97,7 +94,7 @@ void close_device(void) {
|
|||
free(iface);
|
||||
}
|
||||
|
||||
bool read_packet(vpn_packet_t *packet) {
|
||||
static 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));
|
||||
|
@ -112,7 +109,7 @@ bool read_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool write_packet(vpn_packet_t *packet) {
|
||||
static 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));
|
||||
|
@ -127,8 +124,16 @@ bool write_packet(vpn_packet_t *packet) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void dump_device_stats(void) {
|
||||
static 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);
|
||||
}
|
||||
|
||||
const devops_t vde_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
Loading…
Reference in a new issue