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.
184 lines
4.6 KiB
184 lines
4.6 KiB
// 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 <stdlib.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <errno.h> |
|
#include <unistd.h> |
|
|
|
// 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; |
|
} |