/** * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Включение основных модулей 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; }