// utun_instance.c - Root instance implementation #include "utun_instance.h" #include "config_parser.h" #include "tun_if.h" #include "routing.h" #include "etcp_connections.h" #include "../u_async/u_async.h" #include #include #include #include #include // Global instance for signal handlers static utun_instance_t *g_instance = NULL; // Create and initialize root instance utun_instance_t* utun_instance_create(const char *config_file, const char *log_file) { utun_instance_t *instance = calloc(1, sizeof(utun_instance_t)); if (!instance) return NULL; // Initialize basic fields instance->running = 0; instance->log_fp = NULL; // Load configuration instance->config = parse_config(config_file); if (!instance->config) { fprintf(stderr, "Failed to load config from %s\n", config_file); free(instance); return NULL; } // Open log file if (log_file) { instance->log_fp = fopen(log_file, "a"); if (!instance->log_fp) { fprintf(stderr, "Failed to open log file %s: %s\n", log_file, strerror(errno)); } } // Create uasync instance instance->ua = uasync_create(); if (!instance->ua) { fprintf(stderr, "Failed to create uasync instance\n"); utun_instance_destroy(instance); return NULL; } // uasync has built-in wakeup mechanism, no need for manual pipe // Set global instance utun_instance_set(instance); return instance; } // Destroy instance and cleanup resources void utun_instance_destroy(utun_instance_t *instance) { if (!instance) return; // Stop running instance->running = 0; // Cleanup components if (instance->ua) { uasync_destroy(instance->ua); } if (instance->routing_table) { routing_table_destroy(instance->routing_table); } // Cleanup connections if (instance->connections) { for (int i = 0; i < instance->connection_count; i++) { if (instance->connections[i]) { conn_destroy(instance->connections[i]); } } free(instance->connections); } // Cleanup TUN if (instance->tun.fd >= 0) { tun_close(&instance->tun); } // Cleanup config if (instance->config) { free_config(instance->config); } // Close log file if (instance->log_fp) { fclose(instance->log_fp); } // uasync cleanup will handle its built-in wakeup pipe // Clear global instance if (g_instance == instance) { g_instance = NULL; } free(instance); } // Initialize all components int utun_instance_init(utun_instance_t *instance) { if (!instance || !instance->config) return -1; // Initialize TUN device if (tun_create(&instance->tun) < 0) { fprintf(stderr, "Failed to create TUN device\n"); return -1; } // Configure TUN device if (tun_set_ip(instance->tun.ifname, instance->config->global.tun_ip) < 0) { fprintf(stderr, "Failed to set TUN IP\n"); tun_close(&instance->tun); return -1; } if (instance->config->global.mtu > 0) { if (tun_set_mtu(instance->tun.ifname, instance->config->global.mtu) < 0) { fprintf(stderr, "Failed to set TUN MTU\n"); tun_close(&instance->tun); return -1; } } if (tun_set_up(instance->tun.ifname) < 0) { fprintf(stderr, "Failed to bring up TUN interface\n"); tun_close(&instance->tun); return -1; } // Create routing table instance->routing_table = routing_table_create(); if (!instance->routing_table) { fprintf(stderr, "Failed to create routing table\n"); return -1; } // Subnets configuration will be added later from connection configs // For now just return success return 0; } // Start main event loop int utun_instance_run(utun_instance_t *instance) { if (!instance || !instance->ua) return -1; instance->running = 1; // Run main loop while (instance->running) { uasync_poll(instance->ua, 1000); // 100ms timeout } return 0; } // Stop instance void utun_instance_stop(utun_instance_t *instance) { if (!instance) return; instance->running = 0; // Wakeup main loop using built-in uasync wakeup if (instance->ua) { uasync_wakeup(instance->ua); } } // Global instance access utun_instance_t* utun_instance_get(void) { return g_instance; } void utun_instance_set(utun_instance_t *instance) { g_instance = instance; }