]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Implement MESHLINK_CHANNEL_FRAMED.
[meshlink] / src / meshlink.c
index 14ff7155888c96a04ff33945dfd71dcf9e4481dd..89680ef79a9cedc3e1f5be062050d6b47f8bfd6c 100644 (file)
@@ -1659,7 +1659,12 @@ bool meshlink_start(meshlink_handle_t *mesh) {
 
        event_loop_start(&mesh->loop);
 
-       if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) {
+       // Ensure we have a decent amount of stack space. Musl's default of 80 kB is too small.
+       pthread_attr_t attr;
+       pthread_attr_init(&attr);
+       pthread_attr_setstacksize(&attr, 1024 * 1024);
+
+       if(pthread_create(&mesh->thread, &attr, meshlink_main_loop, mesh) != 0) {
                logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
                memset(&mesh->thread, 0, sizeof(mesh)->thread);
                meshlink_errno = MESHLINK_EINTERNAL;
@@ -3675,6 +3680,11 @@ static void channel_poll(struct utcp_connection *connection, size_t len) {
                if(aio->data) {
                        sent = utcp_send(connection, (char *)aio->data + aio->done, todo);
                } else {
+                       /* Limit the amount we read at once to avoid stack overflows */
+                       if(todo > 65536) {
+                               todo = 65536;
+                       }
+
                        char buf[todo];
                        ssize_t result = read(aio->fd, buf, todo);
 
@@ -3896,11 +3906,7 @@ ssize_t meshlink_channel_send(meshlink_handle_t *mesh, meshlink_channel_t *chann
                return -1;
        }
 
-       if(!len) {
-               return 0;
-       }
-
-       if(!data) {
+       if(len && !data) {
                meshlink_errno = MESHLINK_EINVAL;
                return -1;
        }
@@ -4135,6 +4141,27 @@ void meshlink_set_node_channel_timeout(meshlink_handle_t *mesh, meshlink_node_t
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_set_node_flush_timeout(meshlink_handle_t *mesh, meshlink_node_t *node, int timeout) {
+       if(!mesh || !node) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       node_t *n = (node_t *)node;
+
+       pthread_mutex_lock(&mesh->mutex);
+
+       if(!n->utcp) {
+               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);
+       }
+
+       utcp_set_flush_timeout(n->utcp, timeout);
+
+       pthread_mutex_unlock(&mesh->mutex);
+}
+
 void update_node_status(meshlink_handle_t *mesh, node_t *n) {
        if(n->status.reachable && mesh->channel_accept_cb && !n->utcp) {
                n->utcp = utcp_init(channel_accept, channel_pre_accept, channel_send, n);