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) {
202 static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
208 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
209 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s (%s)",
210 packet->len, n->name, n->hostname);
212 if(n->status.blacklisted)
213 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
216 n->in_bytes += packet->len;
218 route(mesh, n, packet);
222 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
223 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
226 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
227 if(!n->sptps.state) {
228 if(!n->status.waitingforkey) {
229 logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
230 send_req_key(mesh, n);
232 logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
235 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
238 void receive_tcppacket(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int len) {
241 if(len > sizeof(outpkt).data)
246 memcpy(outpkt.data, buffer, len);
248 receive_packet(mesh, c->node, &outpkt);
251 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
252 if(!n->status.validkey) {
253 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
254 if(!n->status.waitingforkey)
255 send_req_key(mesh, n);
256 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
257 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
258 sptps_stop(&n->sptps);
259 n->status.waitingforkey = false;
260 send_req_key(mesh, n);
267 // If it's a probe, send it immediately without trying to compress it.
269 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
275 if(n->outcompression) {
276 int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
278 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
279 else if(len < origpkt->len) {
282 type |= PKT_COMPRESSED;
286 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
290 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
295 /* If the UDP address is confirmed, use it. */
296 if(n->status.udp_confirmed)
299 /* Send every third packet to n->address; that could be set
300 to the node's reflexive UDP address discovered during key
309 /* Otherwise, address are found in edges to this node.
310 So we pick a random edge and a random socket. */
313 int j = rand() % n->edge_tree->count;
314 edge_t *candidate = NULL;
316 for splay_each(edge_t, e, n->edge_tree) {
318 candidate = e->reverse;
324 *sa = &candidate->address;
325 *sock = rand() % mesh->listen_sockets;
328 /* Make sure we have a suitable socket for the chosen address */
329 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
330 for(int i = 0; i < mesh->listen_sockets; i++) {
331 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
339 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
340 static sockaddr_t broadcast_ipv4 = {
342 .sin_family = AF_INET,
343 .sin_addr.s_addr = -1,
347 static sockaddr_t broadcast_ipv6 = {
349 .sin6_family = AF_INET6,
350 .sin6_addr.s6_addr[0x0] = 0xff,
351 .sin6_addr.s6_addr[0x1] = 0x02,
352 .sin6_addr.s6_addr[0xf] = 0x01,
356 *sock = rand() % mesh->listen_sockets;
358 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
359 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
360 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
361 *sa = &mesh->localdiscovery_address;
363 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
364 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
365 *sa = &broadcast_ipv6;
368 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
369 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
370 *sa = &mesh->localdiscovery_address;
372 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
373 *sa = &broadcast_ipv4;
378 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
379 if(!n->status.reachable) {
380 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
384 return send_sptps_packet(mesh, n, origpkt);
387 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
389 meshlink_handle_t *mesh = to->mesh;
391 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
393 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
394 char buf[len * 4 / 3 + 5];
395 b64encode(data, buf, len);
396 /* If no valid key is known yet, send the packets using ANS_KEY requests,
397 to ensure we get to learn the reflexive UDP address. */
398 if(!to->status.validkey) {
399 to->incompression = mesh->self->incompression;
400 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);
402 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
405 /* Otherwise, send the packet via UDP */
407 const sockaddr_t *sa;
410 if(to->status.broadcast)
411 choose_broadcast_address(mesh, to, &sa, &sock);
413 choose_udp_address(mesh, to, &sa, &sock);
415 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
416 if(sockmsgsize(sockerrno)) {
417 if(to->maxmtu >= len)
418 to->maxmtu = len - 1;
422 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
430 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
431 node_t *from = handle;
432 meshlink_handle_t *mesh = from->mesh;
434 if(type == SPTPS_HANDSHAKE) {
435 if(!from->status.validkey) {
436 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
437 from->status.validkey = true;
438 from->status.waitingforkey = false;
440 utcp_reset_timers(from->utcp);
446 logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
452 if(type == PKT_PROBE) {
455 memcpy(inpkt.data, data, len);
456 mtu_probe_h(mesh, from, &inpkt, len);
461 if(type & ~(PKT_COMPRESSED)) {
462 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
466 if(type & PKT_COMPRESSED) {
467 uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression);
472 if(inpkt.len > MAXSIZE)
475 memcpy(inpkt.data, data, len);
479 receive_packet(mesh, from, &inpkt);
484 send a packet to the given vpn ip.
486 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
487 if(n == mesh->self) {
489 n->out_bytes += packet->len;
490 // TODO: send to application
494 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s (%s)",
495 packet->len, n->name, n->hostname);
497 if(!n->status.reachable) {
498 logger(mesh, MESHLINK_WARNING, "Node %s (%s) is not reachable",
499 n->name, n->hostname);
504 n->out_bytes += packet->len;
506 send_sptps_packet(mesh, n, packet);
510 /* Broadcast a packet using the minimum spanning tree */
512 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
513 // Always give ourself a copy of the packet.
514 if(from != mesh->self)
515 send_packet(mesh, mesh->self, packet);
517 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
518 packet->len, from->name, from->hostname);
520 for list_each(connection_t, c, mesh->connections)
521 if(c->status.active && c->status.mst && c != from->nexthop->connection)
522 send_packet(mesh, c->node, packet);
525 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
528 static time_t last_hard_try = 0;
530 for splay_each(edge_t, e, mesh->edges) {
531 if(!e->to->status.reachable || e->to == mesh->self)
534 if(sockaddrcmp_noport(from, &e->address)) {
535 if(last_hard_try == mesh->loop.now.tv_sec)
540 if(!try_mac(mesh, e->to, pkt))
548 last_hard_try = mesh->loop.now.tv_sec;
550 last_hard_try = mesh->loop.now.tv_sec;
554 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
555 meshlink_handle_t *mesh = loop->data;
556 listen_socket_t *ls = data;
559 sockaddr_t from = {{0}};
560 socklen_t fromlen = sizeof(from);
564 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
566 if(len <= 0 || len > MAXSIZE) {
567 if(!sockwouldblock(sockerrno))
568 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
574 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
576 n = lookup_node_udp(mesh, &from);
579 n = try_harder(mesh, &from, &pkt);
581 update_node_udp(mesh, n, &from);
582 else if(mesh->log_level >= MESHLINK_WARNING) {
583 hostname = sockaddr2hostname(&from);
584 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
591 if(n->status.blacklisted) {
592 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
595 n->sock = ls - mesh->listen_socket;
597 receive_udppacket(mesh, n, &pkt);