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