]> git.meshlink.io Git - meshlink/commitdiff
Avoid allocating packet buffers unnecessarily.
authorGuus Sliepen <guus@meshlink.io>
Sun, 29 Mar 2020 22:04:29 +0000 (00:04 +0200)
committerGuus Sliepen <guus@meshlink.io>
Sun, 29 Mar 2020 22:04:29 +0000 (00:04 +0200)
Unless we have to queue a packet, we can avoid allocating and freeing
memory by keeping a permanently allocated packet buffer around.

src/meshlink.c
src/meshlink_internal.h
src/utcp

index 38ef57508b7e13540644bdababfc27f2d1042602..3242bc267d625a34686e06804cb4efa925fcd652 100644 (file)
@@ -24,6 +24,7 @@
 #include "ecdsagen.h"
 #include "logger.h"
 #include "meshlink_internal.h"
+#include "net.h"
 #include "netutl.h"
 #include "node.h"
 #include "submesh.h"
@@ -1456,6 +1457,7 @@ meshlink_handle_t *meshlink_open_ex(const meshlink_open_params_t *params) {
        mesh->submeshes = NULL;
        mesh->log_cb = global_log_cb;
        mesh->log_level = global_log_level;
+       mesh->packet = xmalloc(sizeof(vpn_packet_t));
 
        randomize(&mesh->prng_state, sizeof(mesh->prng_state));
 
@@ -1805,6 +1807,7 @@ void meshlink_close(meshlink_handle_t *mesh) {
        free(mesh->confbase);
        free(mesh->config_key);
        free(mesh->external_address_url);
+       free(mesh->packet);
        ecdsa_free(mesh->private_key);
 
        if(mesh->invitation_addresses) {
@@ -1962,12 +1965,12 @@ void meshlink_set_error_cb(struct meshlink_handle *mesh, meshlink_error_cb_t cb)
        pthread_mutex_unlock(&mesh->mutex);
 }
 
-static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
+static bool prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len, vpn_packet_t *packet) {
        meshlink_packethdr_t *hdr;
 
        if(len >= MAXSIZE - sizeof(*hdr)) {
                meshlink_errno = MESHLINK_EINVAL;
-               return NULL;
+               return false;
        }
 
        node_t *n = (node_t *)destination;
@@ -1975,17 +1978,10 @@ static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *de
        if(n->status.blacklisted) {
                logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name);
                meshlink_errno = MESHLINK_EBLACKLISTED;
-               return NULL;
+               return false;
        }
 
        // Prepare the packet
-       vpn_packet_t *packet = malloc(sizeof(*packet));
-
-       if(!packet) {
-               meshlink_errno = MESHLINK_ENOMEM;
-               return NULL;
-       }
-
        packet->probe = false;
        packet->tcp = false;
        packet->len = len + sizeof(*hdr);
@@ -1999,7 +1995,7 @@ static vpn_packet_t *prepare_packet(meshlink_handle_t *mesh, meshlink_node_t *de
 
        memcpy(packet->data + sizeof(*hdr), data, len);
 
-       return packet;
+       return true;
 }
 
 static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
@@ -2009,15 +2005,12 @@ static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *de
        assert(len);
 
        // Prepare the packet
-       vpn_packet_t *packet = prepare_packet(mesh, destination, data, len);
-
-       if(!packet) {
+       if(!prepare_packet(mesh, destination, data, len, mesh->packet)) {
                return false;
        }
 
        // Send it immediately
-       route(mesh, mesh->self, packet);
-       free(packet);
+       route(mesh, mesh->self, mesh->packet);
 
        return true;
 }
@@ -2039,12 +2032,17 @@ bool meshlink_send(meshlink_handle_t *mesh, meshlink_node_t *destination, const
        }
 
        // Prepare the packet
-       vpn_packet_t *packet = prepare_packet(mesh, destination, data, len);
+       vpn_packet_t *packet = malloc(sizeof(*packet));
 
        if(!packet) {
+               meshlink_errno = MESHLINK_ENOMEM;
                return false;
        }
 
+       if(!prepare_packet(mesh, destination, data, len, packet)) {
+               free(packet);
+       }
+
        // Queue it
        if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
                free(packet);
index f0ffed8edb0b5436d41aefd89ffa8278f7b7884a..f324c10645b556cc20760b3d9227691341e05a0b 100644 (file)
@@ -99,6 +99,7 @@ struct meshlink_handle {
        struct node_t *self;
        meshlink_log_cb_t log_cb;
        meshlink_log_level_t log_level;
+       void *packet;
 
        // The most important network-related members come first
        int reachable;
index 0c3abf9e3538c482639ed32b0e85104495db5b4f..fa38b03a6d236619d27df086f46c379476026242 160000 (submodule)
--- a/src/utcp
+++ b/src/utcp
@@ -1 +1 @@
-Subproject commit 0c3abf9e3538c482639ed32b0e85104495db5b4f
+Subproject commit fa38b03a6d236619d27df086f46c379476026242