Add extensive debug logging for control channel messages and enhance script mode

- Add debug logging for all control channel messages in wssshd and wssshc
  when --debug flag is enabled, showing full JSON content of received and sent messages
- Fix data forwarding issue in wsssht script mode
- Suppress data channel message output in wsssht script mode for cleaner output
- Enhance script_started message in wsssht script mode to include tunnel_host, tunnel_port, and service fields
- Remove obsolete test_bridge_interactive.sh file

Control channel messages now logged include: register, registered, registration_error,
tunnel_request, tunnel_ack, tunnel_close, tunnel_error for both server and client.
parent 9ae67412
#!/bin/bash
# WebSocket SSH Tunnel - Interactive Bridge Mode Test
# This script provides an interactive way to test wsssht bridge mode
# allowing manual JSON command input and response monitoring
set -e
# Configuration
WSSSHT="./wssshtools/wsssht" # Path to wsssht binary
CLIENT_ID="${CLIENT_ID:-testclient}"
WSSSHD_HOST="${WSSSHD_HOST:-mbetter.nexlab.net}"
WSSSHD_PORT="${WSSSHD_PORT:-9898}"
DEBUG="${DEBUG:-0}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_command() {
echo -e "${CYAN}[COMMAND]${NC} $1"
}
log_response() {
echo -e "${PURPLE}[RESPONSE]${NC} $1"
}
# Function to show available commands
show_commands() {
cat << EOF
Available JSON Commands for Bridge Mode:
1. Status Check:
{"command":"status","timestamp":\$(date +%s)}
2. Quit/Exit:
{"command":"quit","timestamp":\$(date +%s)}
{"command":"exit","timestamp":\$(date +%s)}
3. Custom Command (replace 'your_command' with actual command):
{"command":"your_command","timestamp":\$(date +%s),"data":"optional_data"}
4. Ping Command:
{"command":"ping","timestamp":\$(date +%s)}
5. Help Command:
{"command":"help","timestamp":\$(date +%s)}
Tunnel Control Channel Messages (received from server):
- tunnel_data: Data received from the server
- tunnel_response: Response to tunnel requests
- tunnel_close: Tunnel closure notification
- websocket_message: Other WebSocket messages
- websocket_close: WebSocket connection closed
Examples of expected responses:
{"type":"tunnel_data","message":"...","timestamp":1234567890}
{"type":"tunnel_response","message":"...","timestamp":1234567890}
{"type":"tunnel_close","message":"...","timestamp":1234567890}
{"type":"websocket_close","timestamp":1234567890}
EOF
}
# Function to start bridge mode
start_bridge() {
log_info "Starting wsssht in bridge mode..."
log_info "Client ID: $CLIENT_ID"
log_info "WSSSHD Host: $WSSSHD_HOST"
log_info "WSSSHD Port: $WSSSHD_PORT"
# Build command arguments
local cmd_args="--bridge --clientid $CLIENT_ID --wssshd-host $WSSSHD_HOST --wssshd-port $WSSSHD_PORT"
if [ "$DEBUG" = "1" ]; then
cmd_args="$cmd_args --debug"
fi
log_command "Command: $WSSSHT $cmd_args"
# Start wsssht in background
$WSSSHT $cmd_args &
WSSSHT_PID=$!
log_success "wsssht started with PID: $WSSSHT_PID"
log_info "Waiting for bridge mode to initialize..."
# Give it time to start
sleep 3
# Check if process is still running
if ! kill -0 $WSSSHT_PID 2>/dev/null; then
log_error "wsssht process failed to start or exited early"
return 1
fi
log_success "Bridge mode appears to be running"
}
# Function to send JSON command
send_json_command() {
local json_command="$1"
if [ -z "$json_command" ]; then
log_warning "Empty command, skipping"
return
fi
log_command "Sending: $json_command"
# Send command to wsssht's stdin
echo "$json_command" > /proc/$WSSSHT_PID/fd/0 2>/dev/null || {
log_error "Failed to send command to wsssht (PID: $WSSSHT_PID)"
log_error "Process may have exited"
return 1
}
log_success "Command sent successfully"
}
# Function to monitor responses
monitor_responses() {
log_info "Monitoring responses from wsssht..."
log_info "Press Ctrl+C to stop monitoring"
# Monitor process output
while kill -0 $WSSSHT_PID 2>/dev/null; do
# Try to read from process stdout
if [ -f /proc/$WSSSHT_PID/fd/1 ]; then
local line
if read -t 1 line < /proc/$WSSSHT_PID/fd/1 2>/dev/null; then
if [ -n "$line" ]; then
log_response "$line"
fi
fi
fi
sleep 0.1
done
log_info "wsssht process has exited"
}
# Function to cleanup
cleanup() {
log_info "Cleaning up..."
if [ -n "$WSSSHT_PID" ] && kill -0 $WSSSHT_PID 2>/dev/null; then
log_info "Terminating wsssht process (PID: $WSSSHT_PID)"
kill $WSSSHT_PID 2>/dev/null || true
wait $WSSSHT_PID 2>/dev/null || true
fi
log_success "Cleanup completed"
}
# Function to show usage
show_usage() {
cat << EOF
WebSocket SSH Tunnel - Interactive Bridge Mode Test
Usage: $0 [OPTIONS] [COMMAND]
Options:
-c, --client-id ID Client ID for the tunnel (default: testclient)
-h, --host HOST wssshd server hostname (default: mbetter.nexlab.net)
-p, --port PORT wssshd server port (default: 9898)
-d, --debug Enable debug output
--help Show this help message
Commands:
start Start bridge mode and enter interactive mode
status Send status command
quit Send quit command
monitor Monitor responses only
commands Show available JSON commands
Environment Variables:
CLIENT_ID Client ID (overrides -c)
WSSSHD_HOST wssshd hostname (overrides -h)
WSSSHD_PORT wssshd port (overrides -p)
DEBUG Enable debug (set to 1)
Examples:
$0 start
$0 --client-id myclient --host example.com start
$0 status
$0 commands
Interactive Mode:
Run '$0 start' to enter interactive mode where you can:
- Type JSON commands to send to wsssht
- See responses in real-time
- Use 'quit' or 'exit' to stop
- Use 'help' to see available commands
EOF
}
# Function for interactive mode
interactive_mode() {
log_info "Entering interactive mode..."
log_info "Type JSON commands to send to wsssht, or 'help' for commands, 'quit' to exit"
while true; do
echo -n "> "
read -r input
case "$input" in
"")
continue
;;
"quit"|"exit")
log_info "Exiting interactive mode"
break
;;
"help"|"commands")
show_commands
;;
"status")
send_json_command "{\"command\":\"status\",\"timestamp\":$(date +%s)}"
;;
"ping")
send_json_command "{\"command\":\"ping\",\"timestamp\":$(date +%s)}"
;;
*)
# Try to send as JSON command
if echo "$input" | jq . >/dev/null 2>&1; then
send_json_command "$input"
else
log_warning "Invalid JSON or unknown command: $input"
log_info "Type 'help' for available commands"
fi
;;
esac
done
}
# Parse command line arguments
COMMAND=""
while [[ $# -gt 0 ]]; do
case $1 in
-c|--client-id)
CLIENT_ID="$2"
shift 2
;;
-h|--host)
WSSSHD_HOST="$2"
shift 2
;;
-p|--port)
WSSSHD_PORT="$2"
shift 2
;;
-d|--debug)
DEBUG=1
shift
;;
--help)
show_usage
exit 0
;;
start|status|quit|monitor|commands)
COMMAND="$1"
shift
;;
*)
log_error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Check if wsssht binary exists
if [ ! -x "$WSSSHT" ]; then
log_error "wsssht binary not found at: $WSSSHT"
log_error "Please build wsssht first or update WSSSHT path in this script"
exit 1
fi
# Set up cleanup trap
trap cleanup EXIT INT TERM
log_info "WebSocket SSH Tunnel - Interactive Bridge Mode Test"
log_info "==================================================="
# Handle commands
case "$COMMAND" in
"start")
if start_bridge; then
interactive_mode
fi
;;
"status")
if start_bridge; then
send_json_command "{\"command\":\"status\",\"timestamp\":$(date +%s)}"
sleep 2
fi
;;
"quit")
if start_bridge; then
send_json_command "{\"command\":\"quit\",\"timestamp\":$(date +%s)}"
sleep 2
fi
;;
"monitor")
if start_bridge; then
monitor_responses
fi
;;
"commands")
show_commands
;;
*)
log_info "No command specified, showing usage..."
echo
show_usage
;;
esac
log_success "Test script completed!"
\ No newline at end of file
......@@ -187,7 +187,6 @@ async def run_server():
args = load_config()
# Set global variables
global debug, server_password, shutdown_event
debug = args.debug
server_password = args.password
......@@ -207,13 +206,13 @@ async def run_server():
ssl_context = setup_ssl_context()
# Start WebSocket server
ws_server = await websockets.serve(partial(handle_websocket, server_password=server_password), args.host, args.port, ssl=ssl_context)
ws_server = await websockets.serve(partial(handle_websocket, server_password=server_password, debug_flag=debug), args.host, args.port, ssl=ssl_context)
print(f"WebSocket SSH Daemon running on {args.host}:{args.port}")
print("Press Ctrl+C to stop the server")
# Start cleanup task
cleanup_coro = asyncio.create_task(cleanup_task())
cleanup_coro = asyncio.create_task(cleanup_task(debug))
# Start web interface if specified
flask_thread = None
......
......@@ -39,7 +39,7 @@ def cleanup_expired_clients():
if client_info['status'] == 'disconnected':
if current_time - client_info['last_seen'] > 30:
expired_clients.append(client_id)
if debug: print(f"[DEBUG] [WebSocket] Client {client_id} expired and removed")
if debug_flag: print(f"[DEBUG] [WebSocket] Client {client_id} expired and removed")
for client_id in expired_clients:
del clients[client_id]
......@@ -47,7 +47,7 @@ def cleanup_expired_clients():
def print_status():
"""Print minimal status information when not in debug mode"""
if debug:
if debug_flag:
return
uptime = time.time() - start_time
......@@ -65,14 +65,15 @@ def print_status():
f"Tunnels: {active_tunnels_count}/{total_tunnels} active")
async def handle_websocket(websocket, path=None, *, server_password=None):
async def handle_websocket(websocket, path=None, *, server_password=None, debug_flag=None):
"""Handle WebSocket connections from clients"""
print(f"[DEBUG] New WebSocket connection established from {websocket.remote_address}")
if debug_flag:
print(f"[DEBUG] New WebSocket connection established from {websocket.remote_address}")
try:
while True:
# Check for shutdown signal before each message
if shutdown_event and shutdown_event.is_set():
if debug: print("[DEBUG] Shutdown event detected in WebSocket handler")
if debug_flag: print("[DEBUG] Shutdown event detected in WebSocket handler")
break
try:
......@@ -82,14 +83,14 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
break
# Process the message (rest of the original logic)
# Log debug info for all control channel messages when debug is enabled
# Log debug info for control channel messages when debug is enabled (excluding data channel messages)
try:
data = json.loads(message)
msg_type = data.get('type', 'unknown')
if debug:
if debug and msg_type not in ('tunnel_data', 'tunnel_response'):
print(f"[DEBUG] [WebSocket] Received {msg_type} message: {message}")
except json.JSONDecodeError as e:
if debug: print(f"[DEBUG] [WebSocket] Invalid JSON received: {e}")
if debug_flag: print(f"[DEBUG] [WebSocket] Invalid JSON received: {e}")
continue
if data.get('type') == 'register':
......@@ -107,7 +108,7 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
was_disconnected = False
if client_id in clients and clients[client_id]['status'] == 'disconnected':
was_disconnected = True
if debug: print(f"[DEBUG] [WebSocket] Client {client_id} reconnecting (was disconnected)")
if debug_flag: print(f"[DEBUG] [WebSocket] Client {client_id} reconnecting (was disconnected)")
clients[client_id] = {
'websocket': websocket,
......@@ -130,18 +131,18 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
print(f"Client {client_id} registered")
try:
response_msg = REGISTERED_MSG % client_id
if debug: print(f"[DEBUG] [WebSocket] Sending registration response: {response_msg}")
if debug_flag: print(f"[DEBUG] [WebSocket] Sending registration response: {response_msg}")
await websocket.send(response_msg)
except Exception:
if debug: print(f"[DEBUG] [WebSocket] Failed to send registration response to {client_id}")
if debug_flag: print(f"[DEBUG] [WebSocket] Failed to send registration response to {client_id}")
else:
if debug: print(f"[DEBUG] [WebSocket] Client {client_id} registration failed: invalid password")
if debug_flag: print(f"[DEBUG] [WebSocket] Client {client_id} registration failed: invalid password")
try:
error_msg = REGISTRATION_ERROR_MSG % "Invalid password"
if debug: print(f"[DEBUG] [WebSocket] Sending registration error: {error_msg}")
if debug_flag: print(f"[DEBUG] [WebSocket] Sending registration error: {error_msg}")
await websocket.send(error_msg)
except Exception:
if debug: print(f"[DEBUG] [WebSocket] Failed to send registration error to {client_id}")
if debug_flag: print(f"[DEBUG] [WebSocket] Failed to send registration error to {client_id}")
elif data.get('type') == 'tunnel_request':
client_id = data['client_id']
request_id = data['request_id']
......@@ -183,7 +184,7 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
try:
request_msg = TUNNEL_REQUEST_MSG % request_id
ack_msg = TUNNEL_ACK_MSG % request_id
if debug:
if debug_flag:
print(f"[DEBUG] [WebSocket] Sending tunnel request to client: {request_msg}")
print(f"[DEBUG] [WebSocket] Sending tunnel ack to wsssh: {ack_msg}")
await client_info['websocket'].send(request_msg)
......@@ -197,14 +198,14 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
# Send error response for tunnel request failures
try:
error_msg = TUNNEL_ERROR_MSG % (request_id, "Failed to forward request")
if debug: print(f"[DEBUG] [WebSocket] Sending tunnel error: {error_msg}")
if debug_flag: print(f"[DEBUG] [WebSocket] Sending tunnel error: {error_msg}")
await websocket.send(error_msg)
except Exception:
pass # Silent failure if even error response fails
else:
try:
error_msg = TUNNEL_ERROR_MSG % (request_id, "Client not registered or disconnected")
if debug: print(f"[DEBUG] [WebSocket] Sending tunnel error: {error_msg}")
if debug_flag: print(f"[DEBUG] [WebSocket] Sending tunnel error: {error_msg}")
await websocket.send(error_msg)
except Exception:
pass # Silent failure for error responses
......@@ -246,7 +247,7 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
if client_info and client_info['status'] == 'active':
try:
close_msg = TUNNEL_CLOSE_MSG % request_id
if debug: print(f"[DEBUG] [WebSocket] Sending tunnel close to client: {close_msg}")
if debug_flag: print(f"[DEBUG] [WebSocket] Sending tunnel close to client: {close_msg}")
await tunnel.client_ws.send(close_msg)
except Exception:
# Silent failure for performance
......@@ -256,7 +257,7 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
tunnel.update_status(TunnelStatus.CLOSED)
del active_tunnels[request_id]
if debug:
if debug_flag:
print(f"[DEBUG] [WebSocket] Tunnel {request_id} closed")
print(f"[DEBUG] Tunnel object: {tunnel}")
else:
......@@ -269,7 +270,7 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
disconnected_client = cid
clients[cid]['status'] = 'disconnected'
clients[cid]['last_seen'] = time.time()
if debug: print(f"[DEBUG] [WebSocket] Client {cid} disconnected (marked for timeout)")
if debug_flag: print(f"[DEBUG] [WebSocket] Client {cid} disconnected (marked for timeout)")
break
# Clean up active tunnels for this client (optimized)
......@@ -281,13 +282,15 @@ async def handle_websocket(websocket, path=None, *, server_password=None):
tunnel = active_tunnels[request_id]
tunnel.update_status(TunnelStatus.ERROR, "Client disconnected")
del active_tunnels[request_id]
if debug:
if debug_flag:
print(f"[DEBUG] [WebSocket] Tunnel {request_id} cleaned up due to client disconnect")
print(f"[DEBUG] Tunnel object: {tunnel}")
async def cleanup_task():
async def cleanup_task(debug_flag=False):
"""Periodic task to clean up expired clients and report status"""
global debug
debug = debug_flag
last_status_time = 0
while True:
# Use moderate sleep intervals for cleanup
......
......@@ -21,9 +21,16 @@
#include "wssshlib.h"
#include "tunnel.h"
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
int websocket_handshake(SSL *ssl, const char *host, int port, const char *path, int debug) {
char request[1024];
......@@ -260,6 +267,245 @@ int send_websocket_frame(SSL *ssl, const char *data) {
return 1;
}
// Bridge mode transport layer functions - Pure WebSocket connection without tunnel setup
int setup_websocket_connection(const char *host, int port, const char *client_id, int debug, SSL_CTX **ctx_out) {
int sock;
struct sockaddr_in server_addr;
SSL_CTX *ctx;
SSL *ssl;
if (debug) {
printf("[DEBUG] Setting up pure WebSocket connection to %s:%d for client %s\n", host, port, client_id);
fflush(stdout);
}
// Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Socket creation failed");
return -1;
}
// Set up server address
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
struct hostent *he;
if ((he = gethostbyname(host)) == NULL) {
fprintf(stderr, "Failed to resolve hostname: %s\n", host);
close(sock);
return -1;
}
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
// Connect to server
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
close(sock);
return -1;
}
// Set up SSL context
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ctx = SSL_CTX_new(TLS_client_method());
if (!ctx) {
fprintf(stderr, "SSL context creation failed\n");
close(sock);
return -1;
}
// Create SSL connection
ssl = SSL_new(ctx);
if (!ssl) {
fprintf(stderr, "SSL creation failed\n");
SSL_CTX_free(ctx);
close(sock);
return -1;
}
SSL_set_fd(ssl, sock);
// Perform SSL handshake
if (SSL_connect(ssl) != 1) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "SSL handshake failed\n");
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return -1;
}
// Perform WebSocket handshake
char path[256];
snprintf(path, sizeof(path), "/ws/%s", client_id);
if (!websocket_handshake(ssl, host, port, path, debug)) {
fprintf(stderr, "WebSocket handshake failed\n");
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return -1;
}
// Store SSL in global tunnel for cleanup (bridge mode doesn't use full tunnel struct)
if (!active_tunnel) {
active_tunnel = malloc(sizeof(tunnel_t));
if (!active_tunnel) {
fprintf(stderr, "Memory allocation failed for tunnel\n");
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return -1;
}
memset(active_tunnel, 0, sizeof(tunnel_t));
}
active_tunnel->ssl = ssl;
// Note: ctx is not stored in tunnel_t, we'll manage it separately for bridge mode
// For bridge mode, we need to store ctx somewhere accessible for cleanup
// For now, we'll handle cleanup in the calling function
if (debug) {
printf("[DEBUG] Pure WebSocket connection established successfully\n");
fflush(stdout);
}
// Return the SSL context for proper cleanup
if (ctx_out) {
*ctx_out = ctx;
}
return sock;
}
int send_websocket_message(int sock, const char *message, int len, const char *channel, int debug) {
// For now, send all messages as text frames
// In a full implementation, you might want to route based on channel
char frame[BUFFER_SIZE];
int header_len = 2;
if (len <= 125) {
header_len = 6; // 2 + 4 for mask
} else if (len <= 65535) {
header_len = 8; // 4 + 4 for mask
} else {
header_len = 14; // 10 + 4 for mask
}
int frame_len = header_len + len;
if (frame_len > BUFFER_SIZE) {
fprintf(stderr, "Message too large for buffer\n");
return 0;
}
frame[0] = 0x81; // FIN + text opcode
if (len <= 125) {
frame[1] = 0x80 | len; // MASK + length
} else if (len <= 65535) {
frame[1] = 0x80 | 126; // MASK + extended length
frame[2] = (len >> 8) & 0xFF;
frame[3] = len & 0xFF;
} else {
frame[1] = 0x80 | 127; // MASK + extended length
frame[2] = 0;
frame[3] = 0;
frame[4] = 0;
frame[5] = 0;
frame[6] = (len >> 24) & 0xFF;
frame[7] = (len >> 16) & 0xFF;
frame[8] = (len >> 8) & 0xFF;
frame[9] = len & 0xFF;
}
// Add mask key
char mask_key[4];
for (int i = 0; i < 4; i++) {
mask_key[i] = rand() % 256;
frame[header_len - 4 + i] = mask_key[i];
}
// Mask payload
for (int i = 0; i < len; i++) {
frame[header_len + i] = message[i] ^ mask_key[i % 4];
}
// Send frame
int total_sent = 0;
while (total_sent < frame_len) {
int sent = send(sock, frame + total_sent, frame_len - total_sent, 0);
if (sent <= 0) {
perror("Send failed");
return 0;
}
total_sent += sent;
}
if (debug) {
printf("[DEBUG] Sent %d bytes to %s channel\n", len, channel);
fflush(stdout);
}
return 1;
}
int send_pong_frame_ws(int sock, const char *ping_payload, int payload_len) {
char frame[BUFFER_SIZE];
int header_len = 2;
frame[0] = 0x8A; // FIN + pong opcode
if (payload_len <= 125) {
frame[1] = 0x80 | payload_len; // MASK + length
} else if (payload_len <= 65535) {
frame[1] = 0x80 | 126; // MASK + extended length
frame[2] = (payload_len >> 8) & 0xFF;
frame[3] = payload_len & 0xFF;
header_len = 4;
} else {
frame[1] = 0x80 | 127; // MASK + extended length
frame[2] = 0;
frame[3] = 0;
frame[4] = 0;
frame[5] = 0;
frame[6] = (payload_len >> 24) & 0xFF;
frame[7] = (payload_len >> 16) & 0xFF;
frame[8] = (payload_len >> 8) & 0xFF;
frame[9] = payload_len & 0xFF;
header_len = 10;
}
// Add mask key
char mask_key[4];
for (int i = 0; i < 4; i++) {
mask_key[i] = rand() % 256;
frame[header_len + i] = mask_key[i];
}
header_len += 4;
// Mask payload
for (int i = 0; i < payload_len; i++) {
frame[header_len + i] = ping_payload[i] ^ mask_key[i % 4];
}
int frame_len = header_len + payload_len;
// Send frame
int total_sent = 0;
while (total_sent < frame_len) {
int sent = send(sock, frame + total_sent, frame_len - total_sent, 0);
if (sent <= 0) {
perror("Pong send failed");
return 0;
}
total_sent += sent;
}
return 1;
}
int send_pong_frame(SSL *ssl, const char *ping_payload, int payload_len) {
// Lock SSL mutex to prevent concurrent SSL operations
pthread_mutex_lock(&ssl_mutex);
......
......@@ -30,4 +30,9 @@ int send_websocket_frame(SSL *ssl, const char *data);
int send_pong_frame(SSL *ssl, const char *ping_payload, int payload_len);
int parse_websocket_frame(const char *buffer, int bytes_read, char **payload, int *payload_len);
// Bridge mode transport layer functions
int setup_websocket_connection(const char *host, int port, const char *client_id, int debug, SSL_CTX **ctx_out);
int send_websocket_message(int sock, const char *message, int len, const char *channel, int debug);
int send_pong_frame_ws(int sock, const char *ping_payload, int payload_len);
#endif // WEBSOCKET_H
\ No newline at end of file
......@@ -398,6 +398,12 @@ int connect_to_server(const wssshc_config_t *config) {
fflush(stdout);
}
int reg_result = send_registration_message(ssl, config->client_id, config->password, best_tunnel ? best_tunnel : expanded_tunnel, best_tunnel_control ? best_tunnel_control : expanded_tunnel_control, config->wssshd_private_ip);
if (config->debug && reg_result) {
// Note: send_registration_message doesn't return the message content, so we can't log the exact JSON here
// The function internally handles the JSON formatting
printf("[DEBUG] Registration message sent successfully\n");
fflush(stdout);
}
// Free expanded transport lists and best transport selections
if (expanded_tunnel != config->tunnel) {
......
No preview for this file type
This diff is collapsed.
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