// socks_proxy.h — SOCKS5 / HTTP CONNECT proxy (client side) #ifndef SOCKS_PROXY_H #define SOCKS_PROXY_H #include #include "../lib/socket_compat.h" #include "../lib/ll_queue.h" struct UASYNC; struct UTUN_INSTANCE; struct ll_entry; struct ll_queue; struct tcp_conn; enum { SOCKS_STATE_GREETING = 0, // ждём SOCKS5 greeting (ver + methods) SOCKS_STATE_REQUEST, // ждём SOCKS5 CONNECT request SOCKS_STATE_CONNECTING, // отправили ETCP CONNECT, ждём ответ от exit SOCKS_STATE_RELAY // релей данных }; enum { HTTP_STATE_REQUEST = 0, // ждём "CONNECT host:port HTTP/1.1\r\n" HTTP_STATE_CONNECTING, // отправили ETCP CONNECT, ждём ответ от exit HTTP_STATE_RELAY // релей данных }; struct socks_proxy_conn { struct socks_proxy_conn* next; struct socks_proxy_conn** head; // указатель на голову списка (для удаления) int* count; // указатель на счётчик списка struct tcp_conn* tc; struct UASYNC* ua; struct UTUN_INSTANCE* inst; uint64_t via_node_id; uint32_t stream_id; uint8_t dest_ip[4]; uint16_t dest_port; uint8_t fin_remote; uint8_t rem_closed; uint8_t close_sent; uint8_t close_pending; uint8_t is_http; uint8_t state; uint8_t freed; uint8_t buf[1024]; uint16_t buf_len; struct queue_waiter_handle tx_waiter; }; struct listen_ctx; // Создать слушающий сокет для SOCKS/HTTP proxy. addr_str = "IP:PORT". // listen_ctx должен быть освобождён через socks_proxy_close_listen. // Возвращает listen_ctx при успехе, NULL при ошибке. struct listen_ctx* socks_proxy_init_listen(struct UASYNC* ua, const char* addr_str, struct socks_proxy_conn** conns, int* count, uint32_t* next_stream_id, struct UTUN_INSTANCE* inst, uint64_t via_node_id, int is_http); // Закрыть слушающий сокет и освободить listen_ctx. // sock_out получает значение сокета (для последующего close). void socks_proxy_close_listen(struct UASYNC* ua, struct listen_ctx* ctx, socket_t* sock_out); // Найти соединение по stream_id struct socks_proxy_conn* socks_proxy_find_conn(struct socks_proxy_conn* head, uint32_t stream_id); // Обработать входящее ETCP сообщение (DATA/CLOSE/ERROR/FIN) // Возвращает 1 если обработано, 0 если stream_id не найден int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count, uint32_t stream_id, uint8_t subcmd, const uint8_t* data, size_t data_len); // Освободить одно соединение (удаляет из списка) void socks_proxy_conn_free(struct socks_proxy_conn* c); // Освободить все соединения в списке void socks_proxy_conn_free_all(struct socks_proxy_conn** head, int* count); #endif // SOCKS_PROXY_H