]> git.meshlink.io Git - meshlink/blob - src/net_packet.c
Don't send UDP probes to tiny nodes.
[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 "pmtu.h"
31 #include "protocol.h"
32 #include "route.h"
33 #include "sptps.h"
34 #include "utils.h"
35 #include "xalloc.h"
36
37 /* Packet I/O */
38
39 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
40         logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
41
42         if(n->status.blacklisted) {
43                 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
44         } else {
45                 route(mesh, n, packet);
46         }
47 }
48
49 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
50         (void)mesh;
51         return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
52 }
53
54 static void receive_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *inpkt) {
55         if(!n->status.reachable) {
56                 logger(mesh, MESHLINK_ERROR, "Got SPTPS data from unreachable node %s", n->name);
57                 return;
58         }
59
60         if(!n->sptps.state) {
61                 if(!n->status.waitingforkey) {
62                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s but we haven't exchanged keys yet", n->name);
63                         send_req_key(mesh, n);
64                 } else {
65                         logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
66                 }
67
68                 return;
69         }
70
71         if(!sptps_receive_data(&n->sptps, inpkt->data, inpkt->len)) {
72                 logger(mesh, MESHLINK_ERROR, "Could not process SPTPS data from %s: %s", n->name, strerror(errno));
73         }
74 }
75
76 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
77         if(!n->status.reachable) {
78                 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", n->name);
79                 return;
80         }
81
82         if(!n->status.validkey) {
83                 if(n->connection && (n->connection->flags & PROTOCOL_TINY) & n->connection->status.active) {
84                         send_raw_packet(mesh, n->connection, origpkt);
85                         return;
86                 }
87
88                 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
89
90                 if(!n->status.waitingforkey) {
91                         send_req_key(mesh, n);
92                 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
93                         logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
94                         sptps_stop(&n->sptps);
95                         n->status.waitingforkey = false;
96                         send_req_key(mesh, n);
97                 }
98
99                 return;
100         }
101
102         uint8_t type = 0;
103
104         // If it's a probe, send it immediately without trying to compress it.
105         if(origpkt->probe) {
106                 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
107                 return;
108         }
109
110         sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
111         return;
112 }
113
114 void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock, sockaddr_t *sa_buf) {
115         /* Latest guess */
116         *sa = &n->address;
117         *sock = n->sock;
118
119         /* If the UDP address is confirmed, use it. */
120         if(n->status.udp_confirmed) {
121                 return;
122         }
123
124         /* Send every third packet to n->address; that could be set
125            to the node's reflexive UDP address discovered during key
126            exchange. */
127
128         if(++mesh->udp_choice >= 3) {
129                 mesh->udp_choice = 0;
130                 return;
131         }
132
133         /* If we have learned an address via Catta, try this once every batch */
134         if(mesh->udp_choice == 1 && n->catta_address.sa.sa_family != AF_UNSPEC) {
135                 *sa = &n->catta_address;
136                 goto check_socket;
137         }
138
139         /* Else, if we have a canonical address, try this once every batch */
140         if(mesh->udp_choice == 1 && n->canonical_address) {
141                 char *host = xstrdup(n->canonical_address);
142                 char *port = strchr(host, ' ');
143
144                 if(port) {
145                         *port++ = 0;
146                         *sa_buf = str2sockaddr_random(mesh, host, port);
147                         *sa = sa_buf;
148
149                         if(sa_buf->sa.sa_family != AF_UNKNOWN) {
150                                 free(host);
151                                 goto check_socket;
152                         }
153                 }
154
155                 free(host);
156         }
157
158         /* Otherwise, address are found in edges to this node.
159            So we pick a random edge and a random socket. */
160
161         edge_t *candidate = NULL;
162
163         {
164                 int i = 0;
165                 int j = prng(mesh, n->edge_tree->count);
166
167                 for splay_each(edge_t, e, n->edge_tree) {
168                         if(i++ == j) {
169                                 candidate = e->reverse;
170                                 break;
171                         }
172                 }
173         }
174
175         if(candidate) {
176                 *sa = &candidate->address;
177                 *sock = prng(mesh, mesh->listen_sockets);
178         }
179
180 check_socket:
181
182         /* Make sure we have a suitable socket for the chosen address */
183         if(mesh->listen_socket[*sock].sa.sa.sa_family != (*sa)->sa.sa_family) {
184                 for(int i = 0; i < mesh->listen_sockets; i++) {
185                         if(mesh->listen_socket[i].sa.sa.sa_family == (*sa)->sa.sa_family) {
186                                 *sock = i;
187                                 break;
188                         }
189                 }
190         }
191 }
192
193 static void choose_broadcast_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock) {
194         *sock = prng(mesh, mesh->listen_sockets);
195         sockaddr_t *broadcast_sa = &mesh->listen_socket[*sock].broadcast_sa;
196
197         if(broadcast_sa->sa.sa_family == AF_INET6) {
198                 broadcast_sa->in6.sin6_port = n->prevedge->address.in.sin_port;
199         } else {
200                 broadcast_sa->in.sin_port = n->prevedge->address.in.sin_port;
201         }
202
203         *sa = broadcast_sa;
204 }
205
206 void send_udppacket(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
207         if(!n->status.reachable) {
208                 logger(mesh, MESHLINK_INFO, "Trying to send UDP packet to unreachable node %s", n->name);
209                 return;
210         }
211
212         send_sptps_packet(mesh, n, origpkt);
213 }
214
215 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
216         assert(handle);
217         assert(data);
218         assert(len);
219
220         node_t *to = handle;
221         meshlink_handle_t *mesh = to->mesh;
222
223         if(!to->status.reachable) {
224                 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", to->name);
225                 return false;
226         }
227
228         /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
229
230         if(type >= SPTPS_HANDSHAKE || (type != PKT_PROBE && (len - 21) > to->minmtu)) {
231                 char buf[len * 4 / 3 + 5];
232                 b64encode(data, buf, len);
233
234                 if(!to->nexthop || !to->nexthop->connection) {
235                         logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
236                         return false;
237                 }
238
239                 /* If no valid key is known yet, send the packets using ANS_KEY requests,
240                    to ensure we get to learn the reflexive UDP address. */
241                 if(!to->status.validkey) {
242                         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);
243                 } else {
244                         return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
245                 }
246         }
247
248         /* Otherwise, send the packet via UDP */
249
250         sockaddr_t sa_buf;
251         const sockaddr_t *sa;
252         int sock;
253
254         if(to->status.broadcast) {
255                 choose_broadcast_address(mesh, to, &sa, &sock);
256         } else {
257                 choose_udp_address(mesh, to, &sa, &sock, &sa_buf);
258         }
259
260         if(sendto(mesh->listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
261                 if(sockmsgsize(sockerrno) && len > 21) {
262                         if(to->maxmtu >= len - 21) {
263                                 to->maxmtu = len - 22;
264                         }
265
266                         if(to->mtu >= len - 21) {
267                                 to->mtu = len - 22;
268                         }
269                 } else {
270                         logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
271                         return false;
272                 }
273         }
274
275         return true;
276 }
277
278 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
279         assert(handle);
280         assert(!data || len);
281
282         node_t *from = handle;
283         meshlink_handle_t *mesh = from->mesh;
284
285         if(type == SPTPS_HANDSHAKE) {
286                 if(!from->status.validkey) {
287                         logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s successful", from->name);
288                         from->status.validkey = true;
289                         from->status.waitingforkey = false;
290
291                         if(from->utcp) {
292                                 utcp_reset_timers(from->utcp);
293                         }
294                 }
295
296                 return true;
297         }
298
299         if(len > MAXSIZE) {
300                 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
301                 return false;
302         }
303
304         vpn_packet_t inpkt;
305
306         if(type == PKT_PROBE) {
307                 inpkt.len = len;
308                 inpkt.probe = true;
309                 memcpy(inpkt.data, data, len);
310                 udp_probe_h(mesh, from, &inpkt, len);
311                 return true;
312         } else {
313                 inpkt.probe = false;
314         }
315
316         if(type & ~(PKT_COMPRESSED)) {
317                 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
318                 return false;
319         }
320
321         if(type & PKT_COMPRESSED) {
322                 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
323                 return false;
324         }
325
326         memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
327         inpkt.len = len;
328
329         receive_packet(mesh, from, &inpkt);
330         return true;
331 }
332
333 /*
334   send a packet to the given vpn ip.
335 */
336 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
337         if(n == mesh->self) {
338                 // TODO: send to application
339                 return;
340         }
341
342         logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
343
344         if(!n->status.reachable) {
345                 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
346                 return;
347         }
348
349         n->status.want_udp = true;
350
351         send_sptps_packet(mesh, n, packet);
352         keepalive(mesh, n, true);
353         return;
354 }
355
356 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
357         node_t *n = NULL;
358         bool hard = false;
359
360         for splay_each(edge_t, e, mesh->edges) {
361                 if(!e->to->status.reachable || e->to == mesh->self) {
362                         continue;
363                 }
364
365                 if(sockaddrcmp_noport(from, &e->address)) {
366                         if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
367                                 continue;
368                         }
369
370                         hard = true;
371                 }
372
373                 if(!try_mac(mesh, e->to, pkt)) {
374                         continue;
375                 }
376
377                 n = e->to;
378                 break;
379         }
380
381         if(hard) {
382                 mesh->last_hard_try = mesh->loop.now.tv_sec;
383         }
384
385         return n;
386 }
387
388 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
389         (void)flags;
390         meshlink_handle_t *mesh = loop->data;
391         listen_socket_t *ls = data;
392         vpn_packet_t pkt;
393         char *hostname;
394         sockaddr_t from;
395         socklen_t fromlen = sizeof(from);
396         node_t *n;
397         int len;
398
399         memset(&from, 0, sizeof(from));
400
401         len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
402
403         if(len <= 0 || len > MAXSIZE) {
404                 if(!sockwouldblock(sockerrno)) {
405                         logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
406                 }
407
408                 return;
409         }
410
411         pkt.len = len;
412
413         sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
414
415         n = lookup_node_udp(mesh, &from);
416
417         if(!n) {
418                 n = try_harder(mesh, &from, &pkt);
419
420                 if(n) {
421                         update_node_udp(mesh, n, &from);
422                 } else if(mesh->log_level <= MESHLINK_WARNING) {
423                         hostname = sockaddr2hostname(&from);
424                         logger(mesh, MESHLINK_WARNING, "Received UDP packet from unknown source %s", hostname);
425                         free(hostname);
426                         return;
427                 } else {
428                         return;
429                 }
430         }
431
432         if(n->status.blacklisted) {
433                 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
434                 return;
435         }
436
437         n->sock = ls - mesh->listen_socket;
438
439         receive_udppacket(mesh, n, &pkt);
440 }