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"
26 #include "meshlink_internal.h"
38 static void receive_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
39 logger(mesh, MESHLINK_DEBUG, "Received packet of %d bytes from %s", packet->len, n->name);
41 if(n->status.blacklisted) {
42 logger(mesh, MESHLINK_WARNING, "Dropping packet from blacklisted node %s", n->name);
44 route(mesh, n, packet);
48 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
49 if(!n->status.reachable) {
50 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", n->name);
54 if(!n->status.validkey) {
55 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
57 if(!n->status.waitingforkey) {
58 send_req_key(mesh, n);
59 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
60 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
61 sptps_stop(&n->sptps);
62 n->status.waitingforkey = false;
63 send_req_key(mesh, n);
71 // If it's a probe, send it immediately without trying to compress it.
73 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
77 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
81 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
87 meshlink_handle_t *mesh = to->mesh;
89 if(!to->status.reachable) {
90 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", to->name);
95 if(type == PKT_PROBE) {
96 /* Probe packets are not supported. */
100 /* Send it via TCP. */
102 char buf[len * 4 / 3 + 5];
103 b64encode(data, buf, len);
105 if(!to->nexthop || !to->nexthop->connection) {
106 logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
110 /* If no valid key is known yet, send the packets using ANS_KEY requests,
111 to ensure we get to learn the reflexive UDP address. */
112 if(!to->status.validkey) {
113 return send_request(mesh, to->nexthop->connection, "%d %s %s %s -1 -1 -1 %d", ANS_KEY, mesh->self->name, to->name, buf, 0);
115 return send_request(mesh, to->nexthop->connection, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
119 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
121 assert(!data || len);
123 node_t *from = handle;
124 meshlink_handle_t *mesh = from->mesh;
126 if(type == SPTPS_HANDSHAKE) {
127 if(!from->status.validkey) {
128 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s successful", from->name);
129 from->status.validkey = true;
130 from->status.waitingforkey = false;
133 utcp_reset_timers(from->utcp);
141 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
147 if(type == PKT_PROBE) {
148 /* We shouldn't receive any UDP probe packets. */
154 if(type & ~(PKT_COMPRESSED)) {
155 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
159 if(type & PKT_COMPRESSED) {
160 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
164 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
167 receive_packet(mesh, from, &inpkt);
172 send a packet to the given vpn ip.
174 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
175 if(n == mesh->self) {
176 // TODO: send to application
180 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
182 if(!n->status.reachable) {
183 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
187 send_sptps_packet(mesh, n, packet);