/*
 * WebSocket SSH Library - Tunnel management
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef TUNNEL_H
#define TUNNEL_H

#include <openssl/ssl.h>
#include <pthread.h>

// Frame buffer for wsscp
typedef struct {
    char *buffer;
    size_t size;
    size_t used;
} frame_buffer_t;

// Tunnel structure
typedef struct {
    int local_sock;  // Local TCP connection socket
    int sock;  // Alternative socket member for wssshc compatibility
    char request_id[37];  // UUID string
    int active;
    SSL *ssl;  // WebSocket SSL connection
    frame_buffer_t *outgoing_buffer;  // Buffer for data to send to local socket (wsscp only)
} tunnel_t;

// Global variables
extern tunnel_t *active_tunnel;
extern pthread_mutex_t tunnel_mutex;

// Function declarations
frame_buffer_t *frame_buffer_init(void);
void frame_buffer_free(frame_buffer_t *fb);
int frame_buffer_resize(frame_buffer_t *fb, size_t new_size);
int frame_buffer_append(frame_buffer_t *fb, const char *data, size_t len);
int frame_buffer_consume(frame_buffer_t *fb, size_t len);

void *forward_tcp_to_ws(void *arg);
void *tunnel_thread(void *arg);
void handle_tunnel_request(SSL *ssl, const char *request_id, int debug);
void handle_tunnel_data(SSL *ssl, const char *request_id, const char *data_hex, int debug);
void handle_tunnel_close(SSL *ssl, const char *request_id, int debug);
void cleanup_tunnel(int debug);
int reconnect_websocket(tunnel_t *tunnel, const char *wssshd_host, int wssshd_port, const char *client_id, const char *request_id, int debug);
int setup_tunnel(const char *wssshd_host, int wssshd_port, const char *client_id, int local_port, int debug, int use_buffer);

#endif // TUNNEL_H