2 net_packet.c -- Handles in- and outgoing VPN packets
3 Copyright (C) 2014-2017 Guus Sliepen <guus@meshlink.io>
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.
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.
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.
23 #include "connection.h"
27 #include "meshlink_internal.h"
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);
42 if(n->status.blacklisted) {
43 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
45 route(mesh, n, packet);
49 static bool try_mac(meshlink_handle_t *mesh, node_t *n, const vpn_packet_t *inpkt) {
51 return sptps_verify_datagram(&n->sptps, inpkt->data, inpkt->len);
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);
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);
65 logger(mesh, MESHLINK_DEBUG, "Got packet from %s but he hasn't got our key yet", n->name);
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));
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);
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);
88 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
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);
104 // If it's a probe, send it immediately without trying to compress it.
106 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
110 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
114 void choose_udp_address(meshlink_handle_t *mesh, const node_t *n, const sockaddr_t **sa, int *sock, sockaddr_t *sa_buf) {
119 /* If the UDP address is confirmed, use it. */
120 if(n->status.udp_confirmed) {
124 /* Send every third packet to n->address; that could be set
125 to the node's reflexive UDP address discovered during key
128 if(++mesh->udp_choice >= 3) {
129 mesh->udp_choice = 0;
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;
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, ' ');
146 *sa_buf = str2sockaddr_random(mesh, host, port);
149 if(sa_buf->sa.sa_family != AF_UNKNOWN) {
158 /* Otherwise, address are found in edges to this node.
159 So we pick a random edge and a random socket. */
161 edge_t *candidate = NULL;
165 int j = prng(mesh, n->edge_tree->count);
167 for splay_each(edge_t, e, n->edge_tree) {
169 candidate = e->reverse;
176 *sa = &candidate->address;
177 *sock = prng(mesh, mesh->listen_sockets);
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) {
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;
197 if(broadcast_sa->sa.sa_family == AF_INET6) {
198 broadcast_sa->in6.sin6_port = n->prevedge->address.in.sin_port;
200 broadcast_sa->in.sin_port = n->prevedge->address.in.sin_port;
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);
212 send_sptps_packet(mesh, n, origpkt);
215 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
221 meshlink_handle_t *mesh = to->mesh;
223 if(!to->status.reachable) {
224 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", to->name);
228 /* Send it via TCP if it is a handshake packet, TCPOnly is in use, or this packet is larger than the MTU. */
230 if(type >= SPTPS_HANDSHAKE || (type != PKT_PROBE && (len - 21) > to->minmtu)) {
231 char buf[len * 4 / 3 + 5];
232 b64encode(data, buf, len);
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);
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);
244 return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
248 /* Otherwise, send the packet via UDP */
251 const sockaddr_t *sa;
254 if(to->status.broadcast) {
255 choose_broadcast_address(mesh, to, &sa, &sock);
257 choose_udp_address(mesh, to, &sa, &sock, &sa_buf);
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;
266 if(to->mtu >= len - 21) {
270 logger(mesh, MESHLINK_WARNING, "Error sending UDP SPTPS packet to %s: %s", to->name, sockstrerror(sockerrno));
278 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
280 assert(!data || len);
282 node_t *from = handle;
283 meshlink_handle_t *mesh = from->mesh;
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;
292 utcp_reset_timers(from->utcp);
300 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
306 if(type == PKT_PROBE) {
309 memcpy(inpkt.data, data, len);
310 udp_probe_h(mesh, from, &inpkt, len);
316 if(type & ~(PKT_COMPRESSED)) {
317 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
321 if(type & PKT_COMPRESSED) {
322 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
326 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
329 receive_packet(mesh, from, &inpkt);
334 send a packet to the given vpn ip.
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
342 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
344 if(!n->status.reachable) {
345 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
349 n->status.want_udp = true;
351 send_sptps_packet(mesh, n, packet);
352 keepalive(mesh, n, true);
356 static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
360 for splay_each(edge_t, e, mesh->edges) {
361 if(!e->to->status.reachable || e->to == mesh->self) {
365 if(sockaddrcmp_noport(from, &e->address)) {
366 if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
373 if(!try_mac(mesh, e->to, pkt)) {
382 mesh->last_hard_try = mesh->loop.now.tv_sec;
388 void handle_incoming_vpn_data(event_loop_t *loop, void *data, int flags) {
390 meshlink_handle_t *mesh = loop->data;
391 listen_socket_t *ls = data;
395 socklen_t fromlen = sizeof(from);
399 memset(&from, 0, sizeof(from));
401 len = recvfrom(ls->udp.fd, pkt.data, MAXSIZE, 0, &from.sa, &fromlen);
403 if(len <= 0 || len > MAXSIZE) {
404 if(!sockwouldblock(sockerrno)) {
405 logger(mesh, MESHLINK_ERROR, "Receiving packet failed: %s", sockstrerror(sockerrno));
413 sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
415 n = lookup_node_udp(mesh, &from);
418 n = try_harder(mesh, &from, &pkt);
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);
432 if(n->status.blacklisted) {
433 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
437 n->sock = ls - mesh->listen_socket;
439 receive_udppacket(mesh, n, &pkt);