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->pinginterval;
77 logger(mesh, MESHLINK_INFO, "%s did not respond to UDP ping, restarting PMTU discovery", n->name);
78 n->status.udp_confirmed = false;
84 if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
85 logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s", n->name);
89 if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
90 if(n->minmtu > n->maxmtu) {
91 n->minmtu = n->maxmtu;
93 n->maxmtu = n->minmtu;
97 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s to %d after %d probes", n->name, n->mtu, n->mtuprobes);
101 if(n->mtuprobes == 31) {
102 timeout = mesh->pinginterval;
104 } else if(n->mtuprobes == 32) {
105 timeout = mesh->pingtimeout;
108 for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
112 if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU) {
117 } else if(n->maxmtu <= n->minmtu) {
120 len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
129 memset(packet.data, 0, 14);
130 randomize(packet.data + 14, len - 14);
132 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
134 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s", len, n->name);
136 send_udppacket(mesh, n, &packet);
139 n->status.broadcast = false;
142 timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval) {
143 timeout, rand() % 100000
147 void send_mtu_probe(meshlink_handle_t *mesh, node_t *n) {
148 timeout_add(&mesh->loop, &n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval) {
151 send_mtu_probe_handler(&mesh->loop, n);
154 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
155 logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s", packet->len, n->name);
157 if(!packet->data[0]) {
158 /* It's a probe request, send back a reply */
162 /* Temporarily set udp_confirmed, so that the reply is sent
163 back exactly the way it came in. */
165 bool udp_confirmed = n->status.udp_confirmed;
166 n->status.udp_confirmed = true;
167 send_udppacket(mesh, n, packet);
168 n->status.udp_confirmed = udp_confirmed;
170 /* It's a valid reply: now we know bidirectional communication
171 is possible using the address and socket that the reply
174 n->status.udp_confirmed = true;
176 /* If we haven't established the PMTU yet, restart the discovery process. */
178 if(n->mtuprobes > 30) {
179 if(len == n->maxmtu + 8) {
180 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s detected, restarting PMTU discovery", n->name);
193 /* If applicable, raise the minimum supported MTU */
195 if(len > n->maxmtu) {
199 if(n->minmtu < len) {
207 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
208 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
210 if(n->status.blacklisted) {
211 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
214 n->in_bytes += packet->len;
216 route(mesh, n, packet);
220 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
222 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
225 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
226 if(!n->sptps.state) {
227 if(!n->status.waitingforkey) {
228 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
229 send_req_key(mesh, n);
231 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
237 sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
240 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
241 if(!n->status.validkey) {
242 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
244 if(!n->status.waitingforkey) {
245 send_req_key(mesh, n);
246 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
247 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
248 sptps_stop(&n->sptps);
249 n->status.waitingforkey = false;
250 send_req_key(mesh, n);
258 // If it's a probe, send it immediately without trying to compress it.
260 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
264 if(n->outcompression) {
265 logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s", n->name);
269 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
273 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
278 /* If the UDP address is confirmed, use it. */
279 if(n->status.udp_confirmed) {
283 /* Send every third packet to n->address; that could be set
284 to the node's reflexive UDP address discovered during key
294 /* Otherwise, address are found in edges to this node.
295 So we pick a random edge and a random socket. */
298 int j = rand() % n->edge_tree->count;
299 edge_t *candidate = NULL;
301 for splay_each(edge_t, e, n->edge_tree) {
303 candidate = e->reverse;
309 *sa = &candidate->address;
310 *sock = rand() % mesh->listen_sockets;
313 /* Make sure we have a suitable socket for the chosen address */
314 if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
315 for(int i = 0; i < mesh->listen_sockets; i++) {
316 if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
324 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
325 static sockaddr_t broadcast_ipv4 = {
327 .sin_family = AF_INET,
328 .sin_addr.s_addr = -1,
332 static sockaddr_t broadcast_ipv6 = {
334 .sin6_family = AF_INET6,
335 .sin6_addr.s6_addr[0x0] = 0xff,
336 .sin6_addr.s6_addr[0x1] = 0x02,
337 .sin6_addr.s6_addr[0xf] = 0x01,
341 *sock = rand() % mesh->listen_sockets;
343 if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
344 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
345 mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
346 *sa = &mesh->localdiscovery_address;
348 broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
349 broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
350 *sa = &broadcast_ipv6;
353 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
354 mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
355 *sa = &mesh->localdiscovery_address;
357 broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
358 *sa = &broadcast_ipv4;
363 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
364 if(!n->status.reachable) {
365 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
369 send_sptps_packet(mesh, n, origpkt);
372 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
374 meshlink_handle_t *mesh = to->mesh;
376 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
378 if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
379 char buf[len * 4 / 3 + 5];
380 b64encode(data, buf, len);
382 /* If no valid key is known yet, send the packets using ANS_KEY requests,
383 to ensure we get to learn the reflexive UDP address. */
384 if(!to->status.validkey) {
385 to->incompression = mesh->self->incompression;
386 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);
388 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
392 /* Otherwise, send the packet via UDP */
394 const sockaddr_t *sa;
397 if(to->status.broadcast) {
398 choose_broadcast_address(mesh, to, &sa, &sock);
400 choose_udp_address(mesh, to, &sa, &sock);
403 if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
404 if(sockmsgsize(sockerrno)) {
405 if(to->maxmtu >= len) {
406 to->maxmtu = len - 1;
413 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
421 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
422 node_t *from = handle;
423 meshlink_handle_t *mesh = from->mesh;
425 if(type == SPTPS_HANDSHAKE) {
426 if(!from->status.validkey) {
427 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s succesful", from->name);
428 from->status.validkey = true;
429 from->status.waitingforkey = false;
432 utcp_reset_timers(from->utcp);
440 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MTU);
446 if(type == PKT_PROBE) {
449 memcpy(inpkt.data, data, len);
450 mtu_probe_h(mesh, from, &inpkt, len);
456 if(type & ~(PKT_COMPRESSED)) {
457 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
461 if(type & PKT_COMPRESSED) {
462 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
466 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
469 receive_packet(mesh, from, &inpkt);
474 send a packet to the given vpn ip.
476 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
477 if(n == mesh->self) {
479 n->out_bytes += packet->len;
480 // TODO: send to application
484 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
486 if(!n->status.reachable) {
487 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
492 n->out_bytes += packet->len;
494 send_sptps_packet(mesh, n, packet);
498 /* Broadcast a packet using the minimum spanning tree */
500 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
501 // Always give ourself a copy of the packet.
502 if(from != mesh->self) {
503 send_packet(mesh, mesh->self, packet);
506 logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s", packet->len, from->name);
508 for list_each(connection_t, c, mesh->connections)
509 if(c->status.active && c->status.mst && c != from->nexthop->connection) {
510 send_packet(mesh, c->node, packet);
514 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
517 static time_t last_hard_try = 0;
519 for splay_each(edge_t, e, mesh->edges) {
520 if(!e->to->status.reachable || e->to == mesh->self) {
524 if(sockaddrcmp_noport(from, &e->address)) {
525 if(last_hard_try == mesh->loop.now.tv_sec) {
532 if(!try_mac(mesh, e->to, pkt)) {
541 last_hard_try = mesh->loop.now.tv_sec;
544 last_hard_try = mesh->loop.now.tv_sec;
548 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
550 meshlink_handle_t *mesh = loop->data;
551 listen_socket_t *ls = data;
554 sockaddr_t from = {0};
555 socklen_t fromlen = sizeof(from);
559 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
561 if(len <= 0 || len > MAXSIZE) {
562 if(!sockwouldblock(sockerrno)) {
563 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
571 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
573 n = lookup_node_udp(mesh, &from);
576 n = try_harder(mesh, &from, &pkt);
579 update_node_udp(mesh, n, &from);
580 } else if(mesh->log_level >= MESHLINK_WARNING) {
581 hostname = sockaddr2hostname(&from);
582 logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
590 if(n->status.blacklisted) {
591 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
595 n->sock = ls - mesh->listen_socket;
597 receive_udppacket(mesh, n, &pkt);