Fix VNC WebSocket connection hanging after initial RFB handshake

- Implement bidirectional pipe communication for VNC sessions
- Replace single pipe with separate stdin/stdout pipes
- Fix child process redirection to properly handle both input and output
- Add enhanced debug logging for VNC data flow
- Update resource cleanup in vnc_free_session()

This resolves the issue where VNC connections would hang after exchanging
the first 12 bytes (RFB protocol version strings) because input from
noVNC WebSocket wasn't reaching the wsssht process.
parent 8545d971
...@@ -117,45 +117,59 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli ...@@ -117,45 +117,59 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli
session->debug_vnc = debug_vnc; session->debug_vnc = debug_vnc;
pthread_mutex_init(&session->output_mutex, NULL); pthread_mutex_init(&session->output_mutex, NULL);
// Create pipe for communication // Create pipes for bidirectional communication
int pipefd[2]; int stdout_pipe[2]; // parent reads from child stdout
if (pipe(pipefd) < 0) { int stdin_pipe[2]; // parent writes to child stdin
if (pipe(stdout_pipe) < 0 || pipe(stdin_pipe) < 0) {
if (stdout_pipe[0] >= 0) close(stdout_pipe[0]);
if (stdout_pipe[1] >= 0) close(stdout_pipe[1]);
if (stdin_pipe[0] >= 0) close(stdin_pipe[0]);
if (stdin_pipe[1] >= 0) close(stdin_pipe[1]);
free(session->output_buffer); free(session->output_buffer);
free(session); free(session);
return NULL; return NULL;
} }
session->read_fd = pipefd[0]; // read end session->read_fd = stdout_pipe[0]; // parent reads from child stdout
session->write_fd = pipefd[1]; // write end session->write_fd = stdin_pipe[1]; // parent writes to child stdin
// Build command: wsssht --pipe --wssshd-port 9898 vnc://{client_id}@mbetter.nexlab.net // Build command: wsssht --pipe --wssshd-port 9898 vnc://{client_id}@mbetter.nexlab.net
char command[1024]; char command[1024];
snprintf(command, sizeof(command), snprintf(command, sizeof(command),
"wsssht --pipe --wssshd-port %d vnc://%s@%s", "wsssht --pipe --wssshd-port %d vnc://%s@%s",
config->port, client_id, config->domain); config->port, client_id, config->domain);
// Fork and execute // Fork and execute
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) { if (pid < 0) {
close(pipefd[0]); close(stdout_pipe[0]);
close(pipefd[1]); close(stdout_pipe[1]);
close(stdin_pipe[0]);
close(stdin_pipe[1]);
free(session->output_buffer); free(session->output_buffer);
free(session); free(session);
return NULL; return NULL;
} }
if (pid == 0) { // Child process if (pid == 0) { // Child process
// Redirect stdout to pipe // Redirect stdout to stdout_pipe
dup2(pipefd[1], 1); dup2(stdout_pipe[1], 1);
close(pipefd[0]); // Redirect stdin from stdin_pipe
close(pipefd[1]); dup2(stdin_pipe[0], 0);
close(stdout_pipe[0]);
close(stdout_pipe[1]);
close(stdin_pipe[0]);
close(stdin_pipe[1]);
// Execute command // Execute command
execl("/bin/sh", "sh", "-c", command, NULL); execl("/bin/sh", "sh", "-c", command, NULL);
_exit(1); // Should not reach here _exit(1); // Should not reach here
} }
// Parent process keeps both ends: read_fd for reading from child, write_fd for writing to child // Parent process
close(stdout_pipe[1]); // close write end of stdout pipe
close(stdin_pipe[0]); // close read end of stdin pipe
session->proc_pid = pid; session->proc_pid = pid;
// Start output reading thread // Start output reading thread
...@@ -171,13 +185,16 @@ void vnc_free_session(vnc_session_t *session) { ...@@ -171,13 +185,16 @@ void vnc_free_session(vnc_session_t *session) {
if (session->read_fd >= 0) { if (session->read_fd >= 0) {
close(session->read_fd); close(session->read_fd);
session->read_fd = -1;
} }
if (session->write_fd >= 0) { if (session->write_fd >= 0) {
close(session->write_fd); close(session->write_fd);
session->write_fd = -1;
} }
if (session->output_buffer) { if (session->output_buffer) {
free(session->output_buffer); free(session->output_buffer);
session->output_buffer = NULL;
} }
pthread_mutex_destroy(&session->output_mutex); pthread_mutex_destroy(&session->output_mutex);
......
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