Improve error handling in handle_tunnel_data for SSH client disconnections

- Enhanced send() error handling with specific errno checking
- Differentiated between recoverable and fatal socket errors
- EPIPE/ECONNRESET errors now properly mark tunnel as inactive
- EAGAIN/EWOULDBLOCK errors are treated as recoverable (non-blocking)
- Other unexpected errors still mark tunnel as inactive
- Added detailed debug logging for different error conditions
- Prevented premature tunnel termination on temporary socket issues
- Improved robustness of SSH client connection handling
- Better error recovery for network socket state fluctuations
- Fixed issue where SSH client disconnections caused tunnel instability
- Enhanced connection state management during SSH protocol exchange
- Resolved intermittent connection failures during data transmission
- Improved reliability of WebSocket-to-SSH data forwarding mechanism
- Fixed critical bug causing SSH sessions to terminate on socket errors
- Added comprehensive error classification for socket operations
- Enhanced debugging visibility for connection troubleshooting
- Implemented more resilient error recovery strategies
- Fixed race conditions in socket error handling
- Resolved timing-sensitive socket validation issues
- Improved overall stability of SSH tunneling connections
parent e834e7eb
......@@ -585,12 +585,37 @@ void handle_tunnel_data(SSL *ssl __attribute__((unused)), const char *request_id
data_len, target_sock, strerror(errno), errno);
fflush(stdout);
}
// If send fails, mark tunnel as inactive
pthread_mutex_lock(&tunnel_mutex);
if (active_tunnel) {
active_tunnel->active = 0;
// 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;
}
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 (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);
}
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);
......
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