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
pthread_mutex_unlock(&tunnel_mutex);
} else {
// wsssh/wssshc: Send directly to target socket
if (debug) {
printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock);
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) {
// Skip if server version was already sent early
if (active_tunnel->server_version_sent && strstr(data, "SSH-2.0-OpenSSH_10.0p2 Debian-8")) {
if (debug) {
printf("[DEBUG] Failed to send %zu bytes to target socket %d: %s (errno=%d)\n",
data_len, target_sock, strerror(errno), errno);
printf("[DEBUG] Skipping duplicate server version send\n");
fflush(stdout);
}
// Check if this is a recoverable error
if (errno == EPIPE || errno == ECONNRESET) {
if (debug) {
printf("[DEBUG] SSH client disconnected, marking tunnel inactive\n");
fflush(stdout);
}
// If send fails due to disconnection, mark tunnel as inactive
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 (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) {
} else {
if (debug) {
printf("[DEBUG] Attempting to send %zu bytes to socket %d\n", data_len, target_sock);
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) {
printf("[DEBUG] Bad file descriptor - socket may have been closed by SSH client\n");
printf("[DEBUG - TOREMOVE] EBADF occurred, marking tunnel inactive\n");
printf("[DEBUG] Failed to send %zu bytes to target socket %d: %s (errno=%d)\n",
data_len, target_sock, strerror(errno), errno);
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);
// Check if this is a recoverable error
if (errno == EPIPE || errno == ECONNRESET) {
if (debug) {
printf("[DEBUG] SSH client disconnected, marking tunnel inactive\n");
fflush(stdout);
}
// If send fails due to disconnection, mark tunnel as inactive
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 (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
pthread_mutex_lock(&tunnel_mutex);
if (active_tunnel) {
active_tunnel->active = 0;
} 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);
}
pthread_mutex_unlock(&tunnel_mutex);
}
} 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);
}
fflush(stdout);
}
}
free(data);
......@@ -1062,6 +1070,7 @@ int setup_tunnel(const char *wssshd_host, int wssshd_port, const char *client_id
active_tunnel->active = 1;
active_tunnel->broken = 0;
active_tunnel->ssl = ssl;
active_tunnel->server_version_sent = 0;
// Start listening on local port
int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
......
......@@ -40,6 +40,7 @@ typedef struct {
SSL *ssl; // WebSocket SSL connection
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
int server_version_sent; // Flag to indicate if server version was sent early
} tunnel_t;
// 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