Unless we have to queue a packet, we can avoid allocating and freeing
memory by keeping a permanently allocated packet buffer around.
#include "ecdsagen.h"
#include "logger.h"
#include "meshlink_internal.h"
#include "ecdsagen.h"
#include "logger.h"
#include "meshlink_internal.h"
#include "netutl.h"
#include "node.h"
#include "submesh.h"
#include "netutl.h"
#include "node.h"
#include "submesh.h"
mesh->submeshes = NULL;
mesh->log_cb = global_log_cb;
mesh->log_level = global_log_level;
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));
randomize(&mesh->prng_state, sizeof(mesh->prng_state));
free(mesh->confbase);
free(mesh->config_key);
free(mesh->external_address_url);
free(mesh->confbase);
free(mesh->config_key);
free(mesh->external_address_url);
ecdsa_free(mesh->private_key);
if(mesh->invitation_addresses) {
ecdsa_free(mesh->private_key);
if(mesh->invitation_addresses) {
pthread_mutex_unlock(&mesh->mutex);
}
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;
meshlink_packethdr_t *hdr;
if(len >= MAXSIZE - sizeof(*hdr)) {
meshlink_errno = MESHLINK_EINVAL;
}
node_t *n = (node_t *)destination;
}
node_t *n = (node_t *)destination;
if(n->status.blacklisted) {
logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name);
meshlink_errno = MESHLINK_EBLACKLISTED;
if(n->status.blacklisted) {
logger(mesh, MESHLINK_ERROR, "Node %s blacklisted, dropping packet\n", n->name);
meshlink_errno = MESHLINK_EBLACKLISTED;
- 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);
packet->probe = false;
packet->tcp = false;
packet->len = len + sizeof(*hdr);
memcpy(packet->data + sizeof(*hdr), data, len);
memcpy(packet->data + sizeof(*hdr), data, len);
}
static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
}
static bool meshlink_send_immediate(meshlink_handle_t *mesh, meshlink_node_t *destination, const void *data, size_t len) {
assert(len);
// Prepare the packet
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
return false;
}
// Send it immediately
- route(mesh, mesh->self, packet);
- free(packet);
+ route(mesh, mesh->self, mesh->packet);
- vpn_packet_t *packet = prepare_packet(mesh, destination, data, len);
+ vpn_packet_t *packet = malloc(sizeof(*packet));
+ meshlink_errno = MESHLINK_ENOMEM;
+ if(!prepare_packet(mesh, destination, data, len, packet)) {
+ free(packet);
+ }
+
// Queue it
if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
free(packet);
// Queue it
if(!meshlink_queue_push(&mesh->outpacketqueue, packet)) {
free(packet);
struct node_t *self;
meshlink_log_cb_t log_cb;
meshlink_log_level_t log_level;
struct node_t *self;
meshlink_log_cb_t log_cb;
meshlink_log_level_t log_level;
// The most important network-related members come first
int reachable;
// The most important network-related members come first
int reachable;
-Subproject commit 0c3abf9e3538c482639ed32b0e85104495db5b4f
+Subproject commit fa38b03a6d236619d27df086f46c379476026242