refactor
This commit is contained in:
1 parent
b27ea97055
commit
9d0223d3fa
19 files changed
+87
-1496
No files matched your search
+2
-6
@@ -636,11 +636,9 @@ void print_config(const struct utun_config *cfg) {
|
||||
printf("\nServers:\n");
|
||||
struct CFG_SERVER *s = cfg->servers;
|
||||
while (s) {
|
||||
char addr_buffer[64];
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&s->ip;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_buffer, sizeof(addr_buffer));
|
||||
printf(" %s: %s:%d (mark=%d, netif=%u, type=%u)\n",
|
||||
s->name, addr_buffer, ntohs(sin->sin_port),
|
||||
s->name, ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port),
|
||||
s->so_mark, s->netif_index, s->type);
|
||||
s = s->next;
|
||||
}
|
||||
@@ -652,10 +650,8 @@ void print_config(const struct utun_config *cfg) {
|
||||
struct CFG_CLIENT_LINK *link = c->links;
|
||||
int link_num = 1;
|
||||
while (link) {
|
||||
char addr_buffer[64];
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&link->remote_addr;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_buffer, sizeof(addr_buffer));
|
||||
printf(" Link %d: %s:%d (via %s)\n", link_num++, addr_buffer, ntohs(sin->sin_port), link->local_srv->name);
|
||||
printf(" Link %d: %s:%d (via %s)\n", link_num++, ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port), link->local_srv->name);
|
||||
link = link->next;
|
||||
}
|
||||
printf(" Peer key: %s\n", c->peer_public_key_hex);
|
||||
|
||||
@@ -209,17 +209,14 @@ int control_server_init(struct control_server* server,
|
||||
return -1;
|
||||
}
|
||||
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
if (family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)bind_addr;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Control server listening on %s:%d",
|
||||
addr_str, ntohs(sin->sin_port));
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
} else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)bind_addr;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, addr_str, sizeof(addr_str));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Control server listening on [%s]:%d",
|
||||
addr_str, ntohs(sin6->sin6_port));
|
||||
ip_to_str(&sin6->sin6_addr, AF_INET6).str, ntohs(sin6->sin6_port));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -383,14 +380,14 @@ static void accept_callback(socket_t fd, void* arg) {
|
||||
client->next = server->clients;
|
||||
server->clients = client;
|
||||
server->client_count++;
|
||||
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
|
||||
const char* addr_str;
|
||||
if (client_addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&client_addr;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, sizeof(addr_str));
|
||||
addr_str = ip_to_str(&sin->sin_addr, AF_INET).str;
|
||||
} else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&client_addr;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, addr_str, sizeof(addr_str));
|
||||
addr_str = ip_to_str(&sin6->sin6_addr, AF_INET6).str;
|
||||
}
|
||||
|
||||
if (server->log_file) {
|
||||
|
||||
@@ -102,13 +102,6 @@ struct shaper_cb_arg {
|
||||
int dir_idx;
|
||||
};
|
||||
|
||||
/* Получить текущее время в timebase units (0.1 мс) */
|
||||
static inline uint64_t get_time_tb(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (uint64_t)ts.tv_sec * 10000ULL + (uint64_t)ts.tv_nsec / 100000ULL;
|
||||
}
|
||||
|
||||
/* Генерация случайного числа 0..max */
|
||||
static inline uint32_t random_range(uint32_t max) {
|
||||
if (max == 0) return 0;
|
||||
|
||||
+5
-19
@@ -66,22 +66,8 @@ static void drain_and_free_inflight_queue(struct ETCP_CONN* etcp, struct ll_queu
|
||||
*q = NULL;
|
||||
}
|
||||
|
||||
// Get current time in 0.1ms units
|
||||
uint64_t get_current_time_units() {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
uint64_t time_units = ((uint64_t)tv.tv_sec * 10000ULL) + (tv.tv_usec / 100);
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "get_current_time_units: tv_sec=%ld, tv_usec=%ld, result=%llu",
|
||||
// tv.tv_sec, tv.tv_usec, (unsigned long long)time_units);
|
||||
return time_units;
|
||||
}
|
||||
|
||||
uint16_t get_current_timestamp() {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
uint16_t timestamp = (uint16_t)(get_current_time_units() & 0xFFFF);
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "get_current_timestamp: result=%u", timestamp);
|
||||
return timestamp;
|
||||
return (uint16_t)get_time_tb();
|
||||
}
|
||||
|
||||
// Timestamp diff (with wrap-around)
|
||||
@@ -116,7 +102,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT));
|
||||
etcp->optimal_inflight=10000;
|
||||
// Initialize log_name with local node_id (peer will be updated later when known)
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04llu→????",
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04llu->????",
|
||||
(unsigned long long)(instance->node_id % 10000));
|
||||
|
||||
if (!etcp->input_queue || !etcp->output_queue || !etcp->input_send_q || !etcp->recv_q || !etcp->ack_q ||
|
||||
@@ -249,7 +235,7 @@ void etcp_update_log_name(struct ETCP_CONN* etcp) {
|
||||
if (!etcp || !etcp->instance) return;
|
||||
uint64_t local_id = etcp->instance->node_id % 10000;
|
||||
uint64_t peer_id = etcp->peer_node_id % 10000;
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04llu→%04llu",
|
||||
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04llu->%04llu",
|
||||
(unsigned long long)local_id, (unsigned long long)peer_id);
|
||||
}
|
||||
|
||||
@@ -443,7 +429,7 @@ static void input_send_q_cb(struct ll_queue* q, void* arg) {// etcp->input_send_
|
||||
static void ack_timeout_check(void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
uint64_t now = get_current_time_units();
|
||||
uint64_t now = get_time_tb();
|
||||
uint64_t timeout = 1000;//(uint64_t)(etcp->rtt_avg_10 * RETRANS_K1) + (uint64_t)(etcp->jitter * RETRANS_K2);
|
||||
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ack_timeout_check: starting check, now=%llu, timeout=%llu, rtt_avg_10=%u, jitter=%u",
|
||||
@@ -533,7 +519,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
|
||||
if (inf_pkt) {
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] prepare udp dgram for send packet %p (seq=%u, len=%u)", etcp->log_name, inf_pkt, inf_pkt->seq, inf_pkt->ll.len);
|
||||
|
||||
inf_pkt->last_timestamp=get_current_time_units();
|
||||
inf_pkt->last_timestamp=get_time_tb();
|
||||
inf_pkt->send_count++;
|
||||
inf_pkt->state=INFLIGHT_STATE_WAIT_ACK;
|
||||
queue_data_put(etcp->input_wait_ack, (struct ll_entry*)inf_pkt, inf_pkt->seq);// move dgram to wait_ack queue
|
||||
|
||||
@@ -21,7 +21,6 @@ struct UTUN_INSTANCE;
|
||||
struct UASYNC;
|
||||
|
||||
uint16_t get_current_timestamp(void);
|
||||
uint64_t get_current_time_units(void);
|
||||
|
||||
// ETCP packet section types (from protocol spec)
|
||||
#define ETCP_SECTION_PAYLOAD 0x00 // Data payload
|
||||
|
||||
+16
-35
@@ -88,9 +88,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) {
|
||||
// Debug: print remote address before sending
|
||||
if (link->remote_addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr;
|
||||
char addr_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] INIT sending to %s:%d, link=%p", addr_str, ntohs(sin->sin_port), link);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] INIT sending to %s:%d, link=%p", ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port), link);
|
||||
}
|
||||
|
||||
etcp_encrypt_send(dgram);
|
||||
@@ -215,7 +213,7 @@ static void keepalive_timer_cb(void* arg) {
|
||||
}
|
||||
|
||||
// Check keepalive timeout
|
||||
uint64_t now = get_current_time_units();
|
||||
uint64_t now = get_time_tb();
|
||||
uint64_t timeout_units = (uint64_t)link->keepalive_timeout * 10; // ms -> 0.1ms units
|
||||
uint64_t elapsed = now - link->last_recv_local_time;
|
||||
|
||||
@@ -471,9 +469,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
|
||||
ip->ss_family, socket_strerror(socket_get_error()));
|
||||
if (ip->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)ip;
|
||||
char addr_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[ETCP] Failed to bind to %s:%d", addr_str, ntohs(sin->sin_port));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[ETCP] Failed to bind to %s:%d", ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
}
|
||||
socket_close_wrapper(e_sock->fd);
|
||||
free(e_sock);
|
||||
@@ -481,10 +477,8 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
|
||||
}
|
||||
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)ip;
|
||||
char addr_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN);
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Successfully bound socket to local address, family=%d %s:%d", ip->ss_family, addr_str, ntohs(sin->sin_port));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Successfully bound socket to local address, family=%d %s:%d", ip->ss_family, ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
}
|
||||
|
||||
e_sock->instance = instance;
|
||||
@@ -585,7 +579,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
||||
// link->last_activity = time(NULL);
|
||||
|
||||
link->ip_port_hash = sockaddr_hash(remote_addr);
|
||||
link->last_recv_local_time = get_current_time_units(); // Initialize to prevent immediate timeout
|
||||
link->last_recv_local_time = get_time_tb(); // Initialize to prevent immediate timeout
|
||||
|
||||
insert_link(conn, link);
|
||||
|
||||
@@ -723,9 +717,7 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
// Debug: print where we're sending the packet
|
||||
if (addr->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
|
||||
char addr_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN);
|
||||
// DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Sending packet to %s:%d, size=%zd", addr_str, ntohs(sin->sin_port), enc_buf_len + dgram->noencrypt_len);
|
||||
// inet_ntop removed - use ip_to_str
|
||||
}
|
||||
|
||||
ssize_t sent = socket_sendto(dgram->link->conn->fd, enc_buf, enc_buf_len + dgram->noencrypt_len,
|
||||
@@ -870,9 +862,8 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
memcpy(&conn->crypto_ctx, &sc, sizeof(sc));// добавляем ключ
|
||||
conn->peer_node_id=peer_id;
|
||||
etcp_update_log_name(conn); // Update log_name with peer_node_id
|
||||
char buf[128];
|
||||
addr_to_string(&addr, buf, sizeof(buf));
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "New connection from %s peer_id=%ld etcp=%p", buf, peer_id, conn);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "New connection from %s peer_id=%ld etcp=%p",
|
||||
ip_to_str(&addr, addr.ss_family).str, peer_id, conn);
|
||||
// Add connection to instance list
|
||||
conn->next = e_sock->instance->connections;
|
||||
e_sock->instance->connections = conn;
|
||||
@@ -993,7 +984,7 @@ process_decrypted:
|
||||
if ( link->remote_keepalive && !link->link_status && link->initialized) loadbalancer_link_ready(link);// up выставляем только если и remote=up и local=up
|
||||
link->link_status=link->remote_keepalive;
|
||||
|
||||
link->last_recv_local_time=get_current_time_units();
|
||||
link->last_recv_local_time=get_time_tb();
|
||||
link->last_recv_timestamp=pkt->timestamp;
|
||||
link->last_recv_updated=1;
|
||||
|
||||
@@ -1036,33 +1027,23 @@ process_decrypted:
|
||||
// First time receiving NAT info
|
||||
link->nat_ip = new_nat_ip;
|
||||
link->nat_port = new_nat_port;
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(new_nat_ip);
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] NAT address initialized: %s:%u",
|
||||
link->etcp->log_name, ip_str, new_nat_port);
|
||||
link->etcp->log_name, ip_to_str(&addr, AF_INET).str, new_nat_port);
|
||||
} else if (link->nat_ip != new_nat_ip || link->nat_port != new_nat_port) {
|
||||
// NAT address changed
|
||||
char old_ip_str[INET_ADDRSTRLEN], new_ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr old_addr, new_addr;
|
||||
old_addr.s_addr = htonl(link->nat_ip);
|
||||
new_addr.s_addr = htonl(new_nat_ip);
|
||||
inet_ntop(AF_INET, &old_addr, old_ip_str, sizeof(old_ip_str));
|
||||
inet_ntop(AF_INET, &new_addr, new_ip_str, sizeof(new_ip_str));
|
||||
|
||||
link->nat_ip = new_nat_ip;
|
||||
link->nat_port = new_nat_port;
|
||||
link->nat_changes_count++;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] NAT address changed: %s:%u -> %s:%u (change #%u)",
|
||||
link->etcp->log_name, old_ip_str, link->nat_port, new_ip_str, new_nat_port,
|
||||
link->etcp->log_name, ip_to_str(&old_addr, AF_INET).str, link->nat_port, ip_to_str(&new_addr, AF_INET).str, new_nat_port,
|
||||
link->nat_changes_count);
|
||||
} else {
|
||||
// NAT address unchanged
|
||||
link->nat_hits_count++;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] NAT address unchanged (%u matches)",
|
||||
link->etcp->log_name, link->nat_hits_count);
|
||||
}
|
||||
} else {
|
||||
// Legacy format without NAT info
|
||||
@@ -1152,7 +1133,9 @@ int init_connections(struct UTUN_INSTANCE* instance) {
|
||||
|
||||
struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type);
|
||||
if (e_sock && default_ip != 0) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Server %s type %d ip=%08x", server->name, server->type, default_ip);
|
||||
struct in_addr addr;
|
||||
addr.s_addr = default_ip;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Server %s type %d ip=%s", server->name, server->type, ip_to_str(&addr, AF_INET).str);
|
||||
e_sock->local_defaultroute_ip = default_ip;
|
||||
}
|
||||
if (!e_sock) {
|
||||
@@ -1165,12 +1148,10 @@ int init_connections(struct UTUN_INSTANCE* instance) {
|
||||
char addr_str[INET6_ADDRSTRLEN + 6];
|
||||
if (server->ip.ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&server->ip;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN);
|
||||
sprintf(addr_str + strlen(addr_str), ":%d", ntohs(sin->sin_port));
|
||||
snprintf(addr_str, sizeof(addr_str), "%s:%d", ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
} else {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&server->ip;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, addr_str, INET6_ADDRSTRLEN);
|
||||
sprintf(addr_str + strlen(addr_str), ":%d", ntohs(sin6->sin6_port));
|
||||
snprintf(addr_str, sizeof(addr_str), "%s:%d", ip_to_str(&sin6->sin6_addr, AF_INET6).str, ntohs(sin6->sin6_port));
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Initialized server %s on %s (links: %zu)",
|
||||
|
||||
@@ -33,7 +33,7 @@ struct ETCP_LINK* etcp_loadbalancer_select_link(struct ETCP_CONN* etcp) {
|
||||
|
||||
struct ETCP_LINK* best = NULL;
|
||||
uint64_t min_load_tb = UINT64_MAX;
|
||||
uint64_t now_tb=get_current_time_units();
|
||||
uint64_t now_tb=get_time_tb();
|
||||
|
||||
struct ETCP_LINK* link = etcp->links;
|
||||
int link_index = 0;
|
||||
@@ -129,7 +129,7 @@ void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) {
|
||||
link->shaper_load_time_tb += carry;
|
||||
|
||||
// Check if exceeds burst -> schedule timer
|
||||
uint64_t now_tb=get_current_time_units();
|
||||
uint64_t now_tb=get_time_tb();
|
||||
if (link->shaper_load_time_tb >= now_tb + SHAPER_BURST_DELAY_TB) {
|
||||
uint64_t wait_tb = link->shaper_load_time_tb - now_tb;
|
||||
link->shaper_timer = uasync_set_timeout(link->etcp->instance->ua, wait_tb, link, shaper_timer_cb);
|
||||
|
||||
+10
-10
@@ -100,9 +100,9 @@ static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* en
|
||||
// Log destination IP
|
||||
uint32_t dst_ip = extract_dst_ip(ip_data, ip_len);
|
||||
if (dst_ip != 0) {
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &dst_ip, ip_str, sizeof(ip_str));
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "Packet from ETCP to %s", ip_str);
|
||||
struct in_addr addr;
|
||||
addr.s_addr = dst_ip;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "Packet from ETCP to %s", ip_to_str(&addr, AF_INET).str);
|
||||
}
|
||||
|
||||
// Allocate ETCP_FRAGMENT for TUN input_queue
|
||||
@@ -172,13 +172,13 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &dst_ip, ip_str, sizeof(ip_str));
|
||||
struct in_addr addr;
|
||||
addr.s_addr = dst_ip;
|
||||
|
||||
// Lookup route in routing table
|
||||
struct ROUTE_ARRAY* routes = route_table_lookup(instance->rt, dst_ip);
|
||||
if (!routes || routes->routes == 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "No route to %s, dropping packet", ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "No route to %s, dropping packet", ip_to_str(&addr, AF_INET).str);
|
||||
free(pkt->ll.dgram);
|
||||
memory_pool_free(instance->tun->pool, pkt);
|
||||
pkt = (struct ETCP_FRAGMENT*)queue_data_get(instance->tun->output_queue);
|
||||
@@ -188,7 +188,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
|
||||
// Use first (best) route
|
||||
struct ETCP_CONN* conn = routes->entries[0]->next_hop;
|
||||
if (!conn) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route to %s has no next_hop, dropping packet", ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Route to %s has no next_hop, dropping packet", ip_to_str(&addr, AF_INET).str);
|
||||
free(pkt->ll.dgram);
|
||||
memory_pool_free(instance->tun->pool, pkt);
|
||||
pkt = (struct ETCP_FRAGMENT*)queue_data_get(instance->tun->output_queue);
|
||||
@@ -197,7 +197,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
|
||||
|
||||
// Check connection has normalizer
|
||||
if (!conn->normalizer) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Connection for %s has no normalizer, dropping packet", ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Connection for %s has no normalizer, dropping packet", ip_to_str(&addr, AF_INET).str);
|
||||
free(pkt->ll.dgram);
|
||||
memory_pool_free(instance->tun->pool, pkt);
|
||||
pkt = (struct ETCP_FRAGMENT*)queue_data_get(instance->tun->output_queue);
|
||||
@@ -223,12 +223,12 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
|
||||
|
||||
// Send via etcp_send
|
||||
if (etcp_send(conn, entry) != 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "etcp_send failed for %s", ip_str);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "etcp_send failed for %s", ip_to_str(&addr, AF_INET).str);
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
} else {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "Forwarded packet to %s via ETCP conn [%s]",
|
||||
ip_str, conn->log_name);
|
||||
ip_to_str(&addr, AF_INET).str, conn->log_name);
|
||||
}
|
||||
|
||||
// Free original TUN packet
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
/* sc_lib.c - Secure Channel library implementation using TinyCrypt */
|
||||
|
||||
#include "secure_channel.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/ecc.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/ecc_dh.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/aes.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/ccm_mode.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/constants.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/ecc_platform_specific.h"
|
||||
#include "../tinycrypt/lib/include/tinycrypt/sha256.h"
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Simple debug macros
|
||||
#define DEBUG_CATEGORY_CRYPTO 1
|
||||
#define DEBUG_ERROR(category, fmt, ...) fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__)
|
||||
#define DEBUG_INFO(category, fmt, ...) fprintf(stdout, "INFO: " fmt "\n", ##__VA_ARGS__)
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "crc32.h"
|
||||
|
||||
static const struct uECC_Curve_t *curve = NULL;
|
||||
static uint8_t sc_urandom_seed[8] = {0};
|
||||
static int sc_urandom_initialized = 0;
|
||||
|
||||
static void sc_init_random_seed(void)
|
||||
{
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
ssize_t ret = read(fd, sc_urandom_seed, 8);
|
||||
close(fd);
|
||||
if (ret == 8) {
|
||||
sc_urandom_initialized = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int sc_rng(uint8_t *dest, unsigned size)
|
||||
{
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t ret = read(fd, dest, size);
|
||||
close(fd);
|
||||
if (ret != size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mix in PID and microtime for additional entropy */
|
||||
pid_t pid = getpid();
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
dest[i] ^= ((pid >> (i % (sizeof(pid) * 8))) & 0xFF);
|
||||
dest[i] ^= ((tv.tv_sec >> (i % (sizeof(tv.tv_sec) * 8))) & 0xFF);
|
||||
dest[i] ^= ((tv.tv_usec >> (i % (sizeof(tv.tv_usec) * 8))) & 0xFF);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sc_validate_key(const uint8_t *public_key)
|
||||
{
|
||||
if (!curve) {
|
||||
curve = uECC_secp256r1();
|
||||
}
|
||||
int result = uECC_valid_public_key(public_key, curve);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CRYPTO, "sc_validate_key: uECC_valid_public_key returned %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
sc_status_t sc_generate_keypair(struct SC_MYKEYS *pk)
|
||||
{
|
||||
if (!pk) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!curve) {
|
||||
curve = uECC_secp256r1();
|
||||
}
|
||||
|
||||
/* Set custom RNG function */
|
||||
uECC_set_rng(sc_rng);
|
||||
|
||||
if (!uECC_make_key(pk->public_key, pk->private_key, curve)) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
// Конвертация hex строки в бинарный формат
|
||||
static int hex_to_binary(const char *hex_str, uint8_t *binary, size_t binary_len) {
|
||||
if (!hex_str || !binary || strlen(hex_str) != binary_len * 2) return -1;
|
||||
|
||||
for (size_t i = 0; i < binary_len; i++) {
|
||||
unsigned int byte;
|
||||
if (sscanf(hex_str + i * 2, "%2x", &byte) != 1) return -1;
|
||||
binary[i] = (uint8_t)byte;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc_status_t sc_init_local_keys(struct SC_MYKEYS *mykeys, const char *public_key, const char *private_key) {
|
||||
if (!mykeys || !public_key || !private_key) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: invalid arguments");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!curve) {
|
||||
curve = uECC_secp256r1();
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: public_key len=%zu, private_key len=%zu",
|
||||
strlen(public_key), strlen(private_key));
|
||||
|
||||
/* Convert hex to binary first */
|
||||
if (hex_to_binary(public_key, mykeys->public_key, SC_PUBKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: failed to convert public key from hex");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
if (hex_to_binary(private_key, mykeys->private_key, SC_PRIVKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: failed to convert private key from hex");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Validate the converted binary public key */
|
||||
if (sc_validate_key(mykeys->public_key) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: public key validation failed");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CRYPTO, "sc_init_local_keys: keys initialized successfully");
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
sc_status_t sc_init_ctx(sc_context_t *ctx, struct SC_MYKEYS *mykeys) {
|
||||
|
||||
ctx->pk=mykeys;
|
||||
ctx->initialized = 1;
|
||||
ctx->peer_key_set = 0;
|
||||
ctx->session_ready = 0;
|
||||
ctx->tx_counter = 0;
|
||||
ctx->rx_counter = 0;
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const char *peer_public_key_h, int mode) {
|
||||
uint8_t shared_secret[SC_SHARED_SECRET_SIZE];
|
||||
uint8_t peer_public_key[SC_PUBKEY_SIZE];
|
||||
|
||||
if (mode) {
|
||||
if (hex_to_binary(peer_public_key_h, peer_public_key, SC_PUBKEY_SIZE)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid hex key format");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
else memcpy(peer_public_key, peer_public_key_h, SC_PUBKEY_SIZE);
|
||||
|
||||
if (!ctx) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid ctx");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ctx->initialized) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: ctx not initialized");
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!curve) {
|
||||
curve = uECC_secp256r1();
|
||||
}
|
||||
|
||||
/* Validate peer public key */
|
||||
if (sc_validate_key(peer_public_key) != 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: invalid key");
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Compute shared secret using ECDH */
|
||||
if (!ctx->pk) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: no private key");
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
if (!uECC_shared_secret(peer_public_key, ctx->pk->private_key,
|
||||
shared_secret, curve)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_set_peer_public_key: shared secret error");
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Derive session key from shared secret (simple copy for demo) */
|
||||
memcpy(ctx->session_key, shared_secret, SC_SESSION_KEY_SIZE);
|
||||
|
||||
/* Store peer public key */
|
||||
memcpy(ctx->peer_public_key, peer_public_key, SC_PUBKEY_SIZE);
|
||||
ctx->peer_key_set = 1;
|
||||
|
||||
ctx->session_ready = 1;
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
static void sc_build_nonce(uint64_t counter, uint8_t *nonce_out)
|
||||
{
|
||||
struct tc_sha256_state_struct sha_ctx;
|
||||
uint8_t hash[32];
|
||||
struct timeval tv;
|
||||
uint8_t data[8 + 8 + 8];
|
||||
|
||||
if (!sc_urandom_initialized) {
|
||||
sc_init_random_seed();
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
memcpy(data, sc_urandom_seed, 8);
|
||||
data[8] = (counter >> 0) & 0xFF;
|
||||
data[9] = (counter >> 8) & 0xFF;
|
||||
data[10] = (counter >> 16) & 0xFF;
|
||||
data[11] = (counter >> 24) & 0xFF;
|
||||
data[12] = (counter >> 32) & 0xFF;
|
||||
data[13] = (counter >> 40) & 0xFF;
|
||||
data[14] = (counter >> 48) & 0xFF;
|
||||
data[15] = (counter >> 56) & 0xFF;
|
||||
data[16] = (tv.tv_sec >> 0) & 0xFF;
|
||||
data[17] = (tv.tv_sec >> 8) & 0xFF;
|
||||
data[18] = (tv.tv_sec >> 16) & 0xFF;
|
||||
data[19] = (tv.tv_sec >> 24) & 0xFF;
|
||||
data[20] = (tv.tv_usec >> 0) & 0xFF;
|
||||
data[21] = (tv.tv_usec >> 8) & 0xFF;
|
||||
data[22] = (tv.tv_usec >> 16) & 0xFF;
|
||||
data[23] = (tv.tv_usec >> 24) & 0xFF;
|
||||
|
||||
tc_sha256_init(&sha_ctx);
|
||||
tc_sha256_update(&sha_ctx, data, 24);
|
||||
tc_sha256_final(hash, &sha_ctx);
|
||||
|
||||
memcpy(nonce_out, hash, SC_NONCE_SIZE);
|
||||
}
|
||||
|
||||
sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len) {
|
||||
uint8_t nonce[SC_NONCE_SIZE];
|
||||
uint8_t plaintext_with_crc[plaintext_len + SC_CRC32_SIZE];
|
||||
size_t total_plaintext_len = plaintext_len + SC_CRC32_SIZE;
|
||||
uint8_t combined_output[total_plaintext_len + SC_TAG_SIZE];
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
struct tc_ccm_mode_struct ccm_state;
|
||||
|
||||
if (!ctx || !plaintext || !ciphertext || !ciphertext_len) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ctx->session_ready) {
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (plaintext_len == 0) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Добавляем CRC32 к данным */
|
||||
memcpy(plaintext_with_crc, plaintext, plaintext_len);
|
||||
uint32_t crc = crc32_calc(plaintext, plaintext_len);
|
||||
plaintext_with_crc[plaintext_len] = (crc >> 0) & 0xFF;
|
||||
plaintext_with_crc[plaintext_len + 1] = (crc >> 8) & 0xFF;
|
||||
plaintext_with_crc[plaintext_len + 2] = (crc >> 16) & 0xFF;
|
||||
plaintext_with_crc[plaintext_len + 3] = (crc >> 24) & 0xFF;
|
||||
|
||||
/* Генерируем nonce с таймером */
|
||||
sc_build_nonce(ctx->tx_counter, nonce);
|
||||
|
||||
/* Initialize AES key schedule */
|
||||
if (tc_aes128_set_encrypt_key(&sched, ctx->session_key) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Configure CCM mode */
|
||||
if (tc_ccm_config(&ccm_state, &sched, nonce, SC_NONCE_SIZE, SC_TAG_SIZE) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Encrypt and generate tag */
|
||||
if (tc_ccm_generation_encryption(combined_output, sizeof(combined_output),
|
||||
NULL, 0, /* no associated data */
|
||||
plaintext_with_crc, total_plaintext_len,
|
||||
&ccm_state) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Copy nonce + ciphertext + tag to output buffer */
|
||||
memcpy(ciphertext, nonce, SC_NONCE_SIZE);
|
||||
memcpy(ciphertext + SC_NONCE_SIZE, combined_output, total_plaintext_len + SC_TAG_SIZE);
|
||||
*ciphertext_len = SC_NONCE_SIZE + total_plaintext_len + SC_TAG_SIZE;
|
||||
|
||||
ctx->tx_counter++;
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
sc_status_t sc_decrypt(sc_context_t *ctx,
|
||||
const uint8_t *ciphertext,
|
||||
size_t ciphertext_len,
|
||||
uint8_t *plaintext,
|
||||
size_t *plaintext_len)
|
||||
{
|
||||
uint8_t nonce[SC_NONCE_SIZE];
|
||||
struct tc_aes_key_sched_struct sched;
|
||||
struct tc_ccm_mode_struct ccm_state;
|
||||
size_t total_plaintext_len = ciphertext_len - SC_NONCE_SIZE - SC_TAG_SIZE;
|
||||
uint8_t plaintext_with_crc[total_plaintext_len];
|
||||
|
||||
if (!ctx || !ciphertext || !plaintext || !plaintext_len) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!ctx->session_ready) {
|
||||
return SC_ERR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (ciphertext_len < SC_NONCE_SIZE + SC_TAG_SIZE + SC_CRC32_SIZE) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Извлекаем nonce из начала ciphertext */
|
||||
memcpy(nonce, ciphertext, SC_NONCE_SIZE);
|
||||
|
||||
/* Ciphertext для расшифровки начинается после nonce */
|
||||
const uint8_t *encrypted_data = ciphertext + SC_NONCE_SIZE;
|
||||
size_t encrypted_len = ciphertext_len - SC_NONCE_SIZE;
|
||||
|
||||
/* Initialize AES key schedule */
|
||||
if (tc_aes128_set_encrypt_key(&sched, ctx->session_key) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Configure CCM mode с извлечённым nonce */
|
||||
if (tc_ccm_config(&ccm_state, &sched, nonce, SC_NONCE_SIZE, SC_TAG_SIZE) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
|
||||
/* Decrypt and verify tag */
|
||||
if (tc_ccm_decryption_verification(plaintext_with_crc, total_plaintext_len,
|
||||
NULL, 0, /* no associated data */
|
||||
encrypted_data, encrypted_len,
|
||||
&ccm_state) != TC_CRYPTO_SUCCESS) {
|
||||
return SC_ERR_AUTH_FAILED;
|
||||
}
|
||||
|
||||
/* Проверяем CRC32 */
|
||||
size_t data_len = total_plaintext_len - SC_CRC32_SIZE;
|
||||
uint32_t expected_crc = crc32_calc(plaintext_with_crc, data_len);
|
||||
uint32_t received_crc = (plaintext_with_crc[data_len] << 0) |
|
||||
(plaintext_with_crc[data_len + 1] << 8) |
|
||||
(plaintext_with_crc[data_len + 2] << 16) |
|
||||
(plaintext_with_crc[data_len + 3] << 24);
|
||||
|
||||
if (expected_crc != received_crc) {
|
||||
return SC_ERR_CRC_FAILED;
|
||||
}
|
||||
|
||||
/* Копируем данные без CRC32 */
|
||||
memcpy(plaintext, plaintext_with_crc, data_len);
|
||||
*plaintext_len = data_len;
|
||||
|
||||
ctx->rx_counter++;
|
||||
|
||||
return SC_OK;
|
||||
}
|
||||
|
||||
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key) {
|
||||
if (!private_key || !public_key) {
|
||||
return SC_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!curve) {
|
||||
curve = uECC_secp256r1();
|
||||
}
|
||||
|
||||
if (!uECC_compute_public_key(private_key, public_key, curve)) {
|
||||
return SC_ERR_CRYPTO;
|
||||
}
|
||||
return SC_OK;
|
||||
}
|
||||
+1
-3
@@ -124,9 +124,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
|
||||
|
||||
char ip_str[64];
|
||||
if (config->global.tun_ip.family == AF_INET) {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &config->global.tun_ip.addr.v4, buf, sizeof(buf));
|
||||
snprintf(ip_str, sizeof(ip_str), "%s/32", buf);
|
||||
snprintf(ip_str, sizeof(ip_str), "%s/32", ip_to_str(&config->global.tun_ip.addr.v4, AF_INET).str);
|
||||
} else {
|
||||
free(tun);
|
||||
return NULL;
|
||||
|
||||
+4
-16
@@ -127,16 +127,12 @@ static int netlink_route(int ifindex, uint32_t network, uint8_t prefix_len, int
|
||||
|
||||
// Fallback: use ip route command
|
||||
static int ip_route_cmd(const char *ifname, uint32_t network, uint8_t prefix_len, const char *cmd) {
|
||||
char network_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = network;
|
||||
if (!inet_ntop(AF_INET, &addr, network_str, sizeof(network_str))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char cmdline[256];
|
||||
snprintf(cmdline, sizeof(cmdline), "ip route %s %s/%d dev %s 2>/dev/null",
|
||||
cmd, network_str, prefix_len, ifname);
|
||||
cmd, ip_to_str(&addr, AF_INET).str, prefix_len, ifname);
|
||||
|
||||
int ret = system(cmdline);
|
||||
return (ret == 0) ? 0 : -1;
|
||||
@@ -349,16 +345,12 @@ static int routing_socket_cmd(int ifindex, uint32_t network, uint8_t prefix_len,
|
||||
|
||||
// Fallback: use route command
|
||||
static int route_cmd(const char *ifname, uint32_t network, uint8_t prefix_len, const char *cmd) {
|
||||
char network_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(network);
|
||||
if (!inet_ntop(AF_INET, &addr, network_str, sizeof(network_str))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char cmdline[256];
|
||||
snprintf(cmdline, sizeof(cmdline), "route %s -net %s/%d -interface %s 2>/dev/null",
|
||||
cmd, network_str, prefix_len, ifname);
|
||||
cmd, ip_to_str(&addr, AF_INET).str, prefix_len, ifname);
|
||||
|
||||
int ret = system(cmdline);
|
||||
return (ret == 0) ? 0 : -1;
|
||||
@@ -422,18 +414,14 @@ int tun_route_add_all(const char *ifname, struct CFG_ROUTE_ENTRY *routes) {
|
||||
uint32_t network = ntohl(entry->ip.addr.v4.s_addr);
|
||||
if (entry->ip.family == AF_INET) {
|
||||
if (tun_route_add(ifname, network, entry->netmask) == 0) {
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = entry->ip.addr.v4.s_addr;
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Added route %s/%d via %s", ip_str, entry->netmask, ifname);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Added route %s/%d via %s", ip_to_str(&addr, AF_INET).str, entry->netmask, ifname);
|
||||
count++;
|
||||
} else {
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = entry->ip.addr.v4.s_addr;
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to add route %s/%d via %s", ip_str, entry->netmask, ifname);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to add route %s/%d via %s", ip_to_str(&addr, AF_INET).str, entry->netmask, ifname);
|
||||
}
|
||||
}
|
||||
entry = entry->next;
|
||||
|
||||
+4
-8
@@ -81,19 +81,15 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
|
||||
entry.destination_node_id = instance->node_id;
|
||||
|
||||
if (route_table_insert(instance->rt, &entry)) {
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(entry.network); // Convert back to network byte order for printing
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
addr.s_addr = htonl(entry.network);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Added local route: %s/%d",
|
||||
ip_str, entry.prefix_length);
|
||||
ip_to_str(&addr, AF_INET).str, entry.prefix_length);
|
||||
} else {
|
||||
char ip_str[INET_ADDRSTRLEN];
|
||||
struct in_addr addr;
|
||||
addr.s_addr = htonl(entry.network); // Convert back to network byte order for printing
|
||||
inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
|
||||
addr.s_addr = htonl(entry.network);
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Failed to add local route: %s/%d (skipping)",
|
||||
ip_str, entry.prefix_length);
|
||||
ip_to_str(&addr, AF_INET).str, entry.prefix_length);
|
||||
}
|
||||
|
||||
subnet = subnet->next;
|
||||
|
||||
Reference in new issue
Block a user