Fix segmentation fault when closing concurrent tunnels

- Add forward_thread field to tunnel_t structure for thread synchronization
- Remove pthread_detach() to allow proper thread joining during cleanup
- Add pthread_join() in cleanup to wait for forwarding thread completion
- Prevent race conditions between cleanup and forwarding threads
- Ensure tunnel resources are not freed while threads are still using them
- Fix concurrent connection cleanup issues in wsssht daemon mode
parent 5227651d
...@@ -652,6 +652,7 @@ void *handle_connection(void *arg) { ...@@ -652,6 +652,7 @@ void *handle_connection(void *arg) {
new_tunnel->outgoing_buffer = NULL; new_tunnel->outgoing_buffer = NULL;
new_tunnel->incoming_buffer = frame_buffer_init(); new_tunnel->incoming_buffer = frame_buffer_init();
new_tunnel->server_version_sent = 0; new_tunnel->server_version_sent = 0;
new_tunnel->forward_thread = 0;
if (!new_tunnel->incoming_buffer) { if (!new_tunnel->incoming_buffer) {
perror("Failed to initialize incoming buffer"); perror("Failed to initialize incoming buffer");
...@@ -858,8 +859,16 @@ void *handle_connection(void *arg) { ...@@ -858,8 +859,16 @@ void *handle_connection(void *arg) {
thread_args->debug = config->debug; thread_args->debug = config->debug;
pthread_t forward_thread; pthread_t forward_thread;
pthread_create(&forward_thread, NULL, forward_tcp_to_ws, thread_args); if (pthread_create(&forward_thread, NULL, forward_tcp_to_ws, thread_args) != 0) {
pthread_detach(forward_thread); perror("Failed to create forwarding thread");
free(thread_args);
close(new_tunnel->local_sock);
frame_buffer_free(new_tunnel->incoming_buffer);
free(new_tunnel);
return NULL;
}
// Store the thread ID for cleanup
new_tunnel->forward_thread = forward_thread;
// Main tunnel loop - handle WebSocket messages // Main tunnel loop - handle WebSocket messages
char ws_buffer[BUFFER_SIZE]; char ws_buffer[BUFFER_SIZE];
...@@ -1245,6 +1254,19 @@ cleanup_and_exit: ...@@ -1245,6 +1254,19 @@ cleanup_and_exit:
fflush(stdout); fflush(stdout);
} }
// Wait for forwarding thread to finish
if (new_tunnel && new_tunnel->forward_thread) {
if (config->debug) {
printf("[DEBUG - Tunnel] [Thread %ld] Waiting for forwarding thread to finish\n", pthread_self());
fflush(stdout);
}
pthread_join(new_tunnel->forward_thread, NULL);
if (config->debug) {
printf("[DEBUG - Tunnel] [Thread %ld] Forwarding thread finished\n", pthread_self());
fflush(stdout);
}
}
// Cleanup // Cleanup
if (new_tunnel) { if (new_tunnel) {
if (new_tunnel->local_sock >= 0) { if (new_tunnel->local_sock >= 0) {
......
...@@ -41,6 +41,7 @@ typedef struct { ...@@ -41,6 +41,7 @@ typedef struct {
frame_buffer_t *outgoing_buffer; // Buffer for data to send to local socket (wsscp only) frame_buffer_t *outgoing_buffer; // Buffer for data to send to local socket (wsscp only)
frame_buffer_t *incoming_buffer; // Buffer for incoming data before connection is established frame_buffer_t *incoming_buffer; // Buffer for incoming data before connection is established
int server_version_sent; // Flag to indicate if server version was sent early int server_version_sent; // Flag to indicate if server version was sent early
pthread_t forward_thread; // Thread ID for the forwarding thread
} tunnel_t; } tunnel_t;
// Thread arguments // Thread arguments
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment