2 net_packet.c -- Handles in- and outgoing VPN packets
3 Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "connection.h"
31 #include "meshlink_internal.h"
41 static void send_udppacket(meshlink_handle_t *mesh, node_t *, vpn_packet_t *);
43 #define MAX_SEQNO 1073741824
45 /* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
46 mtuprobes == 31: sleep pinginterval seconds
47 mtuprobes == 32: send 1 burst, sleep pingtimeout second
48 mtuprobes == 33: no response from other side, restart PMTU discovery process
50 Probes are sent in batches of at least three, with random sizes between the
51 lower and upper boundaries for the MTU thus far discovered.
53 After the initial discovery, a fourth packet is added to each batch with a
54 size larger than the currently known PMTU, to test if the PMTU has increased.
56 In case local discovery is enabled, another packet is added to each batch,
57 which will be broadcast to the local network.
61 static void send_mtu_probe_handler(event_loop_t *loop, void *data) {
62 meshlink_handle_t *mesh = loop->data;
68 if(!n->status.reachable || !n->status.validkey) {
69 logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
74 if(n->mtuprobes > 32) {
77 timeout = mesh->pinginterval;
81 logger(mesh, MESHLINK_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
82 n->status.udp_confirmed = false;
88 if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
89 logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
93 if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
94 if(n->minmtu > n->maxmtu)
95 n->minmtu = n->maxmtu;
97 n->maxmtu = n->minmtu;
99 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
103 if(n->mtuprobes == 31) {
104 timeout = mesh->pinginterval;
106 } else if(n->mtuprobes == 32) {
107 timeout = mesh->pingtimeout;
110 for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
114 if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU)
117 } else if(n->maxmtu <= n->minmtu) {
120 len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
128 memset(packet.data, 0, 14);
129 randomize(packet.data + 14, len - 14);
131 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
133 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
135 send_udppacket(mesh, n, &packet);
138 n->status.broadcast = false;
141 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
144 void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
145 timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0});
146 send_mtu_probe_handler(&mesh->loop, n);
149 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
150 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
152 if(!packet->data[0]) {
153 /* It's a probe request, send back a reply */
157 /* Temporarily set udp_confirmed, so that the reply is sent
158 back exactly the way it came in. */
160 bool udp_confirmed = n->status.udp_confirmed;
161 n->status.udp_confirmed = true;
162 send_udppacket(mesh, n, packet);
163 n->status.udp_confirmed = udp_confirmed;
165 /* It's a valid reply: now we know bidirectional communication
166 is possible using the address and socket that the reply
169 n->status.udp_confirmed = true;
171 /* If we haven't established the PMTU yet, restart the discovery process. */
173 if(n->mtuprobes > 30) {
174 if (len == n->maxmtu + 8) {
175 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
187 /* If applicable, raise the minimum supported MTU */
196 static uint16_t compress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
198 memcpy(dest, source, len);
200 } else if(level == 10) {
202 } else if(level < 10) {
204 unsigned long destlen = MAXSIZE;
205 if(compress2(dest, &destlen, source, len, level) == Z_OK)
217 static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
219 memcpy(dest, source, len);
221 } else if(level > 9) {
226 unsigned long destlen = MAXSIZE;
227 if(uncompress(dest, &destlen, source, len) == Z_OK)
239 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
240 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s (%s)",
241 packet->len, n->name, n->hostname);
243 if (n->status.blacklisted) {
244 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
247 n->in_bytes += packet->len;
249 route(mesh, n, packet);
253 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
254 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
257 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
258 if(!n->sptps.state) {
259 if(!n->status.waitingforkey) {
260 logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
261 send_req_key(mesh, n);
263 logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
267 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
270 void receive_tcppacket(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int len) {
273 if(len > sizeof outpkt.data)
278 memcpy(outpkt.data, buffer, len);
280 receive_packet(mesh, c->node, &outpkt);
283 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
284 if(!n->status.validkey) {
285 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
286 if(!n->status.waitingforkey)
287 send_req_key(mesh, n);
288 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
289 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
290 sptps_stop(&n->sptps);
291 n->status.waitingforkey = false;
292 send_req_key(mesh, n);
299 // If it's a probe, send it immediately without trying to compress it.
301 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
307 if(n->outcompression) {
308 int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
310 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
311 } else if(len < origpkt->len) {
314 type |= PKT_COMPRESSED;
318 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
322 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
327 /* If the UDP address is confirmed, use it. */
328 if(n->status.udp_confirmed)
331 /* Send every third packet to n->address; that could be set
332 to the node's reflexive UDP address discovered during key
341 /* Otherwise, address are found in edges to this node.
342 So we pick a random edge and a random socket. */
345 int j = rand() % n->edge_tree->count;
346 edge_t *candidate = NULL;
348 for splay_each(edge_t, e, n->edge_tree) {
350 candidate = e->reverse;
356 *sa = &candidate->address;
357 *sock = rand() % mesh->listen_sockets;
360 /* Make sure we have a suitable socket for the chosen address */
361 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
362 for(int i = 0; i < mesh->listen_sockets; i++) {
363 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
371 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
372 static sockaddr_t broadcast_ipv4 = {
374 .sin_family = AF_INET,
375 .sin_addr.s_addr = -1,
379 static sockaddr_t broadcast_ipv6 = {
381 .sin6_family = AF_INET6,
382 .sin6_addr.s6_addr[0x0] = 0xff,
383 .sin6_addr.s6_addr[0x1] = 0x02,
384 .sin6_addr.s6_addr[0xf] = 0x01,
388 *sock = rand() % mesh->listen_sockets;
390 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
391 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
392 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
393 *sa = &mesh->localdiscovery_address;
395 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
396 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
397 *sa = &broadcast_ipv6;
400 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
401 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
402 *sa = &mesh->localdiscovery_address;
404 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
405 *sa = &broadcast_ipv4;
410 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
411 if(!n->status.reachable) {
412 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
416 return send_sptps_packet(mesh, n, origpkt);
419 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
421 meshlink_handle_t *mesh = to->mesh;
423 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
425 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
426 char buf[len * 4 / 3 + 5];
427 b64encode(data, buf, len);
428 /* If no valid key is known yet, send the packets using ANS_KEY requests,
429 to ensure we get to learn the reflexive UDP address. */
430 if(!to->status.validkey) {
431 to->incompression = mesh->self->incompression;
432 return send_request(mesh, to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, to->incompression);
434 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
438 /* Otherwise, send the packet via UDP */
440 const sockaddr_t *sa;
443 if(to->status.broadcast)
444 choose_broadcast_address(mesh, to, &sa, &sock);
446 choose_udp_address(mesh, to, &sa, &sock);
448 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
449 if(sockmsgsize(sockerrno)) {
450 if(to->maxmtu >= len)
451 to->maxmtu = len - 1;
455 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
463 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
464 node_t *from = handle;
465 meshlink_handle_t *mesh = from->mesh;
467 if(type == SPTPS_HANDSHAKE) {
468 if(!from->status.validkey) {
469 from->status.validkey = true;
470 from->status.waitingforkey = false;
471 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
477 logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
483 if(type == PKT_PROBE) {
486 memcpy(inpkt.data, data, len);
487 mtu_probe_h(mesh, from, &inpkt, len);
493 if(type & ~(PKT_COMPRESSED)) {
494 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
498 if(type & PKT_COMPRESSED) {
499 uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression);
505 if(inpkt.len > MAXSIZE)
508 memcpy(inpkt.data, data, len);
512 receive_packet(mesh, from, &inpkt);
517 send a packet to the given vpn ip.
519 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
520 if(n == mesh->self) {
522 n->out_bytes += packet->len;
523 // TODO: send to application
527 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s (%s)",
528 packet->len, n->name, n->hostname);
530 if(!n->status.reachable) {
531 logger(mesh, MESHLINK_WARNING, "Node %s (%s) is not reachable",
532 n->name, n->hostname);
537 n->out_bytes += packet->len;
539 send_sptps_packet(mesh, n, packet);
543 /* Broadcast a packet using the minimum spanning tree */
545 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
546 // Always give ourself a copy of the packet.
547 if(from != mesh->self)
548 send_packet(mesh, mesh->self, packet);
550 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
551 packet->len, from->name, from->hostname);
553 for list_each(connection_t, c, mesh->connections)
554 if(c->status.active && c->status.mst && c != from->nexthop->connection)
555 send_packet(mesh, c->node, packet);
558 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
561 static time_t last_hard_try = 0;
563 for splay_each(edge_t, e, mesh->edges) {
564 if(!e->to->status.reachable || e->to == mesh->self)
567 if(sockaddrcmp_noport(from, &e->address)) {
568 if(last_hard_try == mesh->loop.now.tv_sec)
573 if(!try_mac(mesh, e->to, pkt))
581 last_hard_try = mesh->loop.now.tv_sec;
583 last_hard_try = mesh->loop.now.tv_sec;
587 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
588 meshlink_handle_t *mesh = loop->data;
589 listen_socket_t *ls = data;
592 sockaddr_t from = {{0}};
593 socklen_t fromlen = sizeof from;
597 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
599 if(len <= 0 || len > MAXSIZE) {
600 if(!sockwouldblock(sockerrno))
601 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
607 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
609 n = lookup_node_udp(mesh, &from);
612 n = try_harder(mesh, &from, &pkt);
614 update_node_udp(mesh, n, &from);
615 else if(mesh->log_level >= MESHLINK_WARNING) {
616 hostname = sockaddr2hostname(&from);
617 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
625 if (n->status.blacklisted) {
626 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
629 n->sock = ls - mesh->listen_socket;
631 receive_udppacket(mesh, n, &pkt);