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