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