]> git.meshlink.io Git - meshlink/blob - src/net_packet.c
Drop dependency on zlib.
[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         abort();
200 }
201
202 static uint16_t uncompress_packet(uint8_t *dest, const uint8_t *source, uint16_t len, int level) {
203         abort();
204 }
205
206 /* VPN packet I/O */
207
208 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
209         logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s (%s)",
210                packet->len, n->name, n->hostname);
211
212         if(n->status.blacklisted)
213                 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
214         else {
215                 n->in_packets++;
216                 n->in_bytes += packet->len;
217
218                 route(mesh, n, packet);
219         }
220 }
221
222 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
223         return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
224 }
225
226 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
227         if(!n->sptps.state) {
228                 if(!n->status.waitingforkey) {
229                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but we haven't exchanged keys yet", n->name, n->hostname);
230                         send_req_key(mesh, n);
231                 } else
232                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname);
233                 return;
234         }
235         sptps_receive_data(&n->sptps, inpkt->data, inpkt->len);
236 }
237
238 void receive_tcppacket(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int len) {
239         vpn_packet_t outpkt;
240
241         if(len > sizeof outpkt.data)
242                 return;
243
244         outpkt.len = len;
245         outpkt.tcp = true;
246         memcpy(outpkt.data, buffer, len);
247
248         receive_packet(mesh, c->node, &outpkt);
249 }
250
251 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
252         if(!n->status.validkey) {
253                 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname);
254                 if(!n->status.waitingforkey)
255                         send_req_key(mesh, n);
256                 else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
257                         logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
258                         sptps_stop(&n->sptps);
259                         n->status.waitingforkey = false;
260                         send_req_key(mesh, n);
261                 }
262                 return;
263         }
264
265         uint8_t type = 0;
266
267         // If it's a probe, send it immediately without trying to compress it.
268         if(origpkt->probe) {
269                 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
270                 return;
271         }
272
273         vpn_packet_t outpkt;
274
275         if(n->outcompression) {
276                 int len = compress_packet(outpkt.data, origpkt->data, origpkt->len, n->outcompression);
277                 if(len < 0)
278                         logger(mesh, MESHLINK_ERROR, "Error while compressing packet to %s (%s)", n->name, n->hostname);
279                 else if(len < origpkt->len) {
280                         outpkt.len = len;
281                         origpkt = &outpkt;
282                         type |= PKT_COMPRESSED;
283                 }
284         }
285
286         sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
287         return;
288 }
289
290 static void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
291         /* Latest guess */
292         *sa = &n->address;
293         *sock = n->sock;
294
295         /* If the UDP address is confirmed, use it. */
296         if(n->status.udp_confirmed)
297                 return;
298
299         /* Send every third packet to n->address; that could be set
300            to the node's reflexive UDP address discovered during key
301            exchange. */
302
303         static int x = 0;
304         if(++x >= 3) {
305                 x = 0;
306                 return;
307         }
308
309         /* Otherwise, address are found in edges to this node.
310            So we pick a random edge and a random socket. */
311
312         int i = 0;
313         int j = rand() % n->edge_tree->count;
314         edge_t *candidate = NULL;
315
316         for splay_each(edge_t, e, n->edge_tree) {
317                 if(i++ == j) {
318                         candidate = e->reverse;
319                         break;
320                 }
321         }
322
323         if(candidate) {
324                 *sa = &candidate->address;
325                 *sock = rand() % mesh->listen_sockets;
326         }
327
328         /* Make sure we have a suitable socket for the chosen address */
329         if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
330                 for(int i = 0; i < mesh->listen_sockets; i++) {
331                         if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
332                                 *sock = i;
333                                 break;
334                         }
335                 }
336         }
337 }
338
339 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
340         static sockaddr_t broadcast_ipv4 = {
341                 .in = {
342                         .sin_family = AF_INET,
343                         .sin_addr.s_addr = -1,
344                 }
345         };
346
347         static sockaddr_t broadcast_ipv6 = {
348                 .in6 = {
349                         .sin6_family = AF_INET6,
350                         .sin6_addr.s6_addr[0x0] = 0xff,
351                         .sin6_addr.s6_addr[0x1] = 0x02,
352                         .sin6_addr.s6_addr[0xf] = 0x01,
353                 }
354         };
355
356         *sock = rand() % mesh->listen_sockets;
357
358         if(mesh->listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
359                 if(mesh->localdiscovery_address.sa.sa_family == AF_INET6) {
360                         mesh->localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
361                         *sa = &mesh->localdiscovery_address;
362                 } else {
363                         broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
364                         broadcast_ipv6.in6.sin6_scope_id = mesh->listen_socket[*sock].sa.in6.sin6_scope_id;
365                         *sa = &broadcast_ipv6;
366                 }
367         } else {
368                 if(mesh->localdiscovery_address.sa.sa_family == AF_INET) {
369                         mesh->localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
370                         *sa = &mesh->localdiscovery_address;
371                 } else {
372                         broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
373                         *sa = &broadcast_ipv4;
374                 }
375         }
376 }
377
378 static void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
379         if(!n->status.reachable) {
380                 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
381                 return;
382         }
383
384         return send_sptps_packet(mesh, n, origpkt);
385 }
386
387 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
388         node_t *to = handle;
389         meshlink_handle_t *mesh = to->mesh;
390
391         /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
392
393         if(type >= SPTPS_HANDSHAKE || ((mesh->self->options | to->options) & OPTION_TCPONLY) || (type != PKT_PROBE && len > to->minmtu)) {
394                 char buf[len * 4 / 3 + 5];
395                 b64encode(data, buf, len);
396                 /* If no valid key is known yet, send the packets using ANS_KEY requests,
397                    to ensure we get to learn the reflexive UDP address. */
398                 if(!to->status.validkey) {
399                         to->incompression = mesh->self->incompression;
400                         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);
401                 } else
402                         return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
403         }
404
405         /* Otherwise, send the packet via UDP */
406
407         const sockaddr_t *sa;
408         int sock;
409
410         if(to->status.broadcast)
411                 choose_broadcast_address(mesh, to, &sa, &sock);
412         else
413                 choose_udp_address(mesh, to, &sa, &sock);
414
415         if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
416                 if(sockmsgsize(sockerrno)) {
417                         if(to->maxmtu >= len)
418                                 to->maxmtu = len - 1;
419                         if(to->mtu >= len)
420                                 to->mtu = len - 1;
421                 } else {
422                         logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s (%s): %s", to->name, to->hostname, sockstrerror(sockerrno));
423                         return false;
424                 }
425         }
426
427         return true;
428 }
429
430 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
431         node_t *from = handle;
432         meshlink_handle_t *mesh = from->mesh;
433
434         if(type == SPTPS_HANDSHAKE) {
435                 if(!from->status.validkey) {
436                         from->status.validkey = true;
437                         from->status.waitingforkey = false;
438                         logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s (%s) succesful", from->name, from->hostname);
439                 }
440                 return true;
441         }
442
443         if(len > MTU) {
444                 logger(mesh, MESHLINK_ERROR, "Packet from %s (%s) larger than maximum supported size (%d > %d)", from->name, from->hostname, len, MTU);
445                 return false;
446         }
447
448         vpn_packet_t inpkt;
449
450         if(type == PKT_PROBE) {
451                 inpkt.len = len;
452                 inpkt.probe = true;
453                 memcpy(inpkt.data, data, len);
454                 mtu_probe_h(mesh, from, &inpkt, len);
455                 return true;
456         } else
457                 inpkt.probe = false;
458
459         if(type & ~(PKT_COMPRESSED)) {
460                 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s (%s)", type, len, from->name, from->hostname);
461                 return false;
462         }
463
464         if(type & PKT_COMPRESSED) {
465                 uint16_t ulen = uncompress_packet(inpkt.data, (const uint8_t *)data, len, from->incompression);
466                 if(ulen < 0)
467                         return false;
468                 else
469                         inpkt.len = ulen;
470                 if(inpkt.len > MAXSIZE)
471                         abort();
472         } else {
473                 memcpy(inpkt.data, data, len);
474                 inpkt.len = len;
475         }
476
477         receive_packet(mesh, from, &inpkt);
478         return true;
479 }
480
481 /*
482   send a packet to the given vpn ip.
483 */
484 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
485         if(n == mesh->self) {
486                 n->out_packets++;
487                 n->out_bytes += packet->len;
488                 // TODO: send to application
489                 return;
490         }
491
492         logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s (%s)",
493                packet->len, n->name, n->hostname);
494
495         if(!n->status.reachable) {
496                 logger(mesh, MESHLINK_WARNING, "Node %s (%s) is not reachable",
497                        n->name, n->hostname);
498                 return;
499         }
500
501         n->out_packets++;
502         n->out_bytes += packet->len;
503
504         send_sptps_packet(mesh, n, packet);
505         return;
506 }
507
508 /* Broadcast a packet using the minimum spanning tree */
509
510 void broadcast_packet(meshlink_handle_t *mesh, const node_t *from, vpn_packet_t *packet) {
511         // Always give ourself a copy of the packet.
512         if(from != mesh->self)
513                 send_packet(mesh, mesh->self, packet);
514
515         logger(mesh, MESHLINK_INFO, "Broadcasting packet of %d bytes from %s (%s)",
516                packet->len, from->name, from->hostname);
517
518         for list_each(connection_t, c, mesh->connections)
519                 if(c->status.active && c->status.mst && c != from->nexthop->connection)
520                         send_packet(mesh, c->node, packet);
521 }
522
523 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
524         node_t *n = NULL;
525         bool hard = false;
526         static time_t last_hard_try = 0;
527
528         for splay_each(edge_t, e, mesh->edges) {
529                 if(!e->to->status.reachable || e->to == mesh->self)
530                         continue;
531
532                 if(sockaddrcmp_noport(from, &e->address)) {
533                         if(last_hard_try == mesh->loop.now.tv_sec)
534                                 continue;
535                         hard = true;
536                 }
537
538                 if(!try_mac(mesh, e->to, pkt))
539                         continue;
540
541                 n = e->to;
542                 break;
543         }
544
545         if(hard)
546                 last_hard_try = mesh->loop.now.tv_sec;
547
548         last_hard_try = mesh->loop.now.tv_sec;
549         return n;
550 }
551
552 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
553         meshlink_handle_t *mesh = loop->data;
554         listen_socket_t *ls = data;
555         vpn_packet_t pkt;
556         char *hostname;
557         sockaddr_t from = {{0}};
558         socklen_t fromlen = sizeof from;
559         node_t *n;
560         int len;
561
562         len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
563
564         if(len <= 0 || len > MAXSIZE) {
565                 if(!sockwouldblock(sockerrno))
566                         logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
567                 return;
568         }
569
570         pkt.len = len;
571
572         sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
573
574         n = lookup_node_udp(mesh, &from);
575
576         if(!n) {
577                 n = try_harder(mesh, &from, &pkt);
578                 if(n)
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);
583                         free(hostname);
584                         return;
585                 } else
586                         return;
587         }
588
589         if(n->status.blacklisted) {
590                 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
591                 return;
592         }
593         n->sock = ls - mesh->listen_socket;
594
595         receive_udppacket(mesh, n, &pkt);
596 }