Add flag to prevent duplicate server version sends and fix syntax error

parent cf1fbef9
...@@ -600,74 +600,82 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id ...@@ -600,74 +600,82 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
pthread_mutex_unlock(&tunnel_mutex); pthread_mutex_unlock(&tunnel_mutex);
} else { } else {
// wsssh/wssshc: Send directly to target socket // wsssh/wssshc: Send directly to target socket
if (debug) { // Skip if server version was already sent early
printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock); if (active_tunnel->server_version_sent && strstr(data, "SSH-2.0-OpenSSH_10.0p2 Debian-8")) {
printf("[DEBUG - TOREMOVE] Target socket is %d\n", target_sock);
fflush(stdout);
}
ssize_t sent = send(target_sock, data, data_len, 0);
if (sent < 0) {
if (debug) { if (debug) {
printf("[DEBUG] Failed to send %zu bytes to target socket %d: %s (errno=%d)\n", printf("[DEBUG] Skipping duplicate server version send\n");
data_len, target_sock, strerror(errno), errno);
fflush(stdout); fflush(stdout);
} }
// Check if this is a recoverable error } else {
if (errno == EPIPE || errno == ECONNRESET) { if (debug) {
if (debug) { printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock);
printf("[DEBUG] SSH client disconnected, marking tunnel inactive\n"); printf("[DEBUG - TOREMOVE] Target socket is %d\n", target_sock);
fflush(stdout); fflush(stdout);
} }
// If send fails due to disconnection, mark tunnel as inactive ssize_t sent = send(target_sock, data, data_len, 0);
pthread_mutex_lock(&tunnel_mutex); if (sent < 0) {
if (active_tunnel) {
active_tunnel->active = 0;
active_tunnel->broken = 1;
// Send tunnel_close notification immediately
send_tunnel_close(active_tunnel->ssl, active_tunnel->request_id, debug);
}
pthread_mutex_unlock(&tunnel_mutex);
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (debug) {
printf("[DEBUG] Send would block, will retry later\n");
fflush(stdout);
}
// For non-blocking sockets, this is recoverable
// Don't mark tunnel as inactive
} else if (errno == EBADF) {
if (debug) { if (debug) {
printf("[DEBUG] Bad file descriptor - socket may have been closed by SSH client\n"); printf("[DEBUG] Failed to send %zu bytes to target socket %d: %s (errno=%d)\n",
printf("[DEBUG - TOREMOVE] EBADF occurred, marking tunnel inactive\n"); data_len, target_sock, strerror(errno), errno);
fflush(stdout); fflush(stdout);
} }
// EBADF indicates the socket is invalid - SSH client likely disconnected // Check if this is a recoverable error
pthread_mutex_lock(&tunnel_mutex); if (errno == EPIPE || errno == ECONNRESET) {
if (active_tunnel) { if (debug) {
active_tunnel->active = 0; printf("[DEBUG] SSH client disconnected, marking tunnel inactive\n");
active_tunnel->broken = 1; fflush(stdout);
// Send tunnel_close notification immediately }
send_tunnel_close(active_tunnel->ssl, active_tunnel->request_id, debug); // If send fails due to disconnection, mark tunnel as inactive
} pthread_mutex_lock(&tunnel_mutex);
pthread_mutex_unlock(&tunnel_mutex); if (active_tunnel) {
} else { active_tunnel->active = 0;
if (debug) { active_tunnel->broken = 1;
printf("[DEBUG] Unexpected send error, marking tunnel inactive\n"); // Send tunnel_close notification immediately
fflush(stdout); send_tunnel_close(active_tunnel->ssl, active_tunnel->request_id, debug);
}
pthread_mutex_unlock(&tunnel_mutex);
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (debug) {
printf("[DEBUG] Send would block, will retry later\n");
fflush(stdout);
}
// For non-blocking sockets, this is recoverable
// Don't mark tunnel as inactive
} else if (errno == EBADF) {
if (debug) {
printf("[DEBUG] Bad file descriptor - socket may have been closed by SSH client\n");
printf("[DEBUG - TOREMOVE] EBADF occurred, marking tunnel inactive\n");
fflush(stdout);
}
// EBADF indicates the socket is invalid - SSH client likely disconnected
pthread_mutex_lock(&tunnel_mutex);
if (active_tunnel) {
active_tunnel->active = 0;
active_tunnel->broken = 1;
// Send tunnel_close notification immediately
send_tunnel_close(active_tunnel->ssl, active_tunnel->request_id, debug);
}
pthread_mutex_unlock(&tunnel_mutex);
} else {
if (debug) {
printf("[DEBUG] Unexpected send error, marking tunnel inactive\n");
fflush(stdout);
}
// For other errors, mark tunnel as inactive
pthread_mutex_lock(&tunnel_mutex);
if (active_tunnel) {
active_tunnel->active = 0;
}
pthread_mutex_unlock(&tunnel_mutex);
} }
// For other errors, mark tunnel as inactive } else if (debug) {
pthread_mutex_lock(&tunnel_mutex); if ((size_t)sent != data_len) {
if (active_tunnel) { printf("[DEBUG] Partial send: sent %zd of %zu bytes to socket %d\n", sent, data_len, target_sock);
active_tunnel->active = 0; } else {
printf("[DEBUG] Successfully sent %zu bytes to socket %d\n", data_len, target_sock);
} }
pthread_mutex_unlock(&tunnel_mutex); fflush(stdout);
}
} else if (debug) {
if ((size_t)sent != data_len) {
printf("[DEBUG] Partial send: sent %zd of %zu bytes to socket %d\n", sent, data_len, target_sock);
} else {
printf("[DEBUG] Successfully sent %zu bytes to socket %d\n", data_len, target_sock);
} }
fflush(stdout);
} }
} }
free(data); free(data);
...@@ -1062,6 +1070,7 @@ int setup_tunnel(const char *wssshd_host, int wssshd_port, const char *client_id ...@@ -1062,6 +1070,7 @@ int setup_tunnel(const char *wssshd_host, int wssshd_port, const char *client_id
active_tunnel->active = 1; active_tunnel->active = 1;
active_tunnel->broken = 0; active_tunnel->broken = 0;
active_tunnel->ssl = ssl; active_tunnel->ssl = ssl;
active_tunnel->server_version_sent = 0;
// Start listening on local port // Start listening on local port
int listen_sock = socket(AF_INET, SOCK_STREAM, 0); int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
......
...@@ -40,6 +40,7 @@ typedef struct { ...@@ -40,6 +40,7 @@ typedef struct {
SSL *ssl; // WebSocket SSL connection SSL *ssl; // WebSocket SSL connection
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
} tunnel_t; } tunnel_t;
// Global variables // Global variables
......
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