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