Files
Phantom/release/tools/phantom-tunnel.c

1063 lines
36 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Phantom Tunnel - Система туннелирования трафика через Phantom сеть
*
* Эта утилита создает зашифрованные туннели через Phantom сеть,
* позволяя безопасно передавать любой TCP трафик через несколько
* промежуточных узлов для обеспечения анонимности.
*
* Примеры использования:
* ./phantom-tunnel --local 8080 --remote example.com:80 --hops 3
* ./phantom-tunnel --ssh-tunnel 2222 remote.server.com
* ./phantom-tunnel --vpn-mode --interface tun0
*
* Автор: Phantom Protocol Team 2025
* Версия: 1.0.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h>
#include <netdb.h>
// Включение основных модулей Phantom
#include "../src/config.h"
#include "../src/kademlia.h"
#include "../src/path.h"
#define PHANTOM_TUNNEL_VERSION "1.0.0"
#define MAX_HOPS 10
#define MAX_CONNECTIONS 100
#define BUFFER_SIZE 8192
#define DEFAULT_TIMEOUT 30
// Типы туннелей
typedef enum {
TUNNEL_TYPE_TCP, // Простой TCP туннель
TUNNEL_TYPE_HTTP, // HTTP прокси туннель
TUNNEL_TYPE_SOCKS5, // SOCKS5 прокси туннель
TUNNEL_TYPE_SSH, // SSH туннель
TUNNEL_TYPE_VPN // VPN туннель
} tunnel_type_t;
// Состояние туннеля
typedef enum {
TUNNEL_STATE_DISCONNECTED,
TUNNEL_STATE_CONNECTING,
TUNNEL_STATE_CONNECTED,
TUNNEL_STATE_ERROR
} tunnel_state_t;
// Структура узла маршрута
typedef struct {
char node_id[64];
char ip_address[INET6_ADDRSTRLEN];
uint16_t port;
uint32_t latency; // в миллисекундах
uint32_t bandwidth; // в Кбит/с
float reliability; // 0.0 - 1.0
} phantom_route_node_t;
// Структура маршрута
typedef struct {
phantom_route_node_t hops[MAX_HOPS];
int hop_count;
uint32_t total_latency;
uint32_t min_bandwidth;
float route_reliability;
time_t created_time;
} phantom_route_t;
// Структура подключения
typedef struct {
int id;
int client_socket;
int phantom_socket;
tunnel_state_t state;
char remote_host[256];
uint16_t remote_port;
phantom_route_t route;
uint64_t bytes_sent;
uint64_t bytes_received;
time_t start_time;
time_t last_activity;
pthread_t thread;
bool is_active;
} phantom_connection_t;
// Структура туннеля
typedef struct {
tunnel_type_t type;
tunnel_state_t state;
// Локальные настройки
char bind_address[INET6_ADDRSTRLEN];
uint16_t local_port;
int listen_socket;
// Удаленные настройки
char remote_host[256];
uint16_t remote_port;
// Настройки маршрутизации
int desired_hops;
bool use_exit_nodes;
char preferred_countries[10][3]; // ISO коды стран
int country_count;
// Подключения
phantom_connection_t connections[MAX_CONNECTIONS];
int connection_count;
pthread_mutex_t connections_lock;
// Статистика
uint64_t total_bytes_sent;
uint64_t total_bytes_received;
uint32_t total_connections;
time_t start_time;
// Управление
bool is_running;
pthread_t accept_thread;
pthread_t monitor_thread;
} phantom_tunnel_t;
// Глобальная переменная туннеля
static phantom_tunnel_t *g_tunnel = NULL;
// Прототипы функций
phantom_tunnel_t* phantom_tunnel_create(tunnel_type_t type);
int phantom_tunnel_bind(phantom_tunnel_t *tunnel, const char *address, uint16_t port);
int phantom_tunnel_set_target(phantom_tunnel_t *tunnel, const char *host, uint16_t port);
int phantom_tunnel_start(phantom_tunnel_t *tunnel);
int phantom_tunnel_stop(phantom_tunnel_t *tunnel);
void phantom_tunnel_destroy(phantom_tunnel_t *tunnel);
phantom_route_t phantom_build_route(const char *target_host, uint16_t target_port, int hops);
int phantom_connect_through_route(const phantom_route_t *route, const char *target_host, uint16_t target_port);
void* phantom_tunnel_accept_thread(void *arg);
void* phantom_tunnel_connection_thread(void *arg);
void* phantom_tunnel_monitor_thread(void *arg);
void phantom_tunnel_show_status(phantom_tunnel_t *tunnel);
void phantom_tunnel_show_help(void);
void phantom_tunnel_signal_handler(int signal);
/**
* Создание туннеля
*/
phantom_tunnel_t* phantom_tunnel_create(tunnel_type_t type) {
phantom_tunnel_t *tunnel = calloc(1, sizeof(phantom_tunnel_t));
if (!tunnel) {
fprintf(stderr, "Не удалось выделить память для туннеля\n");
return NULL;
}
tunnel->type = type;
tunnel->state = TUNNEL_STATE_DISCONNECTED;
tunnel->desired_hops = 3;
tunnel->use_exit_nodes = true;
tunnel->listen_socket = -1;
tunnel->is_running = false;
tunnel->connection_count = 0;
strcpy(tunnel->bind_address, "127.0.0.1");
// Инициализация мутекса
if (pthread_mutex_init(&tunnel->connections_lock, NULL) != 0) {
free(tunnel);
return NULL;
}
tunnel->start_time = time(NULL);
printf("Phantom Tunnel создан (тип: %s)\n",
phantom_tunnel_type_to_string(type));
return tunnel;
}
/**
* Привязка туннеля к локальному адресу
*/
int phantom_tunnel_bind(phantom_tunnel_t *tunnel, const char *address, uint16_t port) {
if (!tunnel || !address) {
return -1;
}
strncpy(tunnel->bind_address, address, sizeof(tunnel->bind_address) - 1);
tunnel->local_port = port;
// Создание серверного сокета
tunnel->listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if (tunnel->listen_socket < 0) {
perror("socket");
return -1;
}
// Разрешение повторного использования адреса
int opt = 1;
setsockopt(tunnel->listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// Настройка адреса
struct sockaddr_in bind_addr;
memset(&bind_addr, 0, sizeof(bind_addr));
bind_addr.sin_family = AF_INET;
bind_addr.sin_port = htons(port);
if (inet_pton(AF_INET, address, &bind_addr.sin_addr) <= 0) {
fprintf(stderr, "Неверный IP адрес: %s\n", address);
close(tunnel->listen_socket);
tunnel->listen_socket = -1;
return -1;
}
// Привязка сокета
if (bind(tunnel->listen_socket, (struct sockaddr*)&bind_addr, sizeof(bind_addr)) < 0) {
perror("bind");
close(tunnel->listen_socket);
tunnel->listen_socket = -1;
return -1;
}
printf("Туннель привязан к %s:%d\n", address, port);
return 0;
}
/**
* Установка целевого адреса
*/
int phantom_tunnel_set_target(phantom_tunnel_t *tunnel, const char *host, uint16_t port) {
if (!tunnel || !host) {
return -1;
}
strncpy(tunnel->remote_host, host, sizeof(tunnel->remote_host) - 1);
tunnel->remote_port = port;
printf("Целевой адрес установлен: %s:%d\n", host, port);
return 0;
}
/**
* Запуск туннеля
*/
int phantom_tunnel_start(phantom_tunnel_t *tunnel) {
if (!tunnel) {
return -1;
}
if (tunnel->is_running) {
printf("Туннель уже запущен\n");
return 0;
}
if (tunnel->listen_socket < 0) {
fprintf(stderr, "Туннель не привязан к адресу\n");
return -1;
}
printf("Запуск Phantom Tunnel...\n");
// Прослушивание подключений
if (listen(tunnel->listen_socket, 10) < 0) {
perror("listen");
return -1;
}
tunnel->is_running = true;
tunnel->state = TUNNEL_STATE_CONNECTED;
// Запуск потока принятия подключений
if (pthread_create(&tunnel->accept_thread, NULL,
phantom_tunnel_accept_thread, tunnel) != 0) {
perror("pthread_create accept");
tunnel->is_running = false;
return -1;
}
// Запуск потока мониторинга
if (pthread_create(&tunnel->monitor_thread, NULL,
phantom_tunnel_monitor_thread, tunnel) != 0) {
perror("pthread_create monitor");
tunnel->is_running = false;
pthread_cancel(tunnel->accept_thread);
return -1;
}
printf("✅ Phantom Tunnel запущен\n");
printf(" Локальный адрес: %s:%d\n", tunnel->bind_address, tunnel->local_port);
printf(" Удаленный адрес: %s:%d\n", tunnel->remote_host, tunnel->remote_port);
printf(" Количество хопов: %d\n", tunnel->desired_hops);
return 0;
}
/**
* Остановка туннеля
*/
int phantom_tunnel_stop(phantom_tunnel_t *tunnel) {
if (!tunnel || !tunnel->is_running) {
return 0;
}
printf("Остановка Phantom Tunnel...\n");
tunnel->is_running = false;
tunnel->state = TUNNEL_STATE_DISCONNECTED;
// Закрытие серверного сокета
if (tunnel->listen_socket >= 0) {
close(tunnel->listen_socket);
tunnel->listen_socket = -1;
}
// Остановка потоков
pthread_cancel(tunnel->accept_thread);
pthread_cancel(tunnel->monitor_thread);
// Закрытие всех подключений
pthread_mutex_lock(&tunnel->connections_lock);
for (int i = 0; i < tunnel->connection_count; i++) {
phantom_connection_t *conn = &tunnel->connections[i];
if (conn->is_active) {
conn->is_active = false;
if (conn->client_socket >= 0) {
close(conn->client_socket);
}
if (conn->phantom_socket >= 0) {
close(conn->phantom_socket);
}
pthread_cancel(conn->thread);
}
}
tunnel->connection_count = 0;
pthread_mutex_unlock(&tunnel->connections_lock);
printf("✅ Phantom Tunnel остановлен\n");
return 0;
}
/**
* Уничтожение туннеля
*/
void phantom_tunnel_destroy(phantom_tunnel_t *tunnel) {
if (!tunnel) {
return;
}
phantom_tunnel_stop(tunnel);
pthread_mutex_destroy(&tunnel->connections_lock);
free(tunnel);
}
/**
* Построение маршрута через Phantom сеть
*/
phantom_route_t phantom_build_route(const char *target_host, uint16_t target_port, int hops) {
phantom_route_t route;
memset(&route, 0, sizeof(route));
printf("Построение маршрута к %s:%d через %d хопов...\n",
target_host, target_port, hops);
// Симуляция построения маршрута
// В реальной реализации здесь будет использоваться Kademlia DHT
// для поиска оптимальных узлов
route.hop_count = hops;
route.created_time = time(NULL);
for (int i = 0; i < hops && i < MAX_HOPS; i++) {
phantom_route_node_t *node = &route.hops[i];
// Генерация случайного узла (в реальности - поиск в DHT)
snprintf(node->node_id, sizeof(node->node_id), "phantom-node-%d", i + 1);
snprintf(node->ip_address, sizeof(node->ip_address), "10.0.%d.%d",
(i + 1), 100 + (rand() % 50));
node->port = 8050 + i;
node->latency = 50 + (rand() % 200); // 50-250ms
node->bandwidth = 1000 + (rand() % 9000); // 1-10 Мбит/с
node->reliability = 0.8 + (rand() % 20) / 100.0; // 0.8-1.0
route.total_latency += node->latency;
if (i == 0 || node->bandwidth < route.min_bandwidth) {
route.min_bandwidth = node->bandwidth;
}
route.route_reliability *= node->reliability;
printf(" Хоп %d: %s (%s:%d) - задержка: %dms, пропускная способность: %d Кбит/с\n",
i + 1, node->node_id, node->ip_address, node->port,
node->latency, node->bandwidth);
}
printf("Маршрут построен: общая задержка %dms, пропускная способность %d Кбит/с, надежность %.2f\n",
route.total_latency, route.min_bandwidth, route.route_reliability);
return route;
}
/**
* Подключение через маршрут
*/
int phantom_connect_through_route(const phantom_route_t *route,
const char *target_host, uint16_t target_port) {
if (!route || !target_host) {
return -1;
}
printf("Подключение к %s:%d через маршрут из %d хопов...\n",
target_host, target_port, route->hop_count);
// Создание сокета для подключения к первому хопу
int phantom_socket = socket(AF_INET, SOCK_STREAM, 0);
if (phantom_socket < 0) {
perror("socket");
return -1;
}
// Подключение к первому узлу маршрута
if (route->hop_count > 0) {
const phantom_route_node_t *first_hop = &route->hops[0];
struct sockaddr_in hop_addr;
memset(&hop_addr, 0, sizeof(hop_addr));
hop_addr.sin_family = AF_INET;
hop_addr.sin_port = htons(first_hop->port);
if (inet_pton(AF_INET, first_hop->ip_address, &hop_addr.sin_addr) <= 0) {
fprintf(stderr, "Неверный IP адрес узла: %s\n", first_hop->ip_address);
close(phantom_socket);
return -1;
}
printf("Подключение к первому хопу: %s:%d\n",
first_hop->ip_address, first_hop->port);
if (connect(phantom_socket, (struct sockaddr*)&hop_addr, sizeof(hop_addr)) < 0) {
perror("connect to first hop");
close(phantom_socket);
return -1;
}
// Отправка команды построения туннеля через все хопы
char tunnel_command[1024];
snprintf(tunnel_command, sizeof(tunnel_command),
"PHANTOM_BUILD_TUNNEL %s %d", target_host, target_port);
// Добавление информации о хопах
for (int i = 1; i < route->hop_count; i++) {
char hop_info[128];
snprintf(hop_info, sizeof(hop_info), " %s:%d",
route->hops[i].ip_address, route->hops[i].port);
strncat(tunnel_command, hop_info, sizeof(tunnel_command) - strlen(tunnel_command) - 1);
}
strncat(tunnel_command, "\n", sizeof(tunnel_command) - strlen(tunnel_command) - 1);
if (send(phantom_socket, tunnel_command, strlen(tunnel_command), 0) < 0) {
perror("send tunnel command");
close(phantom_socket);
return -1;
}
// Ожидание подтверждения
char response[256];
ssize_t received = recv(phantom_socket, response, sizeof(response) - 1, 0);
if (received <= 0) {
fprintf(stderr, "Не получен ответ от первого хопа\n");
close(phantom_socket);
return -1;
}
response[received] = '\0';
if (strncmp(response, "PHANTOM_TUNNEL_OK", 17) != 0) {
fprintf(stderr, "Ошибка построения туннеля: %s\n", response);
close(phantom_socket);
return -1;
}
printf("✅ Туннель через Phantom сеть установлен\n");
}
return phantom_socket;
}
/**
* Поток принятия подключений
*/
void* phantom_tunnel_accept_thread(void *arg) {
phantom_tunnel_t *tunnel = (phantom_tunnel_t*)arg;
printf("Поток принятия подключений запущен\n");
while (tunnel->is_running) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
// Принятие подключения
int client_socket = accept(tunnel->listen_socket,
(struct sockaddr*)&client_addr, &client_len);
if (client_socket < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
usleep(100000); // 100ms
continue;
}
if (tunnel->is_running) {
perror("accept");
}
continue;
}
// Получение IP адреса клиента
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Новое подключение от %s:%d\n", client_ip, ntohs(client_addr.sin_port));
// Поиск свободного слота для подключения
pthread_mutex_lock(&tunnel->connections_lock);
int connection_id = -1;
for (int i = 0; i < MAX_CONNECTIONS; i++) {
if (!tunnel->connections[i].is_active) {
connection_id = i;
break;
}
}
if (connection_id == -1) {
printf("Достигнуто максимальное количество подключений\n");
close(client_socket);
pthread_mutex_unlock(&tunnel->connections_lock);
continue;
}
// Инициализация подключения
phantom_connection_t *conn = &tunnel->connections[connection_id];
memset(conn, 0, sizeof(phantom_connection_t));
conn->id = connection_id;
conn->client_socket = client_socket;
conn->phantom_socket = -1;
conn->state = TUNNEL_STATE_CONNECTING;
conn->is_active = true;
conn->start_time = time(NULL);
conn->last_activity = time(NULL);
strcpy(conn->remote_host, tunnel->remote_host);
conn->remote_port = tunnel->remote_port;
if (connection_id >= tunnel->connection_count) {
tunnel->connection_count = connection_id + 1;
}
tunnel->total_connections++;
pthread_mutex_unlock(&tunnel->connections_lock);
// Запуск потока обработки подключения
if (pthread_create(&conn->thread, NULL,
phantom_tunnel_connection_thread, conn) != 0) {
perror("pthread_create connection");
close(client_socket);
conn->is_active = false;
continue;
}
pthread_detach(conn->thread);
}
printf("Поток принятия подключений завершен\n");
return NULL;
}
/**
* Поток обработки подключения
*/
void* phantom_tunnel_connection_thread(void *arg) {
phantom_connection_t *conn = (phantom_connection_t*)arg;
printf("Обработка подключения #%d\n", conn->id);
// Построение маршрута к целевому серверу
conn->route = phantom_build_route(conn->remote_host, conn->remote_port,
g_tunnel->desired_hops);
// Подключение через Phantom сеть
conn->phantom_socket = phantom_connect_through_route(&conn->route,
conn->remote_host,
conn->remote_port);
if (conn->phantom_socket < 0) {
printf("Не удалось установить туннель для подключения #%d\n", conn->id);
conn->state = TUNNEL_STATE_ERROR;
close(conn->client_socket);
conn->is_active = false;
return NULL;
}
conn->state = TUNNEL_STATE_CONNECTED;
printf("✅ Туннель для подключения #%d установлен\n", conn->id);
// Проксирование данных между клиентом и Phantom сетью
phantom_tunnel_relay_data(conn);
// Закрытие подключения
printf("Закрытие подключения #%d\n", conn->id);
if (conn->client_socket >= 0) {
close(conn->client_socket);
}
if (conn->phantom_socket >= 0) {
close(conn->phantom_socket);
}
conn->is_active = false;
conn->state = TUNNEL_STATE_DISCONNECTED;
return NULL;
}
/**
* Проксирование данных
*/
void phantom_tunnel_relay_data(phantom_connection_t *conn) {
if (!conn) {
return;
}
fd_set read_fds;
int max_fd = (conn->client_socket > conn->phantom_socket) ?
conn->client_socket : conn->phantom_socket;
char buffer[BUFFER_SIZE];
while (conn->is_active && g_tunnel->is_running) {
FD_ZERO(&read_fds);
FD_SET(conn->client_socket, &read_fds);
FD_SET(conn->phantom_socket, &read_fds);
struct timeval timeout = {1, 0}; // 1 секунда
int activity = select(max_fd + 1, &read_fds, NULL, NULL, &timeout);
if (activity < 0) {
perror("select");
break;
}
if (activity == 0) {
// Проверка таймаута неактивности
if (time(NULL) - conn->last_activity > DEFAULT_TIMEOUT) {
printf("Таймаут неактивности для подключения #%d\n", conn->id);
break;
}
continue;
}
// Данные от клиента к Phantom сети
if (FD_ISSET(conn->client_socket, &read_fds)) {
ssize_t received = recv(conn->client_socket, buffer, sizeof(buffer), 0);
if (received <= 0) {
if (received < 0) {
perror("recv from client");
}
break;
}
if (send(conn->phantom_socket, buffer, received, 0) <= 0) {
perror("send to phantom");
break;
}
conn->bytes_sent += received;
g_tunnel->total_bytes_sent += received;
conn->last_activity = time(NULL);
}
// Данные от Phantom сети к клиенту
if (FD_ISSET(conn->phantom_socket, &read_fds)) {
ssize_t received = recv(conn->phantom_socket, buffer, sizeof(buffer), 0);
if (received <= 0) {
if (received < 0) {
perror("recv from phantom");
}
break;
}
if (send(conn->client_socket, buffer, received, 0) <= 0) {
perror("send to client");
break;
}
conn->bytes_received += received;
g_tunnel->total_bytes_received += received;
conn->last_activity = time(NULL);
}
}
}
/**
* Поток мониторинга
*/
void* phantom_tunnel_monitor_thread(void *arg) {
phantom_tunnel_t *tunnel = (phantom_tunnel_t*)arg;
printf("Поток мониторинга запущен\n");
while (tunnel->is_running) {
sleep(10); // Мониторинг каждые 10 секунд
pthread_mutex_lock(&tunnel->connections_lock);
int active_connections = 0;
uint64_t total_sent = 0;
uint64_t total_received = 0;
for (int i = 0; i < tunnel->connection_count; i++) {
phantom_connection_t *conn = &tunnel->connections[i];
if (conn->is_active) {
active_connections++;
total_sent += conn->bytes_sent;
total_received += conn->bytes_received;
}
}
pthread_mutex_unlock(&tunnel->connections_lock);
printf("📊 Статистика туннеля: %d активных подключений, "
"отправлено %llu байт, получено %llu байт\n",
active_connections, total_sent, total_received);
}
printf("Поток мониторинга завершен\n");
return NULL;
}
/**
* Показ статуса туннеля
*/
void phantom_tunnel_show_status(phantom_tunnel_t *tunnel) {
if (!tunnel) {
return;
}
printf("\n=== Статус Phantom Tunnel ===\n");
printf("Версия: %s\n", PHANTOM_TUNNEL_VERSION);
printf("Тип: %s\n", phantom_tunnel_type_to_string(tunnel->type));
printf("Состояние: %s\n", phantom_tunnel_state_to_string(tunnel->state));
if (tunnel->is_running) {
printf("Локальный адрес: %s:%d\n", tunnel->bind_address, tunnel->local_port);
printf("Удаленный адрес: %s:%d\n", tunnel->remote_host, tunnel->remote_port);
printf("Количество хопов: %d\n", tunnel->desired_hops);
time_t uptime = time(NULL) - tunnel->start_time;
printf("Время работы: %ld сек\n", uptime);
pthread_mutex_lock(&tunnel->connections_lock);
int active_connections = 0;
for (int i = 0; i < tunnel->connection_count; i++) {
if (tunnel->connections[i].is_active) {
active_connections++;
}
}
printf("Активных подключений: %d\n", active_connections);
printf("Всего подключений: %u\n", tunnel->total_connections);
printf("Отправлено: %llu байт\n", tunnel->total_bytes_sent);
printf("Получено: %llu байт\n", tunnel->total_bytes_received);
pthread_mutex_unlock(&tunnel->connections_lock);
}
printf("============================\n\n");
}
/**
* Показ справки
*/
void phantom_tunnel_show_help(void) {
printf("Phantom Tunnel v%s - Система туннелирования через Phantom сеть\n\n",
PHANTOM_TUNNEL_VERSION);
printf("Использование:\n");
printf(" phantom-tunnel [ОПЦИИ]\n\n");
printf("Опции:\n");
printf(" -l, --local АДРЕС:ПОРТ Локальный адрес для прослушивания\n");
printf(" -r, --remote АДРЕС:ПОРТ Удаленный адрес назначения\n");
printf(" -h, --hops КОЛИЧЕСТВО Количество хопов (по умолчанию: 3)\n");
printf(" -t, --type ТИП Тип туннеля (tcp, http, socks5, ssh, vpn)\n");
printf(" -c, --countries СТРАНЫ Предпочитаемые страны (ISO коды)\n");
printf(" -e, --exit-nodes Использовать exit-ноды\n");
printf(" -s, --status Показать статус\n");
printf(" -d, --daemon Запуск в режиме демона\n");
printf(" -v, --verbose Подробный вывод\n");
printf(" --help Показать эту справку\n\n");
printf("Примеры:\n");
printf(" # Простой TCP туннель\n");
printf(" phantom-tunnel -l 8080 -r example.com:80\n\n");
printf(" # SSH туннель через 5 хопов\n");
printf(" phantom-tunnel -l 2222 -r remote.server.com:22 -h 5\n\n");
printf(" # SOCKS5 прокси\n");
printf(" phantom-tunnel -l 1080 -t socks5\n\n");
printf(" # HTTP прокси с предпочтением определенных стран\n");
printf(" phantom-tunnel -l 8888 -t http -c US,DE,NL\n\n");
}
/**
* Преобразование типа туннеля в строку
*/
const char* phantom_tunnel_type_to_string(tunnel_type_t type) {
switch (type) {
case TUNNEL_TYPE_TCP: return "TCP";
case TUNNEL_TYPE_HTTP: return "HTTP Proxy";
case TUNNEL_TYPE_SOCKS5: return "SOCKS5 Proxy";
case TUNNEL_TYPE_SSH: return "SSH Tunnel";
case TUNNEL_TYPE_VPN: return "VPN Tunnel";
default: return "Unknown";
}
}
/**
* Преобразование состояния туннеля в строку
*/
const char* phantom_tunnel_state_to_string(tunnel_state_t state) {
switch (state) {
case TUNNEL_STATE_DISCONNECTED: return "Отключен";
case TUNNEL_STATE_CONNECTING: return "Подключение";
case TUNNEL_STATE_CONNECTED: return "Подключен";
case TUNNEL_STATE_ERROR: return "Ошибка";
default: return "Неизвестно";
}
}
/**
* Обработчик сигналов
*/
void phantom_tunnel_signal_handler(int signal) {
printf("\nПолучен сигнал %d, завершение работы...\n", signal);
if (g_tunnel) {
phantom_tunnel_stop(g_tunnel);
}
exit(0);
}
/**
* Главная функция
*/
int main(int argc, char *argv[]) {
printf("Phantom Tunnel v%s\n", PHANTOM_TUNNEL_VERSION);
printf("Система туннелирования трафика через Phantom сеть\n\n");
// Установка обработчиков сигналов
signal(SIGINT, phantom_tunnel_signal_handler);
signal(SIGTERM, phantom_tunnel_signal_handler);
// Парсинг аргументов командной строки
static struct option long_options[] = {
{"local", required_argument, 0, 'l'},
{"remote", required_argument, 0, 'r'},
{"hops", required_argument, 0, 'h'},
{"type", required_argument, 0, 't'},
{"countries", required_argument, 0, 'c'},
{"exit-nodes", no_argument, 0, 'e'},
{"status", no_argument, 0, 's'},
{"daemon", no_argument, 0, 'd'},
{"verbose", no_argument, 0, 'v'},
{"help", no_argument, 0, 0},
{0, 0, 0, 0}
};
tunnel_type_t tunnel_type = TUNNEL_TYPE_TCP;
char local_address[256] = "127.0.0.1";
uint16_t local_port = 0;
char remote_host[256] = "";
uint16_t remote_port = 0;
int hops = 3;
bool daemon_mode = false;
bool verbose = false;
bool show_status = false;
int option_index = 0;
int c;
while ((c = getopt_long(argc, argv, "l:r:h:t:c:esdv", long_options, &option_index)) != -1) {
switch (c) {
case 'l': {
char *colon = strchr(optarg, ':');
if (colon) {
*colon = '\0';
strcpy(local_address, optarg);
local_port = atoi(colon + 1);
} else {
local_port = atoi(optarg);
}
break;
}
case 'r': {
char *colon = strchr(optarg, ':');
if (colon) {
*colon = '\0';
strcpy(remote_host, optarg);
remote_port = atoi(colon + 1);
} else {
strcpy(remote_host, optarg);
remote_port = 80; // По умолчанию HTTP
}
break;
}
case 'h':
hops = atoi(optarg);
if (hops < 1 || hops > MAX_HOPS) {
fprintf(stderr, "Количество хопов должно быть от 1 до %d\n", MAX_HOPS);
return 1;
}
break;
case 't':
if (strcmp(optarg, "tcp") == 0) {
tunnel_type = TUNNEL_TYPE_TCP;
} else if (strcmp(optarg, "http") == 0) {
tunnel_type = TUNNEL_TYPE_HTTP;
} else if (strcmp(optarg, "socks5") == 0) {
tunnel_type = TUNNEL_TYPE_SOCKS5;
} else if (strcmp(optarg, "ssh") == 0) {
tunnel_type = TUNNEL_TYPE_SSH;
} else if (strcmp(optarg, "vpn") == 0) {
tunnel_type = TUNNEL_TYPE_VPN;
} else {
fprintf(stderr, "Неизвестный тип туннеля: %s\n", optarg);
return 1;
}
break;
case 'c':
// TODO: Обработка списка стран
printf("Предпочитаемые страны: %s\n", optarg);
break;
case 'e':
printf("Использование exit-нодов включено\n");
break;
case 's':
show_status = true;
break;
case 'd':
daemon_mode = true;
break;
case 'v':
verbose = true;
break;
case 0:
if (strcmp(long_options[option_index].name, "help") == 0) {
phantom_tunnel_show_help();
return 0;
}
break;
default:
phantom_tunnel_show_help();
return 1;
}
}
// Проверка обязательных параметров
if (local_port == 0) {
fprintf(stderr, "Не указан локальный порт\n");
phantom_tunnel_show_help();
return 1;
}
if (tunnel_type == TUNNEL_TYPE_TCP && strlen(remote_host) == 0) {
fprintf(stderr, "Для TCP туннеля необходимо указать удаленный адрес\n");
phantom_tunnel_show_help();
return 1;
}
// Создание туннеля
g_tunnel = phantom_tunnel_create(tunnel_type);
if (!g_tunnel) {
return 1;
}
g_tunnel->desired_hops = hops;
// Привязка к локальному адресу
if (phantom_tunnel_bind(g_tunnel, local_address, local_port) != 0) {
phantom_tunnel_destroy(g_tunnel);
return 1;
}
// Установка удаленного адреса
if (strlen(remote_host) > 0) {
if (phantom_tunnel_set_target(g_tunnel, remote_host, remote_port) != 0) {
phantom_tunnel_destroy(g_tunnel);
return 1;
}
}
// Показ статуса
if (show_status) {
phantom_tunnel_show_status(g_tunnel);
phantom_tunnel_destroy(g_tunnel);
return 0;
}
// Запуск в режиме демона
if (daemon_mode) {
if (daemon(0, 0) != 0) {
perror("daemon");
phantom_tunnel_destroy(g_tunnel);
return 1;
}
}
// Запуск туннеля
if (phantom_tunnel_start(g_tunnel) != 0) {
phantom_tunnel_destroy(g_tunnel);
return 1;
}
printf("\nPhantom Tunnel запущен. Нажмите Ctrl+C для остановки\n\n");
// Основной цикл
while (g_tunnel->is_running) {
if (!daemon_mode && verbose) {
phantom_tunnel_show_status(g_tunnel);
}
sleep(30);
}
// Очистка
phantom_tunnel_destroy(g_tunnel);
printf("Phantom Tunnel завершен\n");
return 0;
}