Fix critical VNC pipe bug and add debug logging

- Fix pipe handling in vnc.c: was writing to read end instead of write end
- Add separate read_fd/write_fd fields to vnc_session_t struct
- Add debug logging for VNC data exchange in websocket handler
- Add hex dump logging for VNC pipe communication

This resolves the 'Wrote -1 bytes to pipe' error that was preventing
VNC connections from working properly.
parent 79fa8426
......@@ -40,19 +40,29 @@ static void *read_pipe_output(void *arg) {
while (1) {
FD_ZERO(&readfds);
FD_SET(session->master_fd, &readfds);
FD_SET(session->read_fd, &readfds);
tv.tv_sec = 0;
tv.tv_usec = 100000; // 100ms timeout
int ret = select(session->master_fd + 1, &readfds, NULL, NULL, &tv);
int ret = select(session->read_fd + 1, &readfds, NULL, NULL, &tv);
if (ret < 0) break;
if (ret == 0) continue; // timeout
if (FD_ISSET(session->master_fd, &readfds)) {
ssize_t bytes_read = read(session->master_fd, buffer, sizeof(buffer));
if (FD_ISSET(session->read_fd, &readfds)) {
ssize_t bytes_read = read(session->read_fd, buffer, sizeof(buffer));
if (bytes_read <= 0) break;
if (session->debug_vnc) {
printf("VNC: Received %zd bytes from pipe\n", bytes_read);
// Debug: print first 20 bytes in hex
printf("VNC received data (first 20 bytes): ");
for (ssize_t i = 0; i < bytes_read && i < 20; i++) {
printf("%02x ", (unsigned char)buffer[i]);
}
printf("\n");
}
// Append to session output buffer
pthread_mutex_lock(&session->output_mutex);
if (session->output_used + bytes_read > session->output_size) {
......@@ -79,7 +89,7 @@ static void *read_pipe_output(void *arg) {
return NULL;
}
vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *client_id, const char *username) {
vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *client_id, const char *username, bool debug_vnc) {
vnc_session_t *session = calloc(1, sizeof(vnc_session_t));
if (!session) return NULL;
......@@ -104,6 +114,7 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli
}
session->output_size = 4096;
session->output_used = 0;
session->debug_vnc = debug_vnc;
pthread_mutex_init(&session->output_mutex, NULL);
// Create pipe for communication
......@@ -114,7 +125,8 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli
return NULL;
}
session->master_fd = pipefd[0]; // read end
session->read_fd = pipefd[0]; // read end
session->write_fd = pipefd[1]; // write end
// Build command: wsssht --pipe --wssshd-port 9898 vnc://{client_id}@mbetter.nexlab.net
char command[1024];
......@@ -143,8 +155,7 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli
_exit(1); // Should not reach here
}
// Parent process
close(pipefd[1]); // close write end
// Parent process keeps both ends: read_fd for reading from child, write_fd for writing to child
session->proc_pid = pid;
// Start output reading thread
......@@ -158,8 +169,11 @@ vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *cli
void vnc_free_session(vnc_session_t *session) {
if (!session) return;
if (session->master_fd >= 0) {
close(session->master_fd);
if (session->read_fd >= 0) {
close(session->read_fd);
}
if (session->write_fd >= 0) {
close(session->write_fd);
}
if (session->output_buffer) {
......@@ -171,14 +185,27 @@ void vnc_free_session(vnc_session_t *session) {
}
bool vnc_send_data(vnc_session_t *session, const char *data, size_t len) {
if (!session || session->master_fd < 0) return false;
if (!session || session->write_fd < 0) return false;
// Check if process is still running
if (waitpid(session->proc_pid, NULL, WNOHANG) > 0) {
return false;
}
ssize_t written = write(session->master_fd, data, len);
if (session->debug_vnc) {
printf("VNC: Sending %zu bytes to pipe\n", len);
// Debug: print first 20 bytes in hex
printf("VNC send data (first 20 bytes): ");
for (size_t i = 0; i < len && i < 20; i++) {
printf("%02x ", (unsigned char)data[i]);
}
printf("\n");
}
ssize_t written = write(session->write_fd, data, len);
if (session->debug_vnc) {
printf("VNC: Wrote %zd bytes to pipe\n", written);
}
return written > 0;
}
......
......@@ -29,15 +29,17 @@ typedef struct {
char client_id[256];
char username[50];
int proc_pid;
int master_fd; // pipe fd
int read_fd; // pipe read end
int write_fd; // pipe write end
bool active;
bool debug_vnc;
char *output_buffer;
size_t output_size;
size_t output_used;
pthread_mutex_t output_mutex;
} vnc_session_t;
vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *client_id, const char *username);
vnc_session_t *vnc_create_session(const wssshd_config_t *config, const char *client_id, const char *username, bool debug_vnc);
void vnc_free_session(vnc_session_t *session);
bool vnc_send_data(vnc_session_t *session, const char *data, size_t len);
char *vnc_get_output(vnc_session_t *session, size_t *len);
......
......@@ -321,7 +321,7 @@ static void *websocket_vnc_handler(void *arg) {
printf("[DEBUG] Launching wsssht for VNC client %s\n", ws_conn->client_id);
}
vnc_session_t *session = vnc_create_session(global_config, ws_conn->client_id, ws_conn->username);
vnc_session_t *session = vnc_create_session(global_config, ws_conn->client_id, ws_conn->username, global_config->debug_vnc);
if (!session) {
printf("Failed to create VNC session for client: %s\n", ws_conn->client_id);
ws_send_frame(ws_conn->ws_conn, WS_OPCODE_TEXT, "{\"error\":\"Failed to launch VNC session\"}", 40);
......@@ -366,6 +366,13 @@ static void *websocket_vnc_handler(void *arg) {
char *output = vnc_get_output(session, &output_len);
if (output && output_len > 0) {
printf("WebSocket sending %zu bytes of VNC output for request_id: %s\n", output_len, ws_conn->request_id);
if (global_config->debug_vnc) {
printf("VNC output data (first 20 bytes): ");
for (size_t i = 0; i < output_len && i < 20; i++) {
printf("%02x ", (unsigned char)output[i]);
}
printf("\n");
}
ws_send_frame(ws_conn->ws_conn, WS_OPCODE_BINARY, output, output_len);
free(output);
}
......@@ -379,6 +386,13 @@ static void *websocket_vnc_handler(void *arg) {
if (opcode == WS_OPCODE_BINARY && len > 0) {
// VNC input data
printf("WebSocket received %zu bytes of VNC input for request_id: %s\n", len, ws_conn->request_id);
if (global_config->debug_vnc) {
printf("VNC input data (first 20 bytes): ");
for (size_t i = 0; i < len && i < 20; i++) {
printf("%02x ", (unsigned char)((const char *)data)[i]);
}
printf("\n");
}
vnc_send_data(session, (const char *)data, len);
} else if (opcode == WS_OPCODE_CLOSE) {
// Connection closed
......
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