Import Upstream version 1.0.18
This commit is contained in:
parent
b9a1c8df12
commit
e5d35e092f
19 changed files with 581 additions and 123 deletions
|
|
@ -7,7 +7,7 @@ EXTRA_DIST = linux/device.c bsd/device.c solaris/device.c cygwin/device.c mingw/
|
|||
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 \
|
||||
dummy_device.c raw_socket_device.c
|
||||
dummy_device.c raw_socket_device.c multicast_device.c
|
||||
|
||||
if UML
|
||||
tincd_SOURCES += uml_device.c
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ am__tincd_SOURCES_DIST = conf.c connection.c edge.c event.c graph.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 dummy_device.c \
|
||||
raw_socket_device.c uml_device.c vde_device.c bsd/tunemu.c
|
||||
raw_socket_device.c multicast_device.c uml_device.c \
|
||||
vde_device.c bsd/tunemu.c
|
||||
@UML_TRUE@am__objects_1 = uml_device.$(OBJEXT)
|
||||
@VDE_TRUE@am__objects_2 = vde_device.$(OBJEXT)
|
||||
@TUNEMU_TRUE@am__objects_3 = tunemu.$(OBJEXT)
|
||||
|
|
@ -73,8 +74,8 @@ am_tincd_OBJECTS = conf.$(OBJEXT) connection.$(OBJEXT) edge.$(OBJEXT) \
|
|||
protocol_misc.$(OBJEXT) protocol_key.$(OBJEXT) \
|
||||
protocol_subnet.$(OBJEXT) route.$(OBJEXT) subnet.$(OBJEXT) \
|
||||
tincd.$(OBJEXT) dummy_device.$(OBJEXT) \
|
||||
raw_socket_device.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
|
||||
$(am__objects_3)
|
||||
raw_socket_device.$(OBJEXT) multicast_device.$(OBJEXT) \
|
||||
$(am__objects_1) $(am__objects_2) $(am__objects_3)
|
||||
nodist_tincd_OBJECTS = device.$(OBJEXT)
|
||||
tincd_OBJECTS = $(am_tincd_OBJECTS) $(nodist_tincd_OBJECTS)
|
||||
tincd_DEPENDENCIES = $(top_builddir)/lib/libvpn.a
|
||||
|
|
@ -196,7 +197,8 @@ tincd_SOURCES = conf.c connection.c edge.c event.c graph.c logger.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 dummy_device.c raw_socket_device.c \
|
||||
$(am__append_1) $(am__append_2) $(am__append_3)
|
||||
multicast_device.c $(am__append_1) $(am__append_2) \
|
||||
$(am__append_3)
|
||||
nodist_tincd_SOURCES = device.c
|
||||
DEFAULT_INCLUDES =
|
||||
noinst_HEADERS = conf.h connection.h device.h edge.h event.h graph.h logger.h meta.h net.h netutl.h node.h process.h \
|
||||
|
|
@ -296,6 +298,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logger.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meta.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multicast_device.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_packet.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net_setup.Po@am__quote@
|
||||
|
|
|
|||
|
|
@ -60,44 +60,54 @@ connection_t *new_connection(void) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void free_connection(connection_t *c) {
|
||||
if(c->name)
|
||||
free(c->name);
|
||||
void free_connection_partially(connection_t *c) {
|
||||
free(c->inkey);
|
||||
free(c->outkey);
|
||||
free(c->mychallenge);
|
||||
free(c->hischallenge);
|
||||
free(c->outbuf);
|
||||
|
||||
if(c->hostname)
|
||||
free(c->hostname);
|
||||
c->inkey = NULL;
|
||||
c->outkey = NULL;
|
||||
c->mychallenge = NULL;
|
||||
c->hischallenge = NULL;
|
||||
c->outbuf = NULL;
|
||||
|
||||
if(c->inkey)
|
||||
free(c->inkey);
|
||||
|
||||
if(c->outkey)
|
||||
free(c->outkey);
|
||||
c->buflen = 0;
|
||||
c->reqlen = 0;
|
||||
c->tcplen = 0;
|
||||
c->allow_request = 0;
|
||||
c->outbuflen = 0;
|
||||
c->outbufsize = 0;
|
||||
c->outbufstart = 0;
|
||||
|
||||
if(c->inctx) {
|
||||
EVP_CIPHER_CTX_cleanup(c->inctx);
|
||||
free(c->inctx);
|
||||
c->inctx = NULL;
|
||||
}
|
||||
|
||||
if(c->outctx) {
|
||||
EVP_CIPHER_CTX_cleanup(c->outctx);
|
||||
free(c->outctx);
|
||||
c->outctx = NULL;
|
||||
}
|
||||
|
||||
if(c->mychallenge)
|
||||
free(c->mychallenge);
|
||||
if(c->rsa_key) {
|
||||
RSA_free(c->rsa_key);
|
||||
c->rsa_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
void free_connection(connection_t *c) {
|
||||
free_connection_partially(c);
|
||||
|
||||
free(c->name);
|
||||
free(c->hostname);
|
||||
|
||||
if(c->config_tree)
|
||||
exit_configuration(&c->config_tree);
|
||||
|
||||
if(c->outbuf)
|
||||
free(c->outbuf);
|
||||
|
||||
if(c->rsa_key)
|
||||
RSA_free(c->rsa_key);
|
||||
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ extern void init_connections(void);
|
|||
extern void exit_connections(void);
|
||||
extern connection_t *new_connection(void) __attribute__ ((__malloc__));
|
||||
extern void free_connection(connection_t *);
|
||||
extern void free_connection_partially(connection_t *);
|
||||
extern void connection_add(connection_t *);
|
||||
extern void connection_del(connection_t *);
|
||||
extern void dump_connections(void);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
device.h -- generic header for device.c
|
||||
Copyright (C) 2001-2005 Ivo Timmermans
|
||||
2001-2011 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2001-2012 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
|
||||
|
|
@ -39,6 +39,7 @@ typedef struct 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 multicast_devops;
|
||||
extern const devops_t uml_devops;
|
||||
extern const devops_t vde_devops;
|
||||
extern devops_t devops;
|
||||
|
|
|
|||
228
src/multicast_device.c
Normal file
228
src/multicast_device.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
device.c -- multicast socket
|
||||
Copyright (C) 2002-2005 Ivo Timmermans,
|
||||
2002-2012 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 "conf.h"
|
||||
#include "device.h"
|
||||
#include "net.h"
|
||||
#include "logger.h"
|
||||
#include "netutl.h"
|
||||
#include "utils.h"
|
||||
#include "route.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
static char *device_info;
|
||||
|
||||
static uint64_t device_total_in = 0;
|
||||
static uint64_t device_total_out = 0;
|
||||
|
||||
static struct addrinfo *ai = NULL;
|
||||
static mac_t ignore_src = {{0}};
|
||||
|
||||
static bool setup_device(void) {
|
||||
char *host;
|
||||
char *port;
|
||||
char *space;
|
||||
int ttl = 1;
|
||||
|
||||
device_info = "multicast socket";
|
||||
|
||||
get_config_string(lookup_config(config_tree, "Interface"), &iface);
|
||||
|
||||
if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
|
||||
logger(LOG_ERR, "Device variable required for %s", device_info);
|
||||
return false;
|
||||
}
|
||||
|
||||
host = xstrdup(device);
|
||||
space = strchr(host, ' ');
|
||||
if(!space) {
|
||||
logger(LOG_ERR, "Port number required for %s", device_info);
|
||||
return false;
|
||||
}
|
||||
|
||||
*space++ = 0;
|
||||
port = space;
|
||||
space = strchr(port, ' ');
|
||||
|
||||
if(space) {
|
||||
*space++ = 0;
|
||||
ttl = atoi(space);
|
||||
}
|
||||
|
||||
ai = str2addrinfo(host, port, SOCK_DGRAM);
|
||||
if(!ai)
|
||||
return false;
|
||||
|
||||
device_fd = socket(ai->ai_family, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(device_fd < 0) {
|
||||
logger(LOG_ERR, "Creating socket failed: %s", sockstrerror(sockerrno));
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef FD_CLOEXEC
|
||||
fcntl(device_fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
static const int one = 1;
|
||||
setsockopt(device_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof one);
|
||||
|
||||
if(bind(device_fd, ai->ai_addr, ai->ai_addrlen)) {
|
||||
closesocket(device_fd);
|
||||
logger(LOG_ERR, "Can't bind to %s %s: %s", host, port, sockstrerror(sockerrno));
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(ai->ai_family) {
|
||||
#ifdef IP_ADD_MEMBERSHIP
|
||||
case AF_INET: {
|
||||
struct ip_mreq mreq;
|
||||
struct sockaddr_in in;
|
||||
memcpy(&in, ai->ai_addr, sizeof in);
|
||||
mreq.imr_multiaddr.s_addr = in.sin_addr.s_addr;
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
||||
if(setsockopt(device_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof mreq)) {
|
||||
logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
|
||||
closesocket(device_fd);
|
||||
return false;
|
||||
}
|
||||
#ifdef IP_MULTICAST_LOOP
|
||||
setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&one, sizeof one);
|
||||
#endif
|
||||
#ifdef IP_MULTICAST_TTL
|
||||
setsockopt(device_fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof ttl);
|
||||
#endif
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_JOIN_GROUP
|
||||
case AF_INET6: {
|
||||
struct ipv6_mreq mreq;
|
||||
struct sockaddr_in6 in6;
|
||||
memcpy(&in6, ai->ai_addr, sizeof in6);
|
||||
memcpy(&mreq.ipv6mr_multiaddr, &in6.sin6_addr, sizeof mreq.ipv6mr_multiaddr);
|
||||
mreq.ipv6mr_interface = in6.sin6_scope_id;
|
||||
if(setsockopt(device_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (void *)&mreq, sizeof mreq)) {
|
||||
logger(LOG_ERR, "Cannot join multicast group %s %s: %s", host, port, sockstrerror(sockerrno));
|
||||
closesocket(device_fd);
|
||||
return false;
|
||||
}
|
||||
#ifdef IPV6_MULTICAST_LOOP
|
||||
setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&one, sizeof one);
|
||||
#endif
|
||||
#ifdef IPV6_MULTICAST_HOPS
|
||||
setsockopt(device_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&ttl, sizeof ttl);
|
||||
#endif
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
logger(LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family);
|
||||
closesocket(device_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger(LOG_INFO, "%s is a %s", device, device_info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void close_device(void) {
|
||||
close(device_fd);
|
||||
|
||||
free(device);
|
||||
free(iface);
|
||||
|
||||
if(ai)
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin;
|
||||
|
||||
if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) {
|
||||
logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
|
||||
device, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!memcmp(&ignore_src, packet->data + 6, sizeof ignore_src)) {
|
||||
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignoring loopback packet of %d bytes from %s", lenin, device_info);
|
||||
packet->len = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static bool write_packet(vpn_packet_t *packet) {
|
||||
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
|
||||
packet->len, device_info);
|
||||
|
||||
if(sendto(device_fd, packet->data, packet->len, 0, ai->ai_addr, ai->ai_addrlen) < 0) {
|
||||
logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device,
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
device_total_out += packet->len;
|
||||
|
||||
memcpy(&ignore_src, packet->data + 6, sizeof ignore_src);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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 multicast_devops = {
|
||||
.setup = setup_device,
|
||||
.close = close_device,
|
||||
.read = read_packet,
|
||||
.write = write_packet,
|
||||
.dump_stats = dump_device_stats,
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
static bool not_supported(void) {
|
||||
logger(LOG_ERR, "Raw socket device not supported on this platform");
|
||||
return false;
|
||||
}
|
||||
|
||||
const devops_t multicast_devops = {
|
||||
.setup = not_supported,
|
||||
.close = NULL,
|
||||
.read = NULL,
|
||||
.write = NULL,
|
||||
.dump_stats = NULL,
|
||||
};
|
||||
#endif
|
||||
24
src/net.c
24
src/net.c
|
|
@ -204,18 +204,14 @@ void terminate_connection(connection_t *c, bool report) {
|
|||
}
|
||||
}
|
||||
|
||||
free_connection_partially(c);
|
||||
|
||||
/* Check if this was our outgoing connection */
|
||||
|
||||
if(c->outgoing) {
|
||||
retry_outgoing(c->outgoing);
|
||||
c->outgoing = NULL;
|
||||
c->status.remove = false;
|
||||
do_outgoing_connection(c);
|
||||
}
|
||||
|
||||
free(c->outbuf);
|
||||
c->outbuf = NULL;
|
||||
c->outbuflen = 0;
|
||||
c->outbufsize = 0;
|
||||
c->outbufstart = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -238,7 +234,7 @@ static void check_dead_connections(void) {
|
|||
if(c->status.active) {
|
||||
if(c->status.pinged) {
|
||||
ifdebug(CONNECTIONS) logger(LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds",
|
||||
c->name, c->hostname, now - c->last_ping_time);
|
||||
c->name, c->hostname, (long)now - c->last_ping_time);
|
||||
c->status.timeout = true;
|
||||
terminate_connection(c, true);
|
||||
} else if(c->last_ping_time + pinginterval <= now) {
|
||||
|
|
@ -267,7 +263,7 @@ static void check_dead_connections(void) {
|
|||
if(c->status.active) {
|
||||
ifdebug(CONNECTIONS) logger(LOG_INFO,
|
||||
"%s (%s) could not flush for %ld seconds (%d bytes remaining)",
|
||||
c->name, c->hostname, now - c->last_flushed_time, c->outbuflen);
|
||||
c->name, c->hostname, (long)now - c->last_flushed_time, c->outbuflen);
|
||||
c->status.timeout = true;
|
||||
terminate_connection(c, true);
|
||||
}
|
||||
|
|
@ -290,9 +286,11 @@ 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(devops.read(&packet)) {
|
||||
errors = 0;
|
||||
packet.priority = 0;
|
||||
route(myself, &packet);
|
||||
if(packet.len) {
|
||||
errors = 0;
|
||||
packet.priority = 0;
|
||||
route(myself, &packet);
|
||||
}
|
||||
} else {
|
||||
usleep(errors * 50000);
|
||||
errors++;
|
||||
|
|
|
|||
|
|
@ -548,6 +548,8 @@ static bool setup_myself(void) {
|
|||
devops = dummy_devops;
|
||||
else if(!strcasecmp(type, "raw_socket"))
|
||||
devops = raw_socket_devops;
|
||||
else if(!strcasecmp(type, "multicast"))
|
||||
devops = multicast_devops;
|
||||
#ifdef ENABLE_UML
|
||||
else if(!strcasecmp(type, "uml"))
|
||||
devops = uml_devops;
|
||||
|
|
@ -587,12 +589,25 @@ static bool setup_myself(void) {
|
|||
if(cfg)
|
||||
cfg = lookup_config_next(config_tree, cfg);
|
||||
|
||||
char *port = myport;
|
||||
|
||||
if(address) {
|
||||
char *space = strchr(address, ' ');
|
||||
if(space) {
|
||||
*space++ = 0;
|
||||
port = space;
|
||||
}
|
||||
|
||||
if(!strcmp(address, "*"))
|
||||
*address = 0;
|
||||
}
|
||||
|
||||
hint.ai_family = addressfamily;
|
||||
hint.ai_socktype = SOCK_STREAM;
|
||||
hint.ai_protocol = IPPROTO_TCP;
|
||||
hint.ai_flags = AI_PASSIVE;
|
||||
|
||||
err = getaddrinfo(address, myport, &hint, &ai);
|
||||
err = getaddrinfo(address && *address ? address : NULL, port, &hint, &ai);
|
||||
free(address);
|
||||
|
||||
if(err || !ai) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
protocol_misc.c -- handle the meta-protocol, miscellaneous functions
|
||||
Copyright (C) 1999-2005 Ivo Timmermans,
|
||||
2000-2009 Guus Sliepen <guus@tinc-vpn.org>
|
||||
2000-2012 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
|
||||
|
|
@ -111,8 +111,14 @@ bool pong_h(connection_t *c) {
|
|||
|
||||
/* Succesful connection, reset timeout if this is an outgoing connection. */
|
||||
|
||||
if(c->outgoing)
|
||||
if(c->outgoing) {
|
||||
c->outgoing->timeout = 0;
|
||||
c->outgoing->cfg = NULL;
|
||||
if(c->outgoing->ai)
|
||||
freeaddrinfo(c->outgoing->ai);
|
||||
c->outgoing->ai = NULL;
|
||||
c->outgoing->aip = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
rmode_t routing_mode = RMODE_ROUTER;
|
||||
fmode_t forwarding_mode = FMODE_INTERNAL;
|
||||
bool decrement_ttl = true;
|
||||
bool decrement_ttl = false;
|
||||
bool directonly = false;
|
||||
bool priorityinheritance = false;
|
||||
int macexpire = 600;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ static void close_device(void) {
|
|||
}
|
||||
|
||||
static bool read_packet(vpn_packet_t *packet) {
|
||||
int lenin = plug.vde_recv(conn, packet->data, MTU, 0);
|
||||
int lenin = (ssize_t)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;
|
||||
|
|
@ -114,7 +114,7 @@ static bool read_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((ssize_t)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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue