Merge remote-tracking branch 'remotes/guus/1.1' into thkr-1.1-ponyhof
This commit is contained in:
commit
07ec2d2eb2
3 changed files with 83 additions and 36 deletions
1
THANKS
1
THANKS
|
@ -67,6 +67,7 @@ We would like to thank the following people for their contributions to tinc:
|
||||||
* Robert van der Meulen
|
* Robert van der Meulen
|
||||||
* Rumko
|
* Rumko
|
||||||
* Sam Bryan
|
* Sam Bryan
|
||||||
|
* Samuel Thibault
|
||||||
* Saverio Proto
|
* Saverio Proto
|
||||||
* Scott Lamb
|
* Scott Lamb
|
||||||
* Steffan Karger
|
* Steffan Karger
|
||||||
|
|
|
@ -239,7 +239,7 @@ AC_CHECK_TYPES([socklen_t, struct ether_header, struct arphdr, struct ether_arp,
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_TYPE_SIGNAL
|
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 usleep unsetenv vsyslog writev],
|
AC_CHECK_FUNCS([asprintf daemon fchmod flock ftime fork get_current_dir_name gettimeofday mlockall putenv random recvmmsg select strdup strerror strsignal strtol system time usleep unsetenv vsyslog writev],
|
||||||
[], [], [#include "$srcdir/src/have.h"]
|
[], [], [#include "$srcdir/src/have.h"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
116
src/net_packet.c
116
src/net_packet.c
|
@ -1404,43 +1404,28 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_incoming_vpn_data(void *data, int flags) {
|
static void handle_incoming_vpn_packet(listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *addr) {
|
||||||
listen_socket_t *ls = data;
|
|
||||||
vpn_packet_t pkt;
|
|
||||||
char *hostname;
|
char *hostname;
|
||||||
node_id_t nullid = {};
|
node_id_t nullid = {};
|
||||||
sockaddr_t addr = {};
|
|
||||||
socklen_t addrlen = sizeof addr;
|
|
||||||
node_t *from, *to;
|
node_t *from, *to;
|
||||||
bool direct = false;
|
bool direct = false;
|
||||||
UNUSED(flags);
|
UNUSED(flags);
|
||||||
|
|
||||||
pkt.offset = 0;
|
sockaddrunmap(addr); /* Some braindead IPv6 implementations do stupid things. */
|
||||||
int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen);
|
|
||||||
|
|
||||||
if(len <= 0 || len > MAXSIZE) {
|
|
||||||
if(!sockwouldblock(sockerrno))
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pkt.len = len;
|
|
||||||
|
|
||||||
sockaddrunmap(&addr); /* Some braindead IPv6 implementations do stupid things. */
|
|
||||||
|
|
||||||
// Try to figure out who sent this packet.
|
// Try to figure out who sent this packet.
|
||||||
|
|
||||||
node_t *n = lookup_node_udp(&addr);
|
node_t *n = lookup_node_udp(addr);
|
||||||
|
|
||||||
if(n && !n->status.udp_confirmed)
|
if(n && !n->status.udp_confirmed)
|
||||||
n = NULL; // Don't believe it if we don't have confirmation yet.
|
n = NULL; // Don't believe it if we don't have confirmation yet.
|
||||||
|
|
||||||
if(!n) {
|
if(!n) {
|
||||||
// It might be from a 1.1 node, which might have a source ID in the packet.
|
// It might be from a 1.1 node, which might have a source ID in the packet.
|
||||||
pkt.offset = 2 * sizeof(node_id_t);
|
pkt->offset = 2 * sizeof(node_id_t);
|
||||||
from = lookup_node_id(SRCID(&pkt));
|
from = lookup_node_id(SRCID(pkt));
|
||||||
if(from && !memcmp(DSTID(&pkt), &nullid, sizeof nullid) && from->status.sptps) {
|
if(from && !memcmp(DSTID(pkt), &nullid, sizeof nullid) && from->status.sptps) {
|
||||||
if(sptps_verify_datagram(&from->sptps, DATA(&pkt), pkt.len - 2 * sizeof(node_id_t)))
|
if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t)))
|
||||||
n = from;
|
n = from;
|
||||||
else
|
else
|
||||||
goto skip_harder;
|
goto skip_harder;
|
||||||
|
@ -1448,36 +1433,36 @@ void handle_incoming_vpn_data(void *data, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!n) {
|
if(!n) {
|
||||||
pkt.offset = 0;
|
pkt->offset = 0;
|
||||||
n = try_harder(&addr, &pkt);
|
n = try_harder(addr, pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_harder:
|
skip_harder:
|
||||||
if(!n) {
|
if(!n) {
|
||||||
if(debug_level >= DEBUG_PROTOCOL) {
|
if(debug_level >= DEBUG_PROTOCOL) {
|
||||||
hostname = sockaddr2hostname(&addr);
|
hostname = sockaddr2hostname(addr);
|
||||||
logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname);
|
logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from unknown source %s", hostname);
|
||||||
free(hostname);
|
free(hostname);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt.offset = 0;
|
pkt->offset = 0;
|
||||||
|
|
||||||
if(n->status.sptps) {
|
if(n->status.sptps) {
|
||||||
bool relay_enabled = (n->options >> 24) >= 4;
|
bool relay_enabled = (n->options >> 24) >= 4;
|
||||||
if (relay_enabled) {
|
if (relay_enabled) {
|
||||||
pkt.offset = 2 * sizeof(node_id_t);
|
pkt->offset = 2 * sizeof(node_id_t);
|
||||||
pkt.len -= pkt.offset;
|
pkt->len -= pkt->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!memcmp(DSTID(&pkt), &nullid, sizeof nullid) || !relay_enabled) {
|
if(!memcmp(DSTID(pkt), &nullid, sizeof nullid) || !relay_enabled) {
|
||||||
direct = true;
|
direct = true;
|
||||||
from = n;
|
from = n;
|
||||||
to = myself;
|
to = myself;
|
||||||
} else {
|
} else {
|
||||||
from = lookup_node_id(SRCID(&pkt));
|
from = lookup_node_id(SRCID(pkt));
|
||||||
to = lookup_node_id(DSTID(&pkt));
|
to = lookup_node_id(DSTID(pkt));
|
||||||
}
|
}
|
||||||
if(!from || !to) {
|
if(!from || !to) {
|
||||||
logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname);
|
logger(DEBUG_PROTOCOL, LOG_WARNING, "Received UDP packet from %s (%s) with unknown source and/or destination ID", n->name, n->hostname);
|
||||||
|
@ -1503,7 +1488,7 @@ skip_harder:
|
||||||
/* If we're not the final recipient, relay the packet. */
|
/* If we're not the final recipient, relay the packet. */
|
||||||
|
|
||||||
if(to != myself) {
|
if(to != myself) {
|
||||||
send_sptps_data(to, from, 0, DATA(&pkt), pkt.len);
|
send_sptps_data(to, from, 0, DATA(pkt), pkt->len);
|
||||||
try_tx(to, true);
|
try_tx(to, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1512,12 +1497,12 @@ skip_harder:
|
||||||
from = n;
|
from = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!receive_udppacket(from, &pkt))
|
if(!receive_udppacket(from, pkt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
n->sock = ls - listen_socket;
|
n->sock = ls - listen_socket;
|
||||||
if(direct && sockaddrcmp(&addr, &n->address))
|
if(direct && sockaddrcmp(addr, &n->address))
|
||||||
update_node_udp(n, &addr);
|
update_node_udp(n, addr);
|
||||||
|
|
||||||
/* If the packet went through a relay, help the sender find the appropriate MTU
|
/* If the packet went through a relay, help the sender find the appropriate MTU
|
||||||
through the relay path. */
|
through the relay path. */
|
||||||
|
@ -1526,6 +1511,67 @@ skip_harder:
|
||||||
send_mtu_info(myself, n, MTU);
|
send_mtu_info(myself, n, MTU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_incoming_vpn_data(void *data, int flags) {
|
||||||
|
listen_socket_t *ls = data;
|
||||||
|
|
||||||
|
#ifdef HAVE_RECVMMSG
|
||||||
|
#define MAX_MSG 64
|
||||||
|
static int num = MAX_MSG;
|
||||||
|
static vpn_packet_t pkt[MAX_MSG];
|
||||||
|
static sockaddr_t addr[MAX_MSG];
|
||||||
|
static struct mmsghdr msg[MAX_MSG];
|
||||||
|
static struct iovec iov[MAX_MSG];
|
||||||
|
|
||||||
|
for(int i = 0; i < num; i++) {
|
||||||
|
pkt[i].offset = 0;
|
||||||
|
|
||||||
|
iov[i] = (struct iovec){
|
||||||
|
.iov_base = DATA(&pkt[i]),
|
||||||
|
.iov_len = MAXSIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
msg[i].msg_hdr = (struct msghdr){
|
||||||
|
.msg_name = &addr[i].sa,
|
||||||
|
.msg_namelen = sizeof addr[i],
|
||||||
|
.msg_iov = &iov[i],
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
num = recvmmsg(ls->udp.fd, msg, MAX_MSG, MSG_DONTWAIT, NULL);
|
||||||
|
|
||||||
|
if(num < 0) {
|
||||||
|
if(!sockwouldblock(sockerrno))
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < num; i++) {
|
||||||
|
pkt[i].len = msg[i].msg_len;
|
||||||
|
if(pkt[i].len <= 0 || pkt[i].len > MAXSIZE)
|
||||||
|
continue;
|
||||||
|
handle_incoming_vpn_packet(ls, &pkt[i], &addr[i]);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
vpn_packet_t pkt;
|
||||||
|
sockaddr_t addr = {};
|
||||||
|
socklen_t addrlen = sizeof addr;
|
||||||
|
|
||||||
|
pkt.offset = 0;
|
||||||
|
int len = recvfrom(ls->udp.fd, DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen);
|
||||||
|
|
||||||
|
if(len <= 0 || len > MAXSIZE) {
|
||||||
|
if(!sockwouldblock(sockerrno))
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkt.len = len;
|
||||||
|
|
||||||
|
handle_incoming_vpn_packet(ls, &pkt, &addr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void handle_device_data(void *data, int flags) {
|
void handle_device_data(void *data, int flags) {
|
||||||
vpn_packet_t packet;
|
vpn_packet_t packet;
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
|
|
Loading…
Add table
Reference in a new issue