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.
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", n->name);
74 if(n->mtuprobes > 32) {
77 timeout = mesh->pinginterval;
81 logger(mesh, MESHLINK_INFO, "%s did not respond to UDP ping, restarting PMTU discovery", n->name);
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", n->name);
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;
101 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, n->mtu, n->mtuprobes);
105 if(n->mtuprobes == 31) {
106 timeout = mesh->pinginterval;
108 } else if(n->mtuprobes == 32) {
109 timeout = mesh->pingtimeout;
112 for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
116 if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) {
121 } else if(n->maxmtu <= n->minmtu) {
124 len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
133 memset(packet.data, 0, 14);
134 randomize(packet.data + 14, len - 14);
136 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
138 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s", len, n->name);
140 send_udppacket(mesh, n, &packet);
143 n->status.broadcast = false;
146 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval) {
147 timeout, rand() % 100000
151 void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
152 timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval) {
155 send_mtu_probe_handler(&mesh->loop, n);
158 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
159 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s", packet->len, n->name);
161 if(!packet->data[0]) {
162 /* It's a probe request, send back a reply */
166 /* Temporarily set udp_confirmed, so that the reply is sent
167 back exactly the way it came in. */
169 bool udp_confirmed = n->status.udp_confirmed;
170 n->status.udp_confirmed = true;
171 send_udppacket(mesh, n, packet);
172 n->status.udp_confirmed = udp_confirmed;
174 /* It's a valid reply: now we know bidirectional communication
175 is possible using the address and socket that the reply
178 n->status.udp_confirmed = true;
180 /* If we haven't established the PMTU yet, restart the discovery process. */
182 if(n->mtuprobes > 30) {
183 if(len == n->maxmtu + 8) {
184 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
197 /* If applicable, raise the minimum supported MTU */
199 if(len > n->maxmtu) {
203 if(n->minmtu < len) {
211 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
212 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
214 if(n->status.blacklisted) {
215 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
218 n->in_bytes += packet->len;
220 route(mesh, n, packet);
224 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
226 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
229 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
230 if(!n->sptps.state) {
231 if(!n->status.waitingforkey) {
232 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
233 send_req_key(mesh, n);
235 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
241 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
244 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
245 if(!n->status.validkey) {
246 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
248 if(!n->status.waitingforkey) {
249 send_req_key(mesh, n);
250 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
251 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
252 sptps_stop(&n->sptps);
253 n->status.waitingforkey = false;
254 send_req_key(mesh, n);
262 // If it's a probe, send it immediately without trying to compress it.
264 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
268 if(n->outcompression) {
269 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s", n->name);
273 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
277 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
282 /* If the UDP address is confirmed, use it. */
283 if(n->status.udp_confirmed) {
287 /* Send every third packet to n->address; that could be set
288 to the node's reflexive UDP address discovered during key
298 /* Otherwise, address are found in edges to this node.
299 So we pick a random edge and a random socket. */
302 int j = rand() % n->edge_tree->count;
303 edge_t *candidate = NULL;
305 for splay_each(edge_t, e, n->edge_tree) {
307 candidate = e->reverse;
313 *sa = &candidate->address;
314 *sock = rand() % mesh->listen_sockets;
317 /* Make sure we have a suitable socket for the chosen address */
318 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
319 for(int i = 0; i < mesh->listen_sockets; i++) {
320 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
328 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
329 static sockaddr_t broadcast_ipv4 = {
331 .sin_family = AF_INET,
332 .sin_addr.s_addr = -1,
336 static sockaddr_t broadcast_ipv6 = {
338 .sin6_family = AF_INET6,
339 .sin6_addr.s6_addr[0x0] = 0xff,
340 .sin6_addr.s6_addr[0x1] = 0x02,
341 .sin6_addr.s6_addr[0xf] = 0x01,
345 *sock = rand() % mesh->listen_sockets;
347 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
348 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
349 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
350 *sa = &mesh->localdiscovery_address;
352 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
353 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
354 *sa = &broadcast_ipv6;
357 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
358 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
359 *sa = &mesh->localdiscovery_address;
361 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
362 *sa = &broadcast_ipv4;
367 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
368 if(!n->status.reachable) {
369 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
373 send_sptps_packet(mesh, n, origpkt);
376 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
378 meshlink_handle_t *mesh = to->mesh;
380 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
382 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
383 char buf[len * 4 / 3 + 5];
384 b64encode(data, buf, len);
386 /* If no valid key is known yet, send the packets using ANS_KEY requests,
387 to ensure we get to learn the reflexive UDP address. */
388 if(!to->status.validkey) {
389 to->incompression = mesh->self->incompression;
390 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);
392 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
396 /* Otherwise, send the packet via UDP */
398 const sockaddr_t *sa;
401 if(to->status.broadcast) {
402 choose_broadcast_address(mesh, to, &sa, &sock);
404 choose_udp_address(mesh, to, &sa, &sock);
407 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
408 if(sockmsgsize(sockerrno)) {
409 if(to->maxmtu >= len) {
410 to->maxmtu = len - 1;
417 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
425 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
426 node_t *from = handle;
427 meshlink_handle_t *mesh = from->mesh;
429 if(type == SPTPS_HANDSHAKE) {
430 if(!from->status.validkey) {
431 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s succesful", from->name);
432 from->status.validkey = true;
433 from->status.waitingforkey = false;
436 utcp_reset_timers(from->utcp);
444 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MTU);
450 if(type == PKT_PROBE) {
453 memcpy(inpkt.data, data, len);
454 mtu_probe_h(mesh, from, &inpkt, len);
460 if(type & ~(PKT_COMPRESSED)) {
461 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
465 if(type & PKT_COMPRESSED) {
466 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
470 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
473 receive_packet(mesh, from, &inpkt);
478 send a packet to the given vpn ip.
480 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
481 if(n == mesh->self) {
483 n->out_bytes += packet->len;
484 // TODO: send to application
488 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
490 if(!n->status.reachable) {
491 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
496 n->out_bytes += packet->len;
498 send_sptps_packet(mesh, n, packet);
502 /* Broadcast a packet using the minimum spanning tree */
504 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
505 // Always give ourself a copy of the packet.
506 if(from != mesh->self) {
507 send_packet(mesh, mesh->self, packet);
510 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s", packet->len, from->name);
512 for list_each(connection_t, c, mesh->connections)
513 if(c->status.active && c->status.mst && c != from->nexthop->connection) {
514 send_packet(mesh, c->node, packet);
518 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
521 static time_t last_hard_try = 0;
523 for splay_each(edge_t, e, mesh->edges) {
524 if(!e->to->status.reachable || e->to == mesh->self) {
528 if(sockaddrcmp_noport(from, &e->address)) {
529 if(last_hard_try == mesh->loop.now.tv_sec) {
536 if(!try_mac(mesh, e->to, pkt)) {
545 last_hard_try = mesh->loop.now.tv_sec;
548 last_hard_try = mesh->loop.now.tv_sec;
552 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
554 meshlink_handle_t *mesh = loop->data;
555 listen_socket_t *ls = data;
558 sockaddr_t from = {0};
559 socklen_t fromlen = sizeof(from);
563 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
565 if(len <= 0 || len > MAXSIZE) {
566 if(!sockwouldblock(sockerrno)) {
567 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
575 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
577 n = lookup_node_udp(mesh, &from);
580 n = try_harder(mesh, &from, &pkt);
583 update_node_udp(mesh, n, &from);
584 } else if(mesh->log_level >= MESHLINK_WARNING) {
585 hostname = sockaddr2hostname(&from);
586 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
594 if(n->status.blacklisted) {
595 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
599 n->sock = ls - mesh->listen_socket;
601 receive_udppacket(mesh, n, &pkt);