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;
99 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, 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", len, n->name);
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", packet->len, n->name);
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 detected, restarting PMTU discovery", n->name);
189 /* If applicable, raise the minimum supported MTU */
200 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
201 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
203 if(n->status.blacklisted)
204 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
207 n->in_bytes += packet->len;
209 route(mesh, n, packet);
213 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
215 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
218 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
219 if(!n->sptps.state) {
220 if(!n->status.waitingforkey) {
221 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
222 send_req_key(mesh, n);
224 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
227 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
230 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
231 if(!n->status.validkey) {
232 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
233 if(!n->status.waitingforkey)
234 send_req_key(mesh, n);
235 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
236 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
237 sptps_stop(&n->sptps);
238 n->status.waitingforkey = false;
239 send_req_key(mesh, n);
246 // If it's a probe, send it immediately without trying to compress it.
248 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
252 if(n->outcompression) {
253 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s", n->name);
257 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
261 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
266 /* If the UDP address is confirmed, use it. */
267 if(n->status.udp_confirmed)
270 /* Send every third packet to n->address; that could be set
271 to the node's reflexive UDP address discovered during key
280 /* Otherwise, address are found in edges to this node.
281 So we pick a random edge and a random socket. */
284 int j = rand() % n->edge_tree->count;
285 edge_t *candidate = NULL;
287 for splay_each(edge_t, e, n->edge_tree) {
289 candidate = e->reverse;
295 *sa = &candidate->address;
296 *sock = rand() % mesh->listen_sockets;
299 /* Make sure we have a suitable socket for the chosen address */
300 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
301 for(int i = 0; i < mesh->listen_sockets; i++) {
302 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
310 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
311 static sockaddr_t broadcast_ipv4 = {
313 .sin_family = AF_INET,
314 .sin_addr.s_addr = -1,
318 static sockaddr_t broadcast_ipv6 = {
320 .sin6_family = AF_INET6,
321 .sin6_addr.s6_addr[0x0] = 0xff,
322 .sin6_addr.s6_addr[0x1] = 0x02,
323 .sin6_addr.s6_addr[0xf] = 0x01,
327 *sock = rand() % mesh->listen_sockets;
329 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
330 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
331 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
332 *sa = &mesh->localdiscovery_address;
334 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
335 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
336 *sa = &broadcast_ipv6;
339 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
340 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
341 *sa = &mesh->localdiscovery_address;
343 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
344 *sa = &broadcast_ipv4;
349 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
350 if(!n->status.reachable) {
351 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
355 return send_sptps_packet(mesh, n, origpkt);
358 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
360 meshlink_handle_t *mesh = to->mesh;
362 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
364 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
365 char buf[len * 4 / 3 + 5];
366 b64encode(data, buf, len);
367 /* If no valid key is known yet, send the packets using ANS_KEY requests,
368 to ensure we get to learn the reflexive UDP address. */
369 if(!to->status.validkey) {
370 to->incompression = mesh->self->incompression;
371 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);
373 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
376 /* Otherwise, send the packet via UDP */
378 const sockaddr_t *sa;
381 if(to->status.broadcast)
382 choose_broadcast_address(mesh, to, &sa, &sock);
384 choose_udp_address(mesh, to, &sa, &sock);
386 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
387 if(sockmsgsize(sockerrno)) {
388 if(to->maxmtu >= len)
389 to->maxmtu = len - 1;
393 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
401 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
402 node_t *from = handle;
403 meshlink_handle_t *mesh = from->mesh;
405 if(type == SPTPS_HANDSHAKE) {
406 if(!from->status.validkey) {
407 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s succesful", from->name);
408 from->status.validkey = true;
409 from->status.waitingforkey = false;
411 utcp_reset_timers(from->utcp);
417 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MTU);
423 if(type == PKT_PROBE) {
426 memcpy(inpkt.data, data, len);
427 mtu_probe_h(mesh, from, &inpkt, len);
432 if(type & ~(PKT_COMPRESSED)) {
433 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
437 if(type & PKT_COMPRESSED) {
438 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
442 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
445 receive_packet(mesh, from, &inpkt);
450 send a packet to the given vpn ip.
452 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
453 if(n == mesh->self) {
455 n->out_bytes += packet->len;
456 // TODO: send to application
460 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
462 if(!n->status.reachable) {
463 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
468 n->out_bytes += packet->len;
470 send_sptps_packet(mesh, n, packet);
474 /* Broadcast a packet using the minimum spanning tree */
476 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
477 // Always give ourself a copy of the packet.
478 if(from != mesh->self)
479 send_packet(mesh, mesh->self, packet);
481 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s", packet->len, from->name);
483 for list_each(connection_t, c, mesh->connections)
484 if(c->status.active && c->status.mst && c != from->nexthop->connection)
485 send_packet(mesh, c->node, packet);
488 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
491 static time_t last_hard_try = 0;
493 for splay_each(edge_t, e, mesh->edges) {
494 if(!e->to->status.reachable || e->to == mesh->self)
497 if(sockaddrcmp_noport(from, &e->address)) {
498 if(last_hard_try == mesh->loop.now.tv_sec)
503 if(!try_mac(mesh, e->to, pkt))
511 last_hard_try = mesh->loop.now.tv_sec;
513 last_hard_try = mesh->loop.now.tv_sec;
517 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
519 meshlink_handle_t *mesh = loop->data;
520 listen_socket_t *ls = data;
523 sockaddr_t from = {};
524 socklen_t fromlen = sizeof(from);
528 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
530 if(len <= 0 || len > MAXSIZE) {
531 if(!sockwouldblock(sockerrno))
532 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
538 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
540 n = lookup_node_udp(mesh, &from);
543 n = try_harder(mesh, &from, &pkt);
545 update_node_udp(mesh, n, &from);
546 else if(mesh->log_level >= MESHLINK_WARNING) {
547 hostname = sockaddr2hostname(&from);
548 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
555 if(n->status.blacklisted) {
556 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
559 n->sock = ls - mesh->listen_socket;
561 receive_udppacket(mesh, n, &pkt);