]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Fix potential incorrect destruction of channels.
[meshlink] / src / meshlink.c
index 63feee2c88420b6670251eb697e3fe0aac1f6ce5..fe11af2cc44966a309afea3e224ca9935d2b2229 100644 (file)
@@ -3399,6 +3399,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
 
        if(!buflen) {
                logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
+               free(buf);
                meshlink_errno = MESHLINK_EPEER;
                return false;
        }
@@ -3408,6 +3409,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
 
        if(!count) {
                logger(mesh, MESHLINK_DEBUG, "Invalid data\n");
+               free(buf);
                meshlink_errno = MESHLINK_EPEER;
                return false;
        }
@@ -3464,6 +3466,7 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
 
                if(!node_write_config(mesh, n, true)) {
                        free_node(n);
+                       free(buf);
                        return false;
                }
 
@@ -3514,7 +3517,7 @@ static bool blacklist(meshlink_handle_t *mesh, node_t *n) {
                }
        }
 
-       utcp_abort_all_connections(n->utcp);
+       utcp_reset_all_connections(n->utcp);
 
        n->mtu = 0;
        n->minmtu = 0;
@@ -4252,6 +4255,32 @@ void meshlink_channel_close(meshlink_handle_t *mesh, meshlink_channel_t *channel
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_channel_abort(meshlink_handle_t *mesh, meshlink_channel_t *channel) {
+       if(!mesh || !channel) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       if(pthread_mutex_lock(&mesh->mutex) != 0) {
+               abort();
+       }
+
+       if(channel->c) {
+               utcp_abort(channel->c);
+               channel->c = NULL;
+
+               /* Clean up any outstanding AIO buffers. */
+               aio_abort(mesh, channel, &channel->aio_send);
+               aio_abort(mesh, channel, &channel->aio_receive);
+       }
+
+       if(!channel->in_callback) {
+               free(channel);
+       }
+
+       pthread_mutex_unlock(&mesh->mutex);
+}
+
 ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len) {
        if(!mesh || !channel) {
                meshlink_errno = MESHLINK_EINVAL;