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