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"
36 static void send_udppacket(meshlink_handle_t *mesh, node_t *, vpn_packet_t *);
38 #define MAX_SEQNO 1073741824
40 /* mtuprobes == 1..30: initial discovery, send bursts with 1 second interval
41 mtuprobes == 31: sleep pinginterval seconds
42 mtuprobes == 32: send 1 burst, sleep pingtimeout second
43 mtuprobes == 33: no response from other side, restart PMTU discovery process
45 Probes are sent in batches of at least three, with random sizes between the
46 lower and upper boundaries for the MTU thus far discovered.
48 After the initial discovery, a fourth packet is added to each batch with a
49 size larger than the currently known PMTU, to test if the PMTU has increased.
51 In case local discovery is enabled, another packet is added to each batch,
52 which will be broadcast to the local network.
56 static void send_mtu_probe_handler(event_loop_t *loop, void *data) {
57 meshlink_handle_t *mesh = loop->data;
63 if(!n->status.reachable || !n->status.validkey) {
64 logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s", n->name);
69 if(n->mtuprobes > 32) {
72 timeout = mesh->pinginterval;
76 logger(mesh, MESHLINK_INFO, "%s did not respond to UDP ping, restarting PMTU discovery", n->name);
77 n->status.udp_confirmed = false;
83 if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
84 logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s", n->name);
88 if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
89 if(n->minmtu > n->maxmtu) {
90 n->minmtu = n->maxmtu;
92 n->maxmtu = n->minmtu;
96 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, n->mtu, n->mtuprobes);
100 if(n->mtuprobes == 31) {
101 timeout = mesh->pinginterval;
103 } else if(n->mtuprobes == 32) {
104 timeout = mesh->pingtimeout;
107 for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
111 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);
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", len, n->name);
135 send_udppacket(mesh, n, &packet);
138 n->status.broadcast = false;
141 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval) {
142 timeout, rand() % 100000
146 void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
147 timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval) {
150 send_mtu_probe_handler(&mesh->loop, n);
153 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
154 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s", packet->len, n->name);
156 if(!packet->data[0]) {
157 /* It's a probe request, send back a reply */
161 /* Temporarily set udp_confirmed, so that the reply is sent
162 back exactly the way it came in. */
164 bool udp_confirmed = n->status.udp_confirmed;
165 n->status.udp_confirmed = true;
166 send_udppacket(mesh, n, packet);
167 n->status.udp_confirmed = udp_confirmed;
169 /* It's a valid reply: now we know bidirectional communication
170 is possible using the address and socket that the reply
173 n->status.udp_confirmed = true;
175 /* If we haven't established the PMTU yet, restart the discovery process. */
177 if(n->mtuprobes > 30) {
178 if(len == n->maxmtu + 8) {
179 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
192 /* If applicable, raise the minimum supported MTU */
194 if(len > n->maxmtu) {
198 if(n->minmtu < len) {
206 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, const void *data, uint16_t len) {
207 if(!n->sptps.state) {
208 if(!n->status.waitingforkey) {
209 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
210 send_req_key(mesh, n);
212 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
218 sptps_receive_data(&n->sptps, data, len);
221 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
222 if(!n->status.validkey) {
223 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
225 if(!n->status.waitingforkey) {
226 send_req_key(mesh, n);
227 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
228 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
229 sptps_stop(&n->sptps);
230 n->status.waitingforkey = false;
231 send_req_key(mesh, n);
239 // If it's a probe, send it immediately without trying to compress it.
241 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
245 if(n->outcompression) {
246 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s", n->name);
250 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
254 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
259 /* If the UDP address is confirmed, use it. */
260 if(n->status.udp_confirmed) {
264 /* Send every third packet to n->address; that could be set
265 to the node's reflexive UDP address discovered during key
275 /* Otherwise, address are found in edges to this node.
276 So we pick a random edge and a random socket. */
279 int j = rand() % n->edge_tree->count;
280 edge_t *candidate = NULL;
282 for splay_each(edge_t, e, n->edge_tree) {
284 candidate = e->reverse;
290 *sa = &candidate->address;
291 *sock = rand() % mesh->listen_sockets;
294 /* Make sure we have a suitable socket for the chosen address */
295 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
296 for(int i = 0; i < mesh->listen_sockets; i++) {
297 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
305 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
306 static sockaddr_t broadcast_ipv4 = {
308 .sin_family = AF_INET,
309 .sin_addr.s_addr = -1,
313 static sockaddr_t broadcast_ipv6 = {
315 .sin6_family = AF_INET6,
316 .sin6_addr.s6_addr[0x0] = 0xff,
317 .sin6_addr.s6_addr[0x1] = 0x02,
318 .sin6_addr.s6_addr[0xf] = 0x01,
322 *sock = rand() % mesh->listen_sockets;
324 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
325 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
326 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
327 *sa = &mesh->localdiscovery_address;
329 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
330 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
331 *sa = &broadcast_ipv6;
334 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
335 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
336 *sa = &mesh->localdiscovery_address;
338 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
339 *sa = &broadcast_ipv4;
344 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
345 if(!n->status.reachable) {
346 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
350 send_sptps_packet(mesh, n, origpkt);
353 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
355 meshlink_handle_t *mesh = to->mesh;
357 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
359 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
360 char buf[len * 4 / 3 + 5];
361 b64encode(data, buf, len);
363 /* If no valid key is known yet, send the packets using ANS_KEY requests,
364 to ensure we get to learn the reflexive UDP address. */
365 if(!to->status.validkey) {
366 to->incompression = mesh->self->incompression;
367 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);
369 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
373 /* Otherwise, send the packet via UDP */
375 const sockaddr_t *sa;
378 if(to->status.broadcast) {
379 choose_broadcast_address(mesh, to, &sa, &sock);
381 choose_udp_address(mesh, to, &sa, &sock);
384 /* Add the source and destination IDs */
387 pkt.src = mesh->self->id;
389 memcpy(pkt.data, data, len);
391 if(sendto(mesh->listen_socket[sock].udp.fd, &pkt.src, len + 16, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
392 if(sockmsgsize(sockerrno)) {
393 if(to->maxmtu >= len) {
394 to->maxmtu = len - 1;
401 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
409 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
410 node_t *from = handle;
411 meshlink_handle_t *mesh = from->mesh;
413 assert(!from->status.blacklisted);
415 if(type == SPTPS_HANDSHAKE) {
416 if(!from->status.validkey) {
417 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s succesful", from->name);
418 from->status.validkey = true;
419 from->status.waitingforkey = false;
422 utcp_reset_timers(from->utcp);
430 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MTU);
434 if(type == SPTPS_UNENCRYPTED) {
435 /* This is a packet that needs to be forwarded */
441 if(len < sizeof(hdr)) {
442 logger(mesh, MESHLINK_ERROR, "Too short packet from %s", from->name);
446 memcpy(&hdr, data, sizeof(hdr));
448 if(hdr.src == mesh->self->id) {
449 logger(mesh, MESHLINK_WARNING, "Dropping packet from ourself");
453 node_t *orig = lookup_node_id(mesh, hdr.src);
456 logger(mesh, MESHLINK_ERROR, "Received packet from %s with unknown source", from->name);
460 if(orig->status.blacklisted) {
461 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", orig->name);
465 if(hdr.dst == mesh->self->id) {
466 receive_udppacket(mesh, orig, data, len);
473 if(type == PKT_PROBE) {
477 memcpy(inpkt.data, data, len);
478 mtu_probe_h(mesh, from, &inpkt, len);
482 if(type & ~(PKT_COMPRESSED)) {
483 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
487 if(type & PKT_COMPRESSED) {
488 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
492 if(mesh->receive_cb) {
493 mesh->receive_cb(mesh, (meshlink_node_t *)from, data, len);
500 send a packet to the given vpn ip.
502 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
503 if(n == mesh->self) {
505 n->out_bytes += packet->len;
506 // TODO: send to application
510 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
512 if(!n->status.reachable) {
513 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
518 n->out_bytes += packet->len;
520 send_sptps_packet(mesh, n, packet);
524 /* Broadcast a packet using the minimum spanning tree */
526 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
527 // Always give ourself a copy of the packet.
528 if(from != mesh->self) {
529 send_packet(mesh, mesh->self, packet);
532 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s", packet->len, from->name);
534 for list_each(connection_t, c, mesh->connections)
535 if(c->status.active && c->status.mst && c != from->nexthop->connection) {
536 send_packet(mesh, c->node, packet);
540 void forward_udppacket(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *pkt) {
541 node_t *to = lookup_node_id(mesh, pkt->dst);
544 logger(mesh, MESHLINK_WARNING, "Received UDP packet from %s with unknown destination", from->name);
548 if(pkt->len > to->minmtu) {
553 const sockaddr_t *sa;
556 choose_udp_address(mesh, to, &sa, &sock);
558 if(sendto(mesh->listen_socket[sock].udp.fd, &pkt->src, pkt->len + 16, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
559 if(sockmsgsize(sockerrno)) {
560 if(to->maxmtu >= pkt->len) {
561 to->maxmtu = pkt->len - 1;
564 if(to->mtu >= pkt->len) {
565 to->mtu = pkt->len - 1;
568 logger(mesh, MESHLINK_WARNING, "Error forwarding UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
573 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
575 meshlink_handle_t *mesh = loop->data;
576 listen_socket_t *ls = data;
579 sockaddr_t from = {0};
580 socklen_t fromlen = sizeof(from);
584 len = recvfrom(ls->udp.fd, &pkt.src, 16 + MAXSIZE, 0, &from.sa, &fromlen);
586 if(len <= 16 || len > MAXSIZE + 16) {
587 if(!sockwouldblock(sockerrno)) {
588 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
594 if(!pkt.src || !pkt.dst) {
595 logger(mesh, MESHLINK_WARNING, "Unhandled NULL ids in packet header");
601 n = lookup_node_id(mesh, pkt.src);
604 hostname = sockaddr2hostname(&from);
605 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
610 if(n->status.blacklisted) {
611 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
615 if(n == mesh->self) {
616 logger(mesh, MESHLINK_WARNING, "Dropping packet from ourself");
620 n->sock = ls - mesh->listen_socket;
622 if(sockaddrcmp_noport(&n->address, &from)) {
623 update_node_udp(mesh, n, &from);
626 if(pkt.dst != mesh->self->id) {
627 forward_udppacket(mesh, n, &pkt);
629 receive_udppacket(mesh, n, pkt.data, pkt.len);