]> git.meshlink.io Git - meshlink/blob - src/net_packet.c
Remove unused replay window and RTT/bandwidth estimation code.
[meshlink] / src / net_packet.c
1 /*
2     net_packet.c -- Handles in- and outgoing VPN packets
3     Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
4
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.
9
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.
14
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.
18 */
19
20 #include "system.h"
21
22 #ifdef HAVE_ZLIB
23 #include <zlib.h>
24 #endif
25
26 #include "conf.h"
27 #include "connection.h"
28 #include "crypto.h"
29 #include "graph.h"
30 #include "logger.h"
31 #include "meshlink_internal.h"
32 #include "net.h"
33 #include "netutl.h"
34 #include "protocol.h"
35 #include "route.h"
36 #include "utils.h"
37 #include "xalloc.h"
38
39 int keylifetime = 0;
40
41 static void send_udppacket(meshlink_handle_t *mesh, node_t *, vpn_packet_t *);
42
43 #define MAX_SEQNO 1073741824
44
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
49
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.
52
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.
55
56    In case local discovery is enabled, another packet is added to each batch,
57    which will be broadcast to the local network.
58
59 */
60
61 static void send_mtu_probe_handler(event_loop_t *loop, void *data) {
62         meshlink_handle_t *mesh = loop->data;
63         node_t *n = data;
64         int timeout = 1;
65
66         n->mtuprobes++;
67
68         if(!n->status.reachable || !n->status.validkey) {
69                 logger(mesh, MESHLINK_INFO, "Trying to send MTU probe to unreachable or rekeying node %s (%s)", n->name, n->hostname);
70                 n->mtuprobes = 0;
71                 return;
72         }
73
74         if(n->mtuprobes > 32) {
75                 if(!n->minmtu) {
76                         n->mtuprobes = 31;
77                         timeout = mesh->pinginterval;
78                         goto end;
79                 }
80
81                 logger(mesh, MESHLINK_INFO, "%s (%s) did not respond to UDP ping, restarting PMTU discovery", n->name, n->hostname);
82                 n->status.udp_confirmed = false;
83                 n->mtuprobes = 1;
84                 n->minmtu = 0;
85                 n->maxmtu = MTU;
86         }
87
88         if(n->mtuprobes >= 10 && n->mtuprobes < 32 && !n->minmtu) {
89                 logger(mesh, MESHLINK_INFO, "No response to MTU probes from %s (%s)", n->name, n->hostname);
90                 n->mtuprobes = 31;
91         }
92
93         if(n->mtuprobes == 30 || (n->mtuprobes < 30 && n->minmtu >= n->maxmtu)) {
94                 if(n->minmtu > n->maxmtu)
95                         n->minmtu = n->maxmtu;
96                 else
97                         n->maxmtu = n->minmtu;
98                 n->mtu = n->minmtu;
99                 logger(mesh, MESHLINK_INFO, "Fixing MTU of %s (%s) to %d after %d probes", n->name, n->hostname, n->mtu, n->mtuprobes);
100                 n->mtuprobes = 31;
101         }
102
103         if(n->mtuprobes == 31) {
104                 timeout = mesh->pinginterval;
105                 goto end;
106         } else if(n->mtuprobes == 32) {
107                 timeout = mesh->pingtimeout;
108         }
109
110         for(int i = 0; i < 4 + mesh->localdiscovery; i++) {
111                 int len;
112
113                 if(i == 0) {
114                         if(n->mtuprobes < 30 || n->maxmtu + 8 >= MTU)
115                                 continue;
116                         len = n->maxmtu + 8;
117                 } else if(n->maxmtu <= n->minmtu) {
118                         len = n->maxmtu;
119                 } else {
120                         len = n->minmtu + 1 + rand() % (n->maxmtu - n->minmtu);
121                 }
122
123                 if(len < 64)
124                         len = 64;
125
126                 vpn_packet_t packet;
127                 packet.probe = true;
128                 memset(packet.data, 0, 14);
129                 randomize(packet.data + 14, len - 14);
130                 packet.len = len;
131                 n->status.broadcast = i >= 4 && n->mtuprobes <= 10 && n->prevedge;
132
133                 logger(mesh, MESHLINK_DEBUG, "Sending MTU probe length %d to %s (%s)", len, n->name, n->hostname);
134
135                 send_udppacket(mesh, n, &packet);
136         }
137
138         n->status.broadcast = false;
139
140 end:
141         timeout_set(&mesh->loop, &n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
142 }
143
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){1, 0});
146         send_mtu_probe_handler(&mesh->loop, n);
147 }
148
149 static void mtu_probe_h(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet, uint16_t len) {
150         logger(mesh, MESHLINK_DEBUG, "Got MTU probe length %d from %s (%s)", packet->len, n->name, n->hostname);
151
152         if(!packet->data[0]) {
153                 /* It's a probe request, send back a reply */
154
155                 packet->data[0] = 1;
156
157                 /* Temporarily set udp_confirmed, so that the reply is sent
158                    back exactly the way it came in. */
159
160                 bool udp_confirmed = n->status.udp_confirmed;
161                 n->status.udp_confirmed = true;
162                 send_udppacket(mesh, n, packet);
163                 n->status.udp_confirmed = udp_confirmed;
164         } else {
165                 /* It's a valid reply: now we know bidirectional communication
166                    is possible using the address and socket that the reply
167                    packet used. */
168
169                 n->status.udp_confirmed = true;
170
171                 /* If we haven't established the PMTU yet, restart the discovery process. */
172
173                 if(n->mtuprobes > 30) {
174                         if (len == n->maxmtu + 8) {
175                                 logger(mesh, MESHLINK_INFO, "Increase in PMTU to %s (%s) detected, restarting PMTU discovery", n->name, n->hostname);
176                                 n->maxmtu = MTU;
177                                 n->mtuprobes = 10;
178                                 return;
179                         }
180
181                         if(n->minmtu)
182                                 n->mtuprobes = 30;
183                         else
184                                 n->mtuprobes = 1;
185                 }
186
187                 /* If applicable, raise the minimum supported MTU */
188
189                 if(len > n->maxmtu)
190                         len = n->maxmtu;
191                 if(n->minmtu < len)
192                         n->minmtu = len;
193         }
194 }
195
196 static uint16_t compress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
197         if(level == 0) {
198                 memcpy(dest, source, len);
199                 return len;
200         } else if(level == 10) {
201                 return -1;
202         } else if(level < 10) {
203 #ifdef HAVE_ZLIB
204                 unsigned long destlen = MAXSIZE;
205                 if(compress2(dest, &destlen, source, len, level) == Z_OK)
206                         return destlen;
207                 else
208 #endif
209                         return -1;
210         } else {
211                 return -1;
212         }
213
214         return -1;
215 }
216
217 static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
218         if(level == 0) {
219                 memcpy(dest, source, len);
220                 return len;
221         } else if(level > 9) {
222                         return -1;
223         }
224 #ifdef HAVE_ZLIB
225         else {
226                 unsigned long destlen = MAXSIZE;
227                 if(uncompress(dest, &destlen, source, len) == Z_OK)
228                         return destlen;
229                 else
230                         return -1;
231         }
232 #endif
233
234         return -1;
235 }
236
237 /* VPN packet I/O */
238
239 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
240         logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s (%s)",
241                            packet->len, n->name, n->hostname);
242
243     if (n->status.blacklisted) {
244         logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
245     } else {
246         n->in_packets++;
247         n->in_bytes += packet->len;
248
249         route(mesh, n, packet);
250     }
251 }
252
253 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
254         return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
255 }
256
257 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
258         if(!n->sptps.state) {
259                 if(!n->status.waitingforkey) {
260                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
261                         send_req_key(mesh, n);
262                 } else {
263                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
264                 }
265                 return;
266         }
267         sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
268 }
269
270 void receive_tcppacket(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int len) {
271         vpn_packet_t outpkt;
272
273         if(len > sizeof outpkt.data)
274                 return;
275
276         outpkt.len = len;
277         outpkt.tcp = true;
278         memcpy(outpkt.data, buffer, len);
279
280         receive_packet(mesh, c->node, &outpkt);
281 }
282
283 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
284         if(!n->status.validkey) {
285                 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
286                 if(!n->status.waitingforkey)
287                         send_req_key(mesh, n);
288                 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
289                         logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
290                         sptps_stop(&n->sptps);
291                         n->status.waitingforkey = false;
292                         send_req_key(mesh, n);
293                 }
294                 return;
295         }
296
297         uint8_t type = 0;
298
299         // If it's a probe, send it immediately without trying to compress it.
300         if(origpkt->probe) {
301                 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
302                 return;
303         }
304
305         vpn_packet_t outpkt;
306
307         if(n->outcompression) {
308                 int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
309                 if(len < 0) {
310                         logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
311                 } else if(len < origpkt->len) {
312                         outpkt.len = len;
313                         origpkt = &outpkt;
314                         type |= PKT_COMPRESSED;
315                 }
316         }
317
318         sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
319         return;
320 }
321
322 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
323         /* Latest guess */
324         *sa = &n->address;
325         *sock = n->sock;
326
327         /* If the UDP address is confirmed, use it. */
328         if(n->status.udp_confirmed)
329                 return;
330
331         /* Send every third packet to n->address; that could be set
332            to the node's reflexive UDP address discovered during key
333            exchange. */
334
335         static int x = 0;
336         if(++x >= 3) {
337                 x = 0;
338                 return;
339         }
340
341         /* Otherwise, address are found in edges to this node.
342            So we pick a random edge and a random socket. */
343
344         int i = 0;
345         int j = rand() % n->edge_tree->count;
346         edge_t *candidate = NULL;
347
348         for splay_each(edge_t, e, n->edge_tree) {
349                 if(i++ == j) {
350                         candidate = e->reverse;
351                         break;
352                 }
353         }
354
355         if(candidate) {
356                 *sa = &candidate->address;
357                 *sock = rand() % mesh->listen_sockets;
358         }
359
360         /* Make sure we have a suitable socket for the chosen address */
361         if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
362                 for(int i = 0; i < mesh->listen_sockets; i++) {
363                         if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
364                                 *sock = i;
365                                 break;
366                         }
367                 }
368         }
369 }
370
371 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
372         static sockaddr_t broadcast_ipv4 = {
373                 .in = {
374                         .sin_family = AF_INET,
375                         .sin_addr.s_addr = -1,
376                 }
377         };
378
379         static sockaddr_t broadcast_ipv6 = {
380                 .in6 = {
381                         .sin6_family = AF_INET6,
382                         .sin6_addr.s6_addr[0x0] = 0xff,
383                         .sin6_addr.s6_addr[0x1] = 0x02,
384                         .sin6_addr.s6_addr[0xf] = 0x01,
385                 }
386         };
387
388         *sock = rand() % mesh->listen_sockets;
389
390         if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
391                 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
392                         mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
393                         *sa = &mesh->localdiscovery_address;
394                 } else {
395                         broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
396                         broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
397                         *sa = &broadcast_ipv6;
398                 }
399         } else {
400                 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
401                         mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
402                         *sa = &mesh->localdiscovery_address;
403                 } else {
404                         broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
405                         *sa = &broadcast_ipv4;
406                 }
407         }
408 }
409
410 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
411         if(!n->status.reachable) {
412                 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
413                 return;
414         }
415
416         return send_sptps_packet(mesh, n, origpkt);
417 }
418
419 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
420         node_t *to = handle;
421         meshlink_handle_t *mesh = to->mesh;
422
423         /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
424
425         if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
426                 char buf[len * 4 / 3 + 5];
427                 b64encode(data, buf, len);
428                 /* If no valid key is known yet, send the packets using ANS_KEY requests,
429                    to ensure we get to learn the reflexive UDP address. */
430                 if(!to->status.validkey) {
431                         to->incompression = mesh->self->incompression;
432                         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);
433                 } else {
434                         return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
435                 }
436         }
437
438         /* Otherwise, send the packet via UDP */
439
440         const sockaddr_t *sa;
441         int sock;
442
443         if(to->status.broadcast)
444                 choose_broadcast_address(mesh, to, &sa, &sock);
445         else
446                 choose_udp_address(mesh, to, &sa, &sock);
447
448         if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
449                 if(sockmsgsize(sockerrno)) {
450                         if(to->maxmtu >= len)
451                                 to->maxmtu = len - 1;
452                         if(to->mtu >= len)
453                                 to->mtu = len - 1;
454                 } else {
455                         logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
456                         return false;
457                 }
458         }
459
460         return true;
461 }
462
463 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
464         node_t *from = handle;
465         meshlink_handle_t *mesh = from->mesh;
466
467         if(type == SPTPS_HANDSHAKE) {
468                 if(!from->status.validkey) {
469                         from->status.validkey = true;
470                         from->status.waitingforkey = false;
471                         logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
472                 }
473                 return true;
474         }
475
476         if(len > MTU) {
477                 logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
478                 return false;
479         }
480
481         vpn_packet_t inpkt;
482
483         if(type == PKT_PROBE) {
484                 inpkt.len = len;
485                 inpkt.probe = true;
486                 memcpy(inpkt.data, data, len);
487                 mtu_probe_h(mesh, from, &inpkt, len);
488                 return true;
489         } else {
490                 inpkt.probe = false;
491         }
492
493         if(type & ~(PKT_COMPRESSED)) {
494                 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
495                 return false;
496         }
497
498         if(type & PKT_COMPRESSED) {
499                 uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression);
500                 if(ulen < 0) {
501                         return false;
502                 } else {
503                         inpkt.len = ulen;
504                 }
505                 if(inpkt.len > MAXSIZE)
506                         abort();
507         } else {
508                 memcpy(inpkt.data, data, len);
509                 inpkt.len = len;
510         }
511
512         receive_packet(mesh, from, &inpkt);
513         return true;
514 }
515
516 /*
517   send a packet to the given vpn ip.
518 */
519 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
520         if(n == mesh->self) {
521                 n->out_packets++;
522                 n->out_bytes += packet->len;
523                 // TODO: send to application
524                 return;
525         }
526
527         logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s (%s)",
528                            packet->len, n->name, n->hostname);
529
530         if(!n->status.reachable) {
531                 logger(mesh, MESHLINK_WARNING, "Node %s (%s) is not reachable",
532                                    n->name, n->hostname);
533                 return;
534         }
535
536         n->out_packets++;
537         n->out_bytes += packet->len;
538
539         send_sptps_packet(mesh, n, packet);
540         return;
541 }
542
543 /* Broadcast a packet using the minimum spanning tree */
544
545 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
546         // Always give ourself a copy of the packet.
547         if(from != mesh->self)
548                 send_packet(mesh, mesh->self, packet);
549
550         logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
551                            packet->len, from->name, from->hostname);
552
553         for list_each(connection_t, c, mesh->connections)
554                 if(c->status.active && c->status.mst && c != from->nexthop->connection)
555                         send_packet(mesh, c->node, packet);
556 }
557
558 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
559         node_t *n = NULL;
560         bool hard = false;
561         static time_t last_hard_try = 0;
562
563         for splay_each(edge_t, e, mesh->edges) {
564                 if(!e->to->status.reachable || e->to == mesh->self)
565                         continue;
566
567                 if(sockaddrcmp_noport(from, &e->address)) {
568                         if(last_hard_try == mesh->loop.now.tv_sec)
569                                 continue;
570                         hard = true;
571                 }
572
573                 if(!try_mac(mesh, e->to, pkt))
574                         continue;
575
576                 n = e->to;
577                 break;
578         }
579
580         if(hard)
581                 last_hard_try = mesh->loop.now.tv_sec;
582
583         last_hard_try = mesh->loop.now.tv_sec;
584         return n;
585 }
586
587 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
588         meshlink_handle_t *mesh = loop->data;
589         listen_socket_t *ls = data;
590         vpn_packet_t pkt;
591         char *hostname;
592         sockaddr_t from = {{0}};
593         socklen_t fromlen = sizeof from;
594         node_t *n;
595         int len;
596
597         len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
598
599         if(len <= 0 || len > MAXSIZE) {
600                 if(!sockwouldblock(sockerrno))
601                         logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
602                 return;
603         }
604
605         pkt.len = len;
606
607         sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
608
609         n = lookup_node_udp(mesh, &from);
610
611         if(!n) {
612                 n = try_harder(mesh, &from, &pkt);
613                 if(n)
614                         update_node_udp(mesh, n, &from);
615                 else if(mesh->log_level >= MESHLINK_WARNING) {
616                         hostname = sockaddr2hostname(&from);
617                         logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
618                         free(hostname);
619                         return;
620                 }
621                 else
622                         return;
623         }
624
625     if (n->status.blacklisted) {
626                         logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
627             return;
628     }
629         n->sock = ls - mesh->listen_socket;
630
631         receive_udppacket(mesh, n, &pkt);
632 }