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);
45 n->in_bytes += packet->len;
47 route(mesh, n, packet);
51 static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *origpkt) {
52 if(!n->status.reachable) {
53 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", n->name);
57 if(!n->status.validkey) {
58 logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
60 if(!n->status.waitingforkey) {
61 send_req_key(mesh, n);
62 } else if(n->last_req_key + 10 < mesh->loop.now.tv_sec) {
63 logger(mesh, MESHLINK_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name);
64 sptps_stop(&n->sptps);
65 n->status.waitingforkey = false;
66 send_req_key(mesh, n);
74 // If it's a probe, send it immediately without trying to compress it.
76 sptps_send_record(&n->sptps, PKT_PROBE, origpkt->data, origpkt->len);
80 sptps_send_record(&n->sptps, type, origpkt->data, origpkt->len);
84 bool send_sptps_data(void *handle, uint8_t type, const void *data, size_t len) {
90 meshlink_handle_t *mesh = to->mesh;
92 if(!to->status.reachable) {
93 logger(mesh, MESHLINK_ERROR, "Trying to send SPTPS data to unreachable node %s", to->name);
98 if(type == PKT_PROBE) {
99 /* Probe packets are not supported. */
103 /* Send it via TCP. */
105 char buf[len * 4 / 3 + 5];
106 b64encode(data, buf, len);
108 if(!to->nexthop || !to->nexthop->connection) {
109 logger(mesh, MESHLINK_WARNING, "Unable to forward SPTPS packet to %s via %s", to->name, to->nexthop ? to->nexthop->name : to->name);
113 /* If no valid key is known yet, send the packets using ANS_KEY requests,
114 to ensure we get to learn the reflexive UDP address. */
115 if(!to->status.validkey) {
116 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);
118 return send_request(mesh, to->nexthop->connection, NULL, "%d %s %s %d %s", REQ_KEY, mesh->self->name, to->name, REQ_SPTPS, buf);
122 bool receive_sptps_record(void *handle, uint8_t type, const void *data, uint16_t len) {
124 assert(!data || len);
126 node_t *from = handle;
127 meshlink_handle_t *mesh = from->mesh;
129 if(type == SPTPS_HANDSHAKE) {
130 if(!from->status.validkey) {
131 logger(mesh, MESHLINK_INFO, "SPTPS key exchange with %s successful", from->name);
132 from->status.validkey = true;
133 from->status.waitingforkey = false;
136 utcp_reset_timers(from->utcp);
144 logger(mesh, MESHLINK_ERROR, "Packet from %s larger than maximum supported size (%d > %d)", from->name, len, MAXSIZE);
150 if(type == PKT_PROBE) {
151 /* We shouldn't receive any UDP probe packets. */
157 if(type & ~(PKT_COMPRESSED)) {
158 logger(mesh, MESHLINK_ERROR, "Unexpected SPTPS record type %d len %d from %s", type, len, from->name);
162 if(type & PKT_COMPRESSED) {
163 logger(mesh, MESHLINK_ERROR, "Error while decompressing packet from %s", from->name);
167 memcpy(inpkt.data, data, len); // TODO: get rid of memcpy
170 receive_packet(mesh, from, &inpkt);
175 send a packet to the given vpn ip.
177 void send_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *packet) {
178 if(n == mesh->self) {
180 n->out_bytes += packet->len;
181 // TODO: send to application
185 logger(mesh, MESHLINK_DEBUG, "Sending packet of %d bytes to %s", packet->len, n->name);
187 if(!n->status.reachable) {
188 logger(mesh, MESHLINK_WARNING, "Node %s is not reachable", n->name);
193 n->out_bytes += packet->len;
194 n->status.want_udp = true;
196 send_sptps_packet(mesh, n, packet);