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;
109 for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
113 if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU)
116 } else if(n->maxmtu <= n->minmtu)
119 len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
126 memset(packet.data, 0, 14);
127 randomize(packet.data + 14, len - 14);
129 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
131 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
133 send_udppacket(mesh, n, &packet);
136 n->status.broadcast = false;
139 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval) {
140 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) {
148 send_mtu_probe_handler(&mesh->loop, n);
151 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
152 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
154 if(!packet->data[0]) {
155 /* It's a probe request, send back a reply */
159 /* Temporarily set udp_confirmed, so that the reply is sent
160 back exactly the way it came in. */
162 bool udp_confirmed = n->status.udp_confirmed;
163 n->status.udp_confirmed = true;
164 send_udppacket(mesh, n, packet);
165 n->status.udp_confirmed = udp_confirmed;
167 /* It's a valid reply: now we know bidirectional communication
168 is possible using the address and socket that the reply
171 n->status.udp_confirmed = true;
173 /* If we haven't established the PMTU yet, restart the discovery process. */
175 if(n->mtuprobes > 30) {
176 if(len == n->maxmtu + 8) {
177 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
189 /* If applicable, raise the minimum supported MTU */
198 static uint16_t compress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
200 memcpy(dest, source, len);
202 } else if(level == 10)
204 else if(level < 10) {
206 unsigned long destlen = MAXSIZE;
207 if(compress2(dest, &destlen, source, len, level) == Z_OK)
218 static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
220 memcpy(dest, source, len);
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);
266 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
269 void receive_tcppacket(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int len) {
272 if(len > sizeof outpkt.data)
277 memcpy(outpkt.data, buffer, len);
279 receive_packet(mesh, c->node, &outpkt);
282 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
283 if(!n->status.validkey) {
284 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
285 if(!n->status.waitingforkey)
286 send_req_key(mesh, n);
287 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
288 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
289 sptps_stop(&n->sptps);
290 n->status.waitingforkey = false;
291 send_req_key(mesh, n);
298 // If it's a probe, send it immediately without trying to compress it.
300 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
306 if(n->outcompression) {
307 int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
309 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
310 else if(len < origpkt->len) {
313 type |= PKT_COMPRESSED;
317 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
321 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
326 /* If the UDP address is confirmed, use it. */
327 if(n->status.udp_confirmed)
330 /* Send every third packet to n->address; that could be set
331 to the node's reflexive UDP address discovered during key
340 /* Otherwise, address are found in edges to this node.
341 So we pick a random edge and a random socket. */
344 int j = rand() % n->edge_tree->count;
345 edge_t *candidate = NULL;
347 for splay_each(edge_t, e, n->edge_tree) {
349 candidate = e->reverse;
355 *sa = &candidate->address;
356 *sock = rand() % mesh->listen_sockets;
359 /* Make sure we have a suitable socket for the chosen address */
360 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
361 for(int i = 0; i < mesh->listen_sockets; i++) {
362 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
370 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
371 static sockaddr_t broadcast_ipv4 = {
373 .sin_family = AF_INET,
374 .sin_addr.s_addr = -1,
378 static sockaddr_t broadcast_ipv6 = {
380 .sin6_family = AF_INET6,
381 .sin6_addr.s6_addr[0x0] = 0xff,
382 .sin6_addr.s6_addr[0x1] = 0x02,
383 .sin6_addr.s6_addr[0xf] = 0x01,
387 *sock = rand() % mesh->listen_sockets;
389 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
390 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
391 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
392 *sa = &mesh->localdiscovery_address;
394 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
395 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
396 *sa = &broadcast_ipv6;
399 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
400 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
401 *sa = &mesh->localdiscovery_address;
403 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
404 *sa = &broadcast_ipv4;
409 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
410 if(!n->status.reachable) {
411 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
415 return send_sptps_packet(mesh, n, origpkt);
418 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
420 meshlink_handle_t *mesh = to->mesh;
422 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
424 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
425 char buf[len * 4 / 3 + 5];
426 b64encode(data, buf, len);
427 /* If no valid key is known yet, send the packets using ANS_KEY requests,
428 to ensure we get to learn the reflexive UDP address. */
429 if(!to->status.validkey) {
430 to->incompression = mesh->self->incompression;
431 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);
433 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
436 /* Otherwise, send the packet via UDP */
438 const sockaddr_t *sa;
441 if(to->status.broadcast)
442 choose_broadcast_address(mesh, to, &sa, &sock);
444 choose_udp_address(mesh, to, &sa, &sock);
446 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
447 if(sockmsgsize(sockerrno)) {
448 if(to->maxmtu >= len)
449 to->maxmtu = len - 1;
453 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
461 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
462 node_t *from = handle;
463 meshlink_handle_t *mesh = from->mesh;
465 if(type == SPTPS_HANDSHAKE) {
466 if(!from->status.validkey) {
467 from->status.validkey = true;
468 from->status.waitingforkey = false;
469 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
475 logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
481 if(type == PKT_PROBE) {
484 memcpy(inpkt.data, data, len);
485 mtu_probe_h(mesh, from, &inpkt, len);
490 if(type & ~(PKT_COMPRESSED)) {
491 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
495 if(type & PKT_COMPRESSED) {
496 uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression);
501 if(inpkt.len > MAXSIZE)
504 memcpy(inpkt.data, data, len);
508 receive_packet(mesh, from, &inpkt);
513 send a packet to the given vpn ip.
515 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
516 if(n == mesh->self) {
518 n->out_bytes += packet->len;
519 // TODO: send to application
523 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s (%s)",
524 packet->len, n->name, n->hostname);
526 if(!n->status.reachable) {
527 logger(mesh, MESHLINK_WARNING, "Node %s (%s) is not reachable",
528 n->name, n->hostname);
533 n->out_bytes += packet->len;
535 send_sptps_packet(mesh, n, packet);
539 /* Broadcast a packet using the minimum spanning tree */
541 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
542 // Always give ourself a copy of the packet.
543 if(from != mesh->self)
544 send_packet(mesh, mesh->self, packet);
546 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
547 packet->len, from->name, from->hostname);
549 for list_each(connection_t, c, mesh->connections)
550 if(c->status.active && c->status.mst && c != from->nexthop->connection)
551 send_packet(mesh, c->node, packet);
554 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
557 static time_t last_hard_try = 0;
559 for splay_each(edge_t, e, mesh->edges) {
560 if(!e->to->status.reachable || e->to == mesh->self)
563 if(sockaddrcmp_noport(from, &e->address)) {
564 if(last_hard_try == mesh->loop.now.tv_sec)
569 if(!try_mac(mesh, e->to, pkt))
577 last_hard_try = mesh->loop.now.tv_sec;
579 last_hard_try = mesh->loop.now.tv_sec;
583 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
584 meshlink_handle_t *mesh = loop->data;
585 listen_socket_t *ls = data;
588 sockaddr_t from = {{0}};
589 socklen_t fromlen = sizeof from;
593 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
595 if(len <= 0 || len > MAXSIZE) {
596 if(!sockwouldblock(sockerrno))
597 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
603 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
605 n = lookup_node_udp(mesh, &from);
608 n = try_harder(mesh, &from, &pkt);
610 update_node_udp(mesh, n, &from);
611 else if(mesh->log_level >= MESHLINK_WARNING) {
612 hostname = sockaddr2hostname(&from);
613 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
620 if(n->status.blacklisted) {
621 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
624 n->sock = ls - mesh->listen_socket;
626 receive_udppacket(mesh, n, &pkt);