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 && n->nexthop && n->nexthop->connection) {
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);
192 if(n->nexthop && n->nexthop->connection) {
193 send_request(mesh, n->nexthop->connection, NULL, "%d %s %s . -1 -1 -1 0 %s %s", ANS_KEY, n->name, n->name, address, port);
195 logger(mesh, MESHLINK_WARNING, "Cannot send reflexive address to %s via %s", n->name, n->nexthop ? n->nexthop->name : n->name);
200 n->status.udp_confirmed = true;
203 /* If we haven't established the PMTU yet, restart the discovery process. */
205 if(n->mtuprobes > 30) {
206 if(len == n->maxmtu + 8) {
207 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
220 /* If applicable, raise the minimum supported MTU */
222 if(len > n->maxmtu) {
226 if(n->minmtu < len) {
228 update_node_pmtu(mesh, n);
235 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
236 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
238 if(n->status.blacklisted) {
239 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
242 n->in_bytes += packet->len;
244 route(mesh, n, packet);
248 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
250 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
253 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
254 if(!n->status.reachable) {
255 logger(mesh, MESHLINK_ERROR, "Got SPTPS data from unreachable node %s", n->name);
259 if(!n->sptps.state) {
260 if(!n->status.waitingforkey) {
261 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
262 send_req_key(mesh, n);
264 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
270 if(!sptps_receive_data(&n->sptps, inpkt->data, inpkt->len)) {
271 logger(mesh, MESHLINK_ERROR, "Could not process SPTPS data from %s: %s", n->name, strerror(errno));
275 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
276 if(!n->status.reachable) {
277 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", n->name);
281 if(!n->status.validkey) {
282 if(n->connection && (n->connection->flags & PROTOCOL_TINY) & n->connection->status.active) {
283 send_raw_packet(mesh, n->connection, origpkt);
287 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
289 if(!n->status.waitingforkey) {
290 send_req_key(mesh, n);
291 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
292 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
293 sptps_stop(&n->sptps);
294 n->status.waitingforkey = false;
295 send_req_key(mesh, n);
303 // If it's a probe, send it immediately without trying to compress it.
305 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
309 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
313 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock, sockaddr_t *sa_buf) {
318 /* If the UDP address is confirmed, use it. */
319 if(n->status.udp_confirmed) {
323 /* Send every third packet to n->address; that could be set
324 to the node's reflexive UDP address discovered during key
327 if(++mesh->udp_choice >= 3) {
328 mesh->udp_choice = 0;
332 /* If we have learned an address via Catta, try this once every batch */
333 if(mesh->udp_choice == 1 && n->catta_address.sa.sa_family != AF_UNSPEC) {
334 *sa = &n->catta_address;
338 /* Else, if we have a canonical address, try this once every batch */
339 if(mesh->udp_choice == 1 && n->canonical_address) {
340 char *host = xstrdup(n->canonical_address);
341 char *port = strchr(host, ' ');
345 *sa_buf = str2sockaddr_random(mesh, host, port);
348 if(sa_buf->sa.sa_family != AF_UNKNOWN) {
357 /* Otherwise, address are found in edges to this node.
358 So we pick a random edge and a random socket. */
360 edge_t *candidate = NULL;
364 int j = prng(mesh, n->edge_tree->count);
366 for splay_each(edge_t, e, n->edge_tree) {
368 candidate = e->reverse;
375 *sa = &candidate->address;
376 *sock = prng(mesh, mesh->listen_sockets);
381 /* Make sure we have a suitable socket for the chosen address */
382 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
383 for(int i = 0; i < mesh->listen_sockets; i++) {
384 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
392 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
393 *sock = prng(mesh, mesh->listen_sockets);
394 sockaddr_t *broadcast_sa = &mesh->listen_socket[*sock].broadcast_sa;
396 if(broadcast_sa->sa.sa_family == AF_INET6) {
397 broadcast_sa->in6.sin6_port = n->prevedge->address.in.sin_port;
399 broadcast_sa->in.sin_port = n->prevedge->address.in.sin_port;
405 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
406 if(!n->status.reachable) {
407 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
411 send_sptps_packet(mesh, n, origpkt);
414 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
420 meshlink_handle_t *mesh = to->mesh;
422 if(!to->status.reachable) {
423 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", to->name);
427 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
429 if(type >= SPTPS_HANDSHAKE || (type != PKT_PROBE && (len - 21) > to->minmtu)) {
430 char buf[len * 4 / 3 + 5];
431 b64encode(data, buf, len);
433 if(!to->nexthop || !to->nexthop->connection) {
434 logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
438 /* If no valid key is known yet, send the packets using ANS_KEY requests,
439 to ensure we get to learn the reflexive UDP address. */
440 if(!to->status.validkey) {
441 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);
443 return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
447 /* Otherwise, send the packet via UDP */
450 const sockaddr_t *sa;
453 if(to->status.broadcast) {
454 choose_broadcast_address(mesh, to, &sa, &sock);
456 choose_udp_address(mesh, to, &sa, &sock, &sa_buf);
459 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
460 if(sockmsgsize(sockerrno)) {
461 if(to->maxmtu >= len) {
462 to->maxmtu = len - 1;
469 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
477 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
479 assert(!data || len);
481 node_t *from = handle;
482 meshlink_handle_t *mesh = from->mesh;
484 if(type == SPTPS_HANDSHAKE) {
485 if(!from->status.validkey) {
486 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s successful", from->name);
487 from->status.validkey = true;
488 from->status.waitingforkey = false;
491 utcp_reset_timers(from->utcp);
499 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
505 if(type == PKT_PROBE) {
508 memcpy(inpkt.data, data, len);
509 mtu_probe_h(mesh, from, &inpkt, len);
515 if(type & ~(PKT_COMPRESSED)) {
516 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
520 if(type & PKT_COMPRESSED) {
521 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
525 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
528 receive_packet(mesh, from, &inpkt);
533 send a packet to the given vpn ip.
535 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
536 if(n == mesh->self) {
538 n->out_bytes += packet->len;
539 // TODO: send to application
543 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
545 if(!n->status.reachable) {
546 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
551 n->out_bytes += packet->len;
552 n->status.want_udp = true;
554 send_sptps_packet(mesh, n, packet);
558 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
562 for splay_each(edge_t, e, mesh->edges) {
563 if(!e->to->status.reachable || e->to == mesh->self) {
567 if(sockaddrcmp_noport(from, &e->address)) {
568 if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
575 if(!try_mac(mesh, e->to, pkt)) {
584 mesh->last_hard_try = mesh->loop.now.tv_sec;
590 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
592 meshlink_handle_t *mesh = loop->data;
593 listen_socket_t *ls = data;
597 socklen_t fromlen = sizeof(from);
601 memset(&from, 0, sizeof(from));
603 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
605 if(len <= 0 || len > MAXSIZE) {
606 if(!sockwouldblock(sockerrno)) {
607 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
615 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
617 n = lookup_node_udp(mesh, &from);
620 n = try_harder(mesh, &from, &pkt);
623 update_node_udp(mesh, n, &from);
624 } else if(mesh->log_level <= MESHLINK_WARNING) {
625 hostname = sockaddr2hostname(&from);
626 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
634 if(n->status.blacklisted) {
635 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
639 n->sock = ls - mesh->listen_socket;
641 receive_udppacket(mesh, n, &pkt);