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