]> git.meshlink.io Git - meshlink/commitdiff
Handle raw packets from tiny peers.
authorGuus Sliepen <guus@meshlink.io>
Tue, 22 Jun 2021 19:44:01 +0000 (21:44 +0200)
committerGuus Sliepen <guus@meshlink.io>
Tue, 22 Jun 2021 19:44:01 +0000 (21:44 +0200)
Tiny peers don't support UTCP channels, but send raw packets directly over
the meta connection.

src/connection.h
src/meshlink.c
src/meshlink_internal.h
src/meta.c
src/net_packet.c
src/protocol.c
src/protocol.h
src/protocol_misc.c
src/route.c

index 68d9e97143bb5efd2e6dc77fe1ac29e7539962f7..5e3a7ac7e4f84f372ad9bbe6436184e09f8985f0 100644 (file)
@@ -41,6 +41,7 @@ typedef struct connection_status_t {
        uint16_t invitation: 1;             /* 1 if this is an invitation */
        uint16_t invitation_used: 1;        /* 1 if the invitation has been consumed */
        uint16_t initiator: 1;              /* 1 if we initiated this connection */
+       uint16_t raw_packet: 1;             /* 1 if we are expecting a raw packet next */
 } connection_status_t;
 
 #include "ecdsa.h"
index 4cc285deec1d8270624bf7ba3b7374213da083ec..f153f7573419d55d5adbc19114c371aa8da7ad87 100644 (file)
@@ -4034,7 +4034,7 @@ void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t
        channel->receive_cb = cb;
 }
 
-static void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
+void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, const void *data, size_t len) {
        (void)mesh;
        node_t *n = (node_t *)source;
 
@@ -4188,7 +4188,6 @@ void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_ac
        }
 
        mesh->channel_accept_cb = cb;
-       mesh->receive_cb = channel_receive;
 
        for splay_each(node_t, n, mesh->nodes) {
                if(!n->utcp && n != mesh->self) {
@@ -4283,7 +4282,6 @@ meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_n
                n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);
                utcp_set_mtu(n->utcp, n->mtu - sizeof(meshlink_packethdr_t));
                utcp_set_retransmit_cb(n->utcp, channel_retransmit);
-               mesh->receive_cb = channel_receive;
 
                if(!n->utcp) {
                        meshlink_errno = errno == ENOMEM ? MESHLINK_ENOMEM : MESHLINK_EINTERNAL;
index 26186015cb3b40660acc040830a865fc69610cf0..469a05b1aec146e81f0bf3482fcf2405f2c41ccd 100644 (file)
@@ -250,6 +250,7 @@ extern meshlink_log_cb_t global_log_cb;
 void handle_duplicate_node(meshlink_handle_t *mesh, struct node_t *n);
 void handle_network_change(meshlink_handle_t *mesh, bool online);
 void call_error_cb(meshlink_handle_t *mesh, meshlink_errno_t meshlink_errno);
+void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *node, const void *data, size_t len);
 
 /// Per-instance PRNG
 static inline int prng(meshlink_handle_t *mesh, uint64_t max) {
index 13024677d0bb50f147a738b834682ea2f90f4c89..a023d2a54131950647df0b56d2065ee0abf443bf 100644 (file)
@@ -47,7 +47,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const void *buffer, size_t leng
 bool send_meta(meshlink_handle_t *mesh, connection_t *c, const char *buffer, int length) {
        assert(c);
        assert(buffer);
-       assert(length);
+       assert(length >= 0);
 
        logger(mesh, MESHLINK_DEBUG, "Sending %d bytes of metadata to %s", length, c->name);
 
@@ -107,10 +107,16 @@ bool receive_meta_sptps(void *handle, uint8_t type, const void *data, uint16_t l
                return true;
        }
 
-       /* Are we receiving a TCPpacket? */
+       /* Are we receiving a raw packet? */
+
+       if(c->status.raw_packet) {
+               c->status.raw_packet = false;
 
-       if(c->tcplen) {
-               abort(); // TODO: get rid of tcplen altogether
+               if(mesh->receive_cb) {
+                       mesh->receive_cb(mesh, (meshlink_node_t *)c->node, data, length);
+               }
+
+               return true;
        }
 
        /* Change newline to null byte, just like non-SPTPS requests */
index 02a617d1922bfae065a41539b14ddedec707964e..67fadfc5a8c6817d740ec5a33aba029ea4417994 100644 (file)
@@ -279,6 +279,11 @@ static void send_sptps_packet(meshlink_handle_t *mesh, node_t *n, vpn_packet_t *
        }
 
        if(!n->status.validkey) {
+               if(n->connection && (n->connection->flags & PROTOCOL_TINY) & n->connection->status.active) {
+                       send_raw_packet(mesh, n->connection, origpkt);
+                       return;
+               }
+
                logger(mesh, MESHLINK_INFO, "No valid key known yet for %s", n->name);
 
                if(!n->status.waitingforkey) {
index 9d1dff971e2b800a803584027aeb914866032be8..9975402c592c14ed5a9d6d7edce90cce5f2caa66 100644 (file)
@@ -44,6 +44,7 @@ static bool (*request_handlers[NUM_REQUESTS])(meshlink_handle_t *, connection_t
        [KEY_CHANGED] = key_changed_h,
        [REQ_KEY] = req_key_h,
        [ANS_KEY] = ans_key_h,
+       [PACKET] = raw_packet_h,
 };
 
 /* Request names */
@@ -61,6 +62,7 @@ static const char *request_name[NUM_REQUESTS] = {
        [KEY_CHANGED] = "KEY_CHANGED",
        [REQ_KEY] = "REQ_KEY",
        [ANS_KEY] = "ANS_KEY",
+       [PACKET] = "PACKET",
 };
 
 bool check_id(const char *id) {
index 05c2203bf70bc791bbb8657e3090191a8aa55e81..94f760f1e2cb0cf51b5d786b93eedb4de994e314 100644 (file)
@@ -100,6 +100,7 @@ bool send_add_edge(struct meshlink_handle *mesh, struct connection_t *, const st
 bool send_del_edge(struct meshlink_handle *mesh, struct connection_t *, const struct edge_t *, int contradictions);
 bool send_req_key(struct meshlink_handle *mesh, struct node_t *);
 bool send_canonical_address(struct meshlink_handle *mesh, struct node_t *);
+bool send_raw_packet(struct meshlink_handle *mesh, struct connection_t *, const vpn_packet_t *);
 
 /* Request handlers  */
 
@@ -116,5 +117,6 @@ bool key_changed_h(struct meshlink_handle *mesh, struct connection_t *, const ch
 bool req_key_h(struct meshlink_handle *mesh, struct connection_t *, const char *);
 bool ans_key_h(struct meshlink_handle *mesh, struct connection_t *, const char *);
 bool tcppacket_h(struct meshlink_handle *mesh, struct connection_t *, const char *);
+bool raw_packet_h(struct meshlink_handle *mesh, struct connection_t *, const char *);
 
 #endif
index 7410ad13c8f5316b3d274ede08877e58f2e54050..6589543778697ce13c0e731c2e74c047396af2a0 100644 (file)
@@ -145,3 +145,16 @@ bool tcppacket_h(meshlink_handle_t *mesh, connection_t *c, const char *request)
        // This should never happen with MeshLink.
        return false;
 }
+
+bool send_raw_packet(meshlink_handle_t *mesh, connection_t *c, const vpn_packet_t *packet) {
+       size_t hdrsize = sizeof(meshlink_packethdr_t);
+       assert(packet->len >= hdrsize);
+       return send_request(mesh, c, NULL, "%d", PACKET) && send_meta(mesh, c, (const char *)packet->data + hdrsize, packet->len - hdrsize);
+}
+
+bool raw_packet_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
+       (void)mesh;
+       (void)request;
+       c->status.raw_packet = true;
+       return true;
+}
index ee36a9bfe4b17c8289d85053312a7d44ed2692c3..ea3a54340c8c9dbd1099ff0e066a810344308186 100644 (file)
@@ -69,7 +69,9 @@ void route(meshlink_handle_t *mesh, node_t *source, vpn_packet_t *packet) {
 
                logger(mesh, MESHLINK_DEBUG, "I received a packet for me with payload: %s\n", hex);
 
-               if(mesh->receive_cb) {
+               if(source->utcp) {
+                       channel_receive(mesh, (meshlink_node_t *)source, payload, len);
+               } else if(mesh->receive_cb) {
                        mesh->receive_cb(mesh, (meshlink_node_t *)source, payload, len);
                }