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