2 net_packet.c -- Handles in- and outgoing VPN packets
3 Copyright (C) 2014-2017 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.
23 #include "connection.h"
27 #include "meshlink_internal.h"
37 static void send_udppacket(meshlink_handle_t *mesh, node_t *, vpn_packet_t *);
39 #define MAX_SEQNO 1073741824
41 /* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
42 mtuprobes == 31: sleep pinginterval seconds
43 mtuprobes == 32: send 1 burst, sleep pingtimeout second
44 mtuprobes == 33: no response from other side, restart PMTU discovery process
46 Probes are sent in batches of at least three, with random sizes between the
47 lower and upper boundaries for the MTU thus far discovered.
49 After the initial discovery, a fourth packet is added to each batch with a
50 size larger than the currently known PMTU, to test if the PMTU has increased.
52 In case local discovery is enabled, another packet is added to each batch,
53 which will be broadcast to the local network.
57 static void send_mtu_probe_handler(event_loop_t *loop, void *data) {
58 meshlink_handle_t *mesh = loop->data;
64 if(!n->status.reachable || !n->status.validkey) {
65 logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s", n->name);
70 if(n->mtuprobes > 32) {
73 timeout = mesh->dev_class_traits[n->devclass].pinginterval;
77 logger(mesh, MESHLINK_INFO, "%s did not respond to UDP ping, restarting PMTU discovery", n->name);
78 n->status.udp_confirmed = false;
83 update_node_pmtu(mesh, n);
86 if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
87 logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s", n->name);
91 if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
92 if(n->minmtu > n->maxmtu) {
93 n->minmtu = n->maxmtu;
94 update_node_pmtu(mesh, n);
96 n->maxmtu = n->minmtu;
100 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, n->mtu, n->mtuprobes);
104 if(n->mtuprobes == 31) {
105 if(!n->minmtu && n->status.want_udp) {
106 /* Send a dummy ANS_KEY to try to update the reflexive UDP address */
107 send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0", ANS_KEY, mesh->self->name, n->name);
108 n->status.want_udp = false;
111 timeout = mesh->dev_class_traits[n->devclass].pinginterval;
113 } else if(n->mtuprobes == 32) {
114 timeout = mesh->dev_class_traits[n->devclass].pingtimeout;
117 for(int i = 0; i < 5; i++) {
121 if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) {
126 } else if(n->maxmtu <= n->minmtu) {
129 len = n->minmtu + 1 + prng(mesh, n->maxmtu - n->minmtu);
138 memset(packet.data, 0, 14);
139 randomize(packet.data + 14, len - 14);
141 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
143 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s", len, n->name);
145 send_udppacket(mesh, n, &packet);
148 n->status.broadcast = false;
151 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timespec) {
152 timeout, prng(mesh, TIMER_FUDGE)
156 void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
157 timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timespec) {
160 send_mtu_probe_handler(&mesh->loop, n);
163 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
165 logger(mesh, MESHLINK_WARNING, "Got too short MTU probe length %d from %s", packet->len, n->name);
169 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s", packet->len, n->name);
171 if(!packet->data[0]) {
172 /* It's a probe request, send back a reply */
176 /* Temporarily set udp_confirmed, so that the reply is sent
177 back exactly the way it came in. */
179 bool udp_confirmed = n->status.udp_confirmed;
180 n->status.udp_confirmed = true;
181 send_udppacket(mesh, n, packet);
182 n->status.udp_confirmed = udp_confirmed;
184 /* It's a valid reply: now we know bidirectional communication
185 is possible using the address and socket that the reply
188 if(!n->status.udp_confirmed) {
189 char *address, *port;
190 sockaddr2str(&n->address, &address, &port);
191 send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, n->name, n->name, address, port);
194 n->status.udp_confirmed = true;
197 /* If we haven't established the PMTU yet, restart the discovery process. */
199 if(n->mtuprobes > 30) {
200 if(len == n->maxmtu + 8) {
201 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
214 /* If applicable, raise the minimum supported MTU */
216 if(len > n->maxmtu) {
220 if(n->minmtu < len) {
222 update_node_pmtu(mesh, n);
229 #if defined(HAVE_RECVMMSG) || defined(HAVE_SENDMMSG)
236 struct mmsghdr hdrs[MAX_MMSG];
237 struct iovec iovs[MAX_MMSG];
238 sockaddr_t addrs[MAX_MMSG];
239 vpn_packet_t pkts[MAX_MMSG];
242 static void init_mmsg_array(struct mmsgs *mmsgs) {
246 for(int i = 0; i < MAX_MMSG; i++) {
247 mmsgs->hdrs[i].msg_hdr.msg_name = &mmsgs->addrs[i];
248 mmsgs->hdrs[i].msg_hdr.msg_namelen = sizeof(mmsgs->addrs[i]);
249 mmsgs->hdrs[i].msg_hdr.msg_iov = &mmsgs->iovs[i];
250 mmsgs->hdrs[i].msg_hdr.msg_iovlen = 1;
251 mmsgs->iovs[i].iov_base = mmsgs->pkts[i].data;
252 mmsgs->iovs[i].iov_len = MAXSIZE;
256 void init_mmsg(meshlink_handle_t *mesh) {
257 mesh->in_mmsgs = xzalloc(sizeof(*mesh->in_mmsgs));
258 mesh->out_mmsgs = xzalloc(sizeof(*mesh->out_mmsgs));
260 init_mmsg_array(mesh->in_mmsgs);
261 init_mmsg_array(mesh->out_mmsgs);
264 void exit_mmsg(meshlink_handle_t *mesh) {
265 free(mesh->out_mmsgs);
266 free(mesh->in_mmsgs);
268 mesh->out_mmsgs = NULL;
269 mesh->in_mmsgs = NULL;
274 void flush_mmsg(meshlink_handle_t *mesh) {
275 struct mmsgs *mmsgs = mesh->out_mmsgs;
277 int todo = mmsgs->count - mmsgs->offset;
278 int offset = mmsgs->offset;
281 int result = sendmmsg(mmsgs->fd, mmsgs->hdrs + offset, todo, 0);
284 logger(mesh, MESHLINK_WARNING, "Error sending packet: %s", sockstrerror(errno));
296 static vpn_packet_t *get_next_mmsg_pkt(meshlink_handle_t *mesh) {
297 struct mmsgs *mmsgs = mesh->out_mmsgs;
299 if(mmsgs->count >= MAX_MMSG) {
303 return &mmsgs->pkts[mmsgs->count];
306 static void add_mmsg(meshlink_handle_t *mesh, int fd, const void *data, size_t len, const struct sockaddr *sa, socklen_t salen) {
307 struct mmsgs *mmsgs = mesh->out_mmsgs;
308 assert(mmsgs->count < MAX_MMSG);
309 assert(data == get_next_mmsg_pkt(mesh)->data);
311 if(mmsgs->fd != fd) {
312 // Flush all packets from the previous fd
313 int oldcount = mmsgs->count;
316 // Adjust offset and count to start the next flush with this packet
318 mmsgs->count = oldcount;
319 mmsgs->offset = oldcount;
322 assert(mmsgs->iovs[mmsgs->count].iov_base == mmsgs->pkts[mmsgs->count].data);
323 assert(mmsgs->hdrs[mmsgs->count].msg_hdr.msg_iovlen == 1);
324 mmsgs->iovs[mmsgs->count].iov_len = len;
325 memcpy(mmsgs->hdrs[mmsgs->count].msg_hdr.msg_name, sa, salen);
326 mmsgs->hdrs[mmsgs->count].msg_hdr.msg_namelen = salen;
331 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
332 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
334 if(n->status.blacklisted) {
335 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
338 n->in_bytes += packet->len;
340 route(mesh, n, packet);
344 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
346 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
349 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
350 if(!n->sptps.state) {
351 if(!n->status.waitingforkey) {
352 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
353 send_req_key(mesh, n);
355 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
361 if(!sptps_receive_data(&n->sptps, inpkt->data, inpkt->len)) {
362 logger(mesh, MESHLINK_ERROR, "Could not process SPTPS data from %s: %s", n->name, strerror(errno));
366 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
367 if(!n->status.validkey) {
368 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
370 if(!n->status.waitingforkey) {
371 send_req_key(mesh, n);
372 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
373 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
374 sptps_stop(&n->sptps);
375 n->status.waitingforkey = false;
376 send_req_key(mesh, n);
385 sptps_set_send_buffer(&n->sptps, get_next_mmsg_pkt(mesh)->data, MAXSIZE);
388 // If it's a probe, send it immediately without trying to compress it.
390 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
394 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
398 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
403 /* If the UDP address is confirmed, use it. */
404 if(n->status.udp_confirmed) {
408 /* Send every third packet to n->address; that could be set
409 to the node's reflexive UDP address discovered during key
412 if(++mesh->udp_choice >= 3) {
413 mesh->udp_choice = 0;
417 /* If we have learned an address via Catta, try this once every batch */
418 if(mesh->udp_choice == 1 && n->catta_address.sa.sa_family != AF_UNSPEC) {
419 *sa = &n->catta_address;
423 /* Otherwise, address are found in edges to this node.
424 So we pick a random edge and a random socket. */
427 int j = prng(mesh, n->edge_tree->count);
428 edge_t *candidate = NULL;
430 for splay_each(edge_t, e, n->edge_tree) {
432 candidate = e->reverse;
438 *sa = &candidate->address;
439 *sock = prng(mesh, mesh->listen_sockets);
444 /* Make sure we have a suitable socket for the chosen address */
445 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
446 for(int i = 0; i < mesh->listen_sockets; i++) {
447 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
455 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
456 *sock = prng(mesh, mesh->listen_sockets);
457 sockaddr_t *broadcast_sa = &mesh->listen_socket[*sock].broadcast_sa;
459 if(broadcast_sa->sa.sa_family == AF_INET6) {
460 broadcast_sa->in6.sin6_port = n->prevedge->address.in.sin_port;
462 broadcast_sa->in.sin_port = n->prevedge->address.in.sin_port;
468 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
469 if(!n->status.reachable) {
470 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
474 send_sptps_packet(mesh, n, origpkt);
477 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
483 meshlink_handle_t *mesh = to->mesh;
485 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
487 if(type >= SPTPS_HANDSHAKE || (type != PKT_PROBE && (len - 21) > to->minmtu)) {
488 char buf[len * 4 / 3 + 5];
489 b64encode(data, buf, len);
491 /* If no valid key is known yet, send the packets using ANS_KEY requests,
492 to ensure we get to learn the reflexive UDP address. */
493 if(!to->status.validkey) {
494 return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, 0);
496 return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
500 /* Otherwise, send the packet via UDP */
502 const sockaddr_t *sa;
505 if(to->status.broadcast) {
506 choose_broadcast_address(mesh, to, &sa, &sock);
508 choose_udp_address(mesh, to, &sa, &sock);
513 if(type != PKT_PROBE) {
514 add_mmsg(mesh, mesh->listen_socket[sock].udp.fd, data, len, &sa->sa, SALEN(sa->sa));
520 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
521 if(sockmsgsize(sockerrno)) {
522 if(to->maxmtu >= len) {
523 to->maxmtu = len - 1;
530 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
538 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
540 assert(!data || len);
542 node_t *from = handle;
543 meshlink_handle_t *mesh = from->mesh;
545 if(type == SPTPS_HANDSHAKE) {
546 if(!from->status.validkey) {
547 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s successful", from->name);
548 from->status.validkey = true;
549 from->status.waitingforkey = false;
552 utcp_reset_timers(from->utcp);
560 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
566 if(type == PKT_PROBE) {
569 memcpy(inpkt.data, data, len);
570 mtu_probe_h(mesh, from, &inpkt, len);
576 if(type & ~(PKT_COMPRESSED)) {
577 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
581 if(type & PKT_COMPRESSED) {
582 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
586 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
589 receive_packet(mesh, from, &inpkt);
594 send a packet to the given vpn ip.
596 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
597 if(n == mesh->self) {
599 n->out_bytes += packet->len;
600 // TODO: send to application
604 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
606 if(!n->status.reachable) {
607 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
612 n->out_bytes += packet->len;
613 n->status.want_udp = true;
615 send_sptps_packet(mesh, n, packet);
619 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
623 for splay_each(edge_t, e, mesh->edges) {
624 if(!e->to->status.reachable || e->to == mesh->self) {
628 if(sockaddrcmp_noport(from, &e->address)) {
629 if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
636 if(!try_mac(mesh, e->to, pkt)) {
645 mesh->last_hard_try = mesh->loop.now.tv_sec;
651 static void handle_one_incoming(meshlink_handle_t *mesh, listen_socket_t *ls, vpn_packet_t *pkt, sockaddr_t *from) {
652 sockaddrunmap(from); /* Some braindead IPv6 implementations do stupid things. */
654 node_t *n = lookup_node_udp(mesh, from);
657 n = try_harder(mesh, from, pkt);
660 update_node_udp(mesh, n, from);
661 } else if(mesh->log_level <= MESHLINK_WARNING) {
662 char *hostname = sockaddr2hostname(from);
663 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
671 if(n->status.blacklisted) {
672 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
676 n->sock = ls - mesh->listen_socket;
678 receive_udppacket(mesh, n, pkt);
681 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
683 meshlink_handle_t *mesh = loop->data;
684 listen_socket_t *ls = data;
687 struct mmsgs *mmsgs = mesh->in_mmsgs;
688 int count = recvmmsg(ls->udp.fd, mmsgs->hdrs, MAX_MMSG, 0, NULL);
690 if(count <= 0 || count > MAX_MMSG) {
691 if(!sockwouldblock(sockerrno)) {
692 logger(mesh, MESHLINK_ERROR, "Receiving packets failed: %s", sockstrerror(sockerrno));
698 for(int i = 0; i < count; i++) {
699 mmsgs->pkts[i].len = mmsgs->hdrs[i].msg_len;
700 handle_one_incoming(mesh, ls, &mmsgs->pkts[i], &mmsgs->addrs[i]);
701 mmsgs->hdrs[i].msg_hdr.msg_namelen = sizeof(mmsgs->addrs[i]);
707 socklen_t fromlen = sizeof(from);
708 memset(&from, 0, sizeof(from));
710 ssize_t len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
712 if(len <= 0 || len > MAXSIZE) {
713 if(!sockwouldblock(sockerrno)) {
714 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
721 handle_one_incoming(mesh, ls, &pkt, &from);