You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
3.3 KiB
79 lines
3.3 KiB
// socks_proxy.h — SOCKS5 / HTTP CONNECT proxy (client side) |
|
#ifndef SOCKS_PROXY_H |
|
#define SOCKS_PROXY_H |
|
|
|
#include <stdint.h> |
|
#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
|
|
|