Browse Source

mem

nodeinfo-routing-update
jeka 4 weeks ago
parent
commit
15c7968c8c
  1. 4
      lib/Makefile.am
  2. 11
      lib/debug_config.c
  3. 25
      lib/ll_queue.c
  4. 11
      lib/memory_pool.c
  5. 12
      lib/timeout_heap.c
  6. 146
      lib/u_async.c
  7. 13
      lib/u_async.h
  8. 31
      src/config_parser.c
  9. 17
      src/config_updater.c
  10. 19
      src/control_server.c
  11. 21
      src/dummynet.c
  12. 6
      src/etcp.c
  13. 35
      src/etcp_connections.c
  14. 2
      src/etcp_connections.h
  15. 7
      src/etcp_loadbalancer.c
  16. 11
      src/pkt_normalizer.c
  17. 9
      src/route_bgp.c
  18. 37
      src/route_lib.c
  19. 19
      src/routing.c
  20. 35
      src/tun_if.c
  21. 1
      src/tun_linux.c
  22. 7
      src/tun_route.c
  23. 13
      src/tun_windows.c
  24. 1
      src/utun.c
  25. 17
      src/utun_instance.c
  26. 17
      tests/test_etcp_dummynet.c
  27. 21
      tests/test_etcp_link_id.c
  28. 5
      tests/test_offset.c
  29. 9
      tests/test_pkt_normalizer_etcp.c
  30. 5
      tests/test_pkt_normalizer_standalone.c
  31. 3
      tests/test_route_lib.c
  32. 19
      tests/test_routing_mesh.c
  33. 2
      tests/test_u_async_comprehensive.c
  34. 25
      tests/test_u_async_performance.c

4
lib/Makefile.am

@ -16,7 +16,9 @@ libuasync_a_SOURCES = \
socket_compat.c \
socket_compat.h \
platform_compat.c \
platform_compat.h
platform_compat.h \
mem.c \
mem.h
libuasync_a_CFLAGS = \
-D_ISOC99_SOURCE \

11
lib/debug_config.c

@ -4,6 +4,7 @@
#include "debug_config.h"
#include "platform_compat.h"
#include "mem.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@ -349,7 +350,7 @@ int debug_parse_config(const char* config_string) {
char* eq = strchr(token, '=');
if (!eq) {
free(str);
u_free(str);
return -1;
}
@ -372,7 +373,7 @@ int debug_parse_config(const char* config_string) {
debug_category_t cat = get_category_by_name(mod_token);
if (cat == DEBUG_CATEGORY_NONE) {
free(str);
u_free(str);
return -1;
}
categories |= cat;
@ -381,12 +382,12 @@ int debug_parse_config(const char* config_string) {
} else if (strcasecmp(key, "level") == 0) {
int lev_num = atoi(value);
if (lev_num < DEBUG_LEVEL_NONE || lev_num > DEBUG_LEVEL_TRACE) {
free(str);
u_free(str);
return -1;
}
level = (debug_level_t)lev_num;
} else {
free(str);
u_free(str);
return -1;
}
@ -395,6 +396,6 @@ int debug_parse_config(const char* config_string) {
debug_set_masks(categories, level);
free(str);
u_free(str);
return 0;
}

25
lib/ll_queue.c

@ -6,6 +6,7 @@
#include "ll_queue.h"
#include "u_async.h"
#include "debug_config.h"
#include "mem.h"
// Предварительные объявления внутренних функций
static void queue_resume_timeout_cb(void* arg);
@ -18,7 +19,7 @@ static void remove_from_hash(struct ll_queue* q, struct ll_entry* entry);
struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size) {
if (!ua) return NULL;
struct ll_queue* q = calloc(1, sizeof(struct ll_queue));
struct ll_queue* q = u_calloc(1, sizeof(struct ll_queue));
if (!q) return NULL;
q->ua = ua;
@ -27,9 +28,9 @@ struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size) {
// Создать хеш-таблицу если нужно
if (hash_size > 0) {
q->hash_table = calloc(hash_size, sizeof(struct ll_entry*));
q->hash_table = u_calloc(hash_size, sizeof(struct ll_entry*));
if (!q->hash_table) {
free(q);
u_free(q);
return NULL;
}
}
@ -45,7 +46,7 @@ struct ll_entry* ll_alloc_lldgram(uint16_t len) {
entry->len=0;
entry->memlen=len;
entry->dgram = malloc(len);
entry->dgram = u_malloc(len);
// entry->dgram_pool = NULL; - уже null (memset)
// entry->dgram_free_fn = NULL;
if (!entry->dgram) {
@ -63,11 +64,11 @@ void queue_free(struct ll_queue* q) {
q, q->head, q->tail, q->count);
// ВАЖНО: Не освобождаем элементы в очереди - они должны быть извлечены отдельно
// Это упрощает архитектуру и предотвращает double-free
// Это упрощает архитектуру и предотвращает double-u_free
// Освободить хеш-таблицу
if (q->hash_table) {
free(q->hash_table);
u_free(q->hash_table);
}
// Отменить отложенное возобновление
@ -76,7 +77,7 @@ void queue_free(struct ll_queue* q) {
q->resume_timeout_id = NULL;
}
free(q);
u_free(q);
}
// ==================== Конфигурация очереди ====================
@ -118,13 +119,13 @@ void queue_set_size_limit(struct ll_queue* q, int lim) {
// ==================== Управление элементами ====================
struct ll_entry* queue_entry_new(size_t data_size) {
struct ll_entry* entry = malloc(sizeof(struct ll_entry) + data_size);
struct ll_entry* entry = u_malloc(sizeof(struct ll_entry) + data_size);
if (!entry) return NULL;
memset(entry, 0, sizeof(struct ll_entry) + data_size);
entry->size = data_size;
entry->len = 0;
entry->pool = NULL; // Выделено через malloc
entry->pool = NULL; // Выделено через u_malloc
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_entry_new: created entry %p, size=%zu", entry, data_size);
@ -147,7 +148,7 @@ struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool) {
return entry;
}
//void ll_free_dgram(struct ll_entry* entry) {
//void ll_u_free_dgram(struct ll_entry* entry) {
void queue_dgram_free(struct ll_entry* entry) {
if (!entry) return;
@ -157,7 +158,7 @@ void queue_dgram_free(struct ll_entry* entry) {
} else if (entry->dgram_pool) {
memory_pool_free(entry->dgram_pool, entry->dgram);
} else {
free(entry->dgram);
u_free(entry->dgram);
}
entry->dgram = NULL;
entry->len = 0; // Опционально сброс len
@ -170,7 +171,7 @@ void queue_entry_free(struct ll_entry* entry) {
if (entry->pool) {
memory_pool_free(entry->pool, entry);
} else {
free(entry);
u_free(entry);
}
}

11
lib/memory_pool.c

@ -2,10 +2,11 @@
#include "memory_pool.h"
#include <stdlib.h>
#include <string.h>
#include "mem.h"
// Инициализировать пул памяти
struct memory_pool* memory_pool_init(size_t object_size) {
struct memory_pool* pool = calloc(1, sizeof(struct memory_pool));
struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool));
if (!pool) {
return NULL;
}
@ -33,7 +34,7 @@ void* memory_pool_alloc(struct memory_pool* pool) {
}
pool->allocations++;
return calloc(1, pool->object_size); // Используем calloc для инициализации нулями
return u_calloc(1, pool->object_size); // Используем calloc для инициализации нулями
}
// Освободить объект в пул или в free
@ -51,7 +52,7 @@ void memory_pool_free(struct memory_pool* pool, void* obj) {
}
// Иначе освободить через free
free(obj);
u_free(obj);
}
// Получить статистику пула
@ -77,11 +78,11 @@ void memory_pool_destroy(struct memory_pool* pool) {
void* obj = pool->free_head;
while (obj) {
void* next = *(void**)obj;
free(obj);
u_free(obj);
obj = next;
}
pool->free_head = NULL;
pool->free_count = 0;
free(pool);
u_free(pool);
}

12
lib/timeout_heap.c

@ -11,11 +11,11 @@
#define RIGHT_CHILD(i) (2 * (i) + 1)
TimeoutHeap *timeout_heap_create(size_t initial_capacity) {
TimeoutHeap *h = malloc(sizeof(TimeoutHeap));
TimeoutHeap *h = u_malloc(sizeof(TimeoutHeap));
if (!h) return NULL;
h->heap = malloc(sizeof(TimeoutEntry) * initial_capacity);
h->heap = u_malloc(sizeof(TimeoutEntry) * initial_capacity);
if (!h->heap) {
free(h);
u_free(h);
return NULL;
}
h->size = 0;
@ -37,8 +37,8 @@ void timeout_heap_destroy(TimeoutHeap *h) {
}
}
free(h->heap);
free(h);
u_free(h->heap);
u_free(h);
}
@ -56,7 +56,7 @@ static void bubble_up(TimeoutHeap *h, size_t i) {
int timeout_heap_push(TimeoutHeap *h, TimeoutTime expiration, void *data) {
if (h->size == h->capacity) {
size_t new_cap = h->capacity ? h->capacity * 2 : 1;
TimeoutEntry *new_heap = realloc(h->heap, sizeof(TimeoutEntry) * new_cap);
TimeoutEntry *new_heap = u_realloc(h->heap, sizeof(TimeoutEntry) * new_cap);
if (!new_heap) return -1; // Allocation failed
h->heap = new_heap;
h->capacity = new_cap;

146
lib/u_async.c

@ -3,6 +3,7 @@
#include "u_async.h"
#include "platform_compat.h"
#include "debug_config.h"
#include "mem.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -46,7 +47,7 @@ struct socket_node {
socket_t_callback_t write_cbk_sock; // For SOCK type
socket_callback_t except_cbk;
void* user_data;
int active; // 1 if socket is active, 0 if freed (for reuse)
int active; // 1 if socket is active, 0 if u_freed (for reuse)
};
// Array-based socket management for O(1) operations
@ -72,20 +73,20 @@ static struct socket_node* socket_array_get(struct socket_array* sa, int fd);
static struct socket_array* socket_array_create(int initial_capacity) {
if (initial_capacity < 4) initial_capacity = 4; // Minimum capacity
struct socket_array* sa = malloc(sizeof(struct socket_array));
struct socket_array* sa = u_malloc(sizeof(struct socket_array));
if (!sa) return NULL;
sa->sockets = calloc(initial_capacity, sizeof(struct socket_node));
sa->fd_to_index = calloc(initial_capacity, sizeof(int));
sa->index_to_fd = calloc(initial_capacity, sizeof(int));
sa->active_indices = calloc(initial_capacity, sizeof(int));
sa->sockets = u_calloc(initial_capacity, sizeof(struct socket_node));
sa->fd_to_index = u_calloc(initial_capacity, sizeof(int));
sa->index_to_fd = u_calloc(initial_capacity, sizeof(int));
sa->active_indices = u_calloc(initial_capacity, sizeof(int));
if (!sa->sockets || !sa->fd_to_index || !sa->index_to_fd || !sa->active_indices) {
free(sa->sockets);
free(sa->fd_to_index);
free(sa->index_to_fd);
free(sa->active_indices);
free(sa);
u_free(sa->sockets);
u_free(sa->fd_to_index);
u_free(sa->index_to_fd);
u_free(sa->active_indices);
u_free(sa);
return NULL;
}
@ -108,11 +109,11 @@ static struct socket_array* socket_array_create(int initial_capacity) {
static void socket_array_destroy(struct socket_array* sa) {
if (!sa) return;
free(sa->sockets);
free(sa->fd_to_index);
free(sa->index_to_fd);
free(sa->active_indices);
free(sa);
u_free(sa->sockets);
u_free(sa->fd_to_index);
u_free(sa->index_to_fd);
u_free(sa->active_indices);
u_free(sa);
}
static int socket_array_add_internal(struct socket_array* sa, int fd, socket_t sock, int type,
@ -129,17 +130,17 @@ static int socket_array_add_internal(struct socket_array* sa, int fd, socket_t s
int new_capacity = sa->capacity * 2;
if (fd >= new_capacity) new_capacity = fd + 16; // Ensure enough space
struct socket_node* new_sockets = realloc(sa->sockets, new_capacity * sizeof(struct socket_node));
int* new_fd_to_index = realloc(sa->fd_to_index, new_capacity * sizeof(int));
int* new_index_to_fd = realloc(sa->index_to_fd, new_capacity * sizeof(int));
int* new_active_indices = realloc(sa->active_indices, new_capacity * sizeof(int));
struct socket_node* new_sockets = u_realloc(sa->sockets, new_capacity * sizeof(struct socket_node));
int* new_fd_to_index = u_realloc(sa->fd_to_index, new_capacity * sizeof(int));
int* new_index_to_fd = u_realloc(sa->index_to_fd, new_capacity * sizeof(int));
int* new_active_indices = u_realloc(sa->active_indices, new_capacity * sizeof(int));
if (!new_sockets || !new_fd_to_index || !new_index_to_fd || !new_active_indices) {
// Allocation failed
free(new_sockets);
free(new_fd_to_index);
free(new_index_to_fd);
free(new_active_indices);
u_free(new_sockets);
u_free(new_fd_to_index);
u_free(new_index_to_fd);
u_free(new_active_indices);
return -1;
}
@ -162,7 +163,7 @@ static int socket_array_add_internal(struct socket_array* sa, int fd, socket_t s
// Check if FD already exists
if (sa->fd_to_index[fd] != -1) return -1; // FD already exists
// Find first free slot
// Find first u_free slot
int index = -1;
for (int i = 0; i < sa->capacity; i++) {
if (!sa->sockets[i].active) {
@ -171,7 +172,7 @@ static int socket_array_add_internal(struct socket_array* sa, int fd, socket_t s
}
}
if (index == -1) return -1; // No free slots (shouldn't happen)
if (index == -1) return -1; // No u_free slots (shouldn't happen)
// Add the socket
sa->sockets[index].fd = fd;
@ -272,13 +273,13 @@ static struct socket_node* socket_array_get_by_sock(struct socket_array* sa, soc
return &sa->sockets[index];
}
// Callback to free timeout node and update counters
// Callback to u_free timeout node and update counters
static void timeout_node_free_callback(void* user_data, void* data) {
struct UASYNC* ua = (struct UASYNC*)user_data;
struct timeout_node* node = (struct timeout_node*)data;
(void)node; // Not used directly, but keep for consistency
ua->timer_free_count++;
free(data);
u_free(data);
}
// Helper to get current time
@ -329,19 +330,20 @@ static void drain_wakeup_pipe(struct UASYNC* ua) {
}
}
// Process posted tasks (lock-free during execution)
// Process posted tasks (lock-u_free during execution)
static void process_posted_tasks(struct UASYNC* ua) {
if (!ua) return;
struct posted_task* list = NULL;
#ifdef _WIN32
EnterCriticalSection(&ua->posted_lock);
#else
pthread_mutex_lock(&ua->posted_lock);
#endif
list = ua->posted_tasks_head;
ua->posted_tasks_head = NULL;
ua->posted_tasks_head = ua->posted_tasks_tail = NULL;
#ifdef _WIN32
LeaveCriticalSection(&ua->posted_lock);
#else
@ -349,13 +351,14 @@ static void process_posted_tasks(struct UASYNC* ua) {
#endif
while (list) {
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "POSTed task get");
struct posted_task* t = list;
list = list->next;
if (t->callback) {
t->callback(t->arg);
}
free(t);
u_free(t);
}
}
@ -417,11 +420,11 @@ static void process_timeouts(struct UASYNC* ua) {
node->callback(node->arg);
}
// Always free the node after processing
// Always u_free the node after processing
if (node && node->ua) {
node->ua->timer_free_count++;
}
free(node);
u_free(node);
continue; // Process next expired timeout
}
}
@ -465,7 +468,7 @@ void* uasync_set_timeout(struct UASYNC* ua, int timeout_tb, void* arg, timeout_c
// DEBUG_DEBUG(DEBUG_CATEGORY_TIMERS, "uasync_set_timeout: timeout=%d.%d ms, arg=%p, callback=%p", timeout_tb/10, timeout_tb%10, arg, callback);
struct timeout_node* node = malloc(sizeof(struct timeout_node));
struct timeout_node* node = u_malloc(sizeof(struct timeout_node));
if (!node) {
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "uasync_set_timeout: failed to allocate node");
return NULL;
@ -486,7 +489,7 @@ void* uasync_set_timeout(struct UASYNC* ua, int timeout_tb, void* arg, timeout_c
// Add to heap
if (timeout_heap_push(ua->timeout_heap, node->expiration_ms, node) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "uasync_set_timeout: failed to push to heap");
free(node);
u_free(node);
ua->timer_free_count++; // Balance the alloc counter
return NULL;
}
@ -508,7 +511,7 @@ err_t uasync_cancel_timeout(struct UASYNC* ua, void* t_id) {
// Try to cancel from heap first
if (timeout_heap_cancel(ua->timeout_heap, node->expiration_ms, node) == 0) {
// Successfully marked as deleted - free will happen lazily in heap
// Successfully marked as deleted - u_free will happen lazily in heap
node->cancelled = 1;
node->callback = NULL;
// DEBUG_DEBUG(DEBUG_CATEGORY_TIMERS, "uasync_cancel_timeout: successfully cancelled timer %p from heap", node);
@ -666,7 +669,7 @@ static void rebuild_poll_fds(struct UASYNC* ua) {
int new_capacity = total_fds * 2;
if (new_capacity < 16) new_capacity = 16;
struct pollfd* new_poll_fds = realloc(ua->poll_fds, sizeof(struct pollfd) * new_capacity);
struct pollfd* new_poll_fds = u_realloc(ua->poll_fds, sizeof(struct pollfd) * new_capacity);
if (!new_poll_fds) return; // Keep old allocation on failure
ua->poll_fds = new_poll_fds;
@ -1091,7 +1094,7 @@ struct UASYNC* uasync_create(void) {
// Initialize socket platform (Winsock on Windows)
socket_platform_init();
struct UASYNC* ua = calloc(1, sizeof(struct UASYNC));
struct UASYNC* ua = u_calloc(1, sizeof(struct UASYNC));
if (!ua) return NULL;
ua->timer_alloc_count = 0;
@ -1120,7 +1123,7 @@ struct UASYNC* uasync_create(void) {
close(ua->wakeup_pipe[1]);
#endif
}
free(ua);
u_free(ua);
return NULL;
}
@ -1136,11 +1139,11 @@ struct UASYNC* uasync_create(void) {
close(ua->wakeup_pipe[1]);
#endif
}
free(ua);
u_free(ua);
return NULL;
}
// Set callback to free timeout nodes and update counters
// Set callback to u_free timeout nodes and update counters
timeout_heap_set_free_callback(ua->timeout_heap, ua, timeout_node_free_callback);
// Initialize epoll on Linux
@ -1171,7 +1174,7 @@ struct UASYNC* uasync_create(void) {
SOCKET w = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (r == INVALID_SOCKET || w == INVALID_SOCKET) {
DEBUG_ERROR(DEBUG_CATEGORY_UASYNC, "Failed to create wakeup sockets");
free(ua);
u_free(ua);
return NULL;
}
@ -1186,7 +1189,7 @@ struct UASYNC* uasync_create(void) {
closesocket(r);
closesocket(w);
DEBUG_ERROR(DEBUG_CATEGORY_UASYNC, "Wakeup socket setup failed: %d", WSAGetLastError());
free(ua);
u_free(ua);
return NULL;
}
@ -1206,7 +1209,7 @@ struct UASYNC* uasync_create(void) {
// POSIX pipe
if (pipe(ua->wakeup_pipe) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_UASYNC, "pipe() failed: %s", strerror(errno));
free(ua);
u_free(ua);
return NULL;
}
ua->wakeup_initialized = 1;
@ -1232,10 +1235,10 @@ void uasync_print_resources(struct UASYNC* ua, const char* prefix) {
}
printf("\n🔍 %s: UASYNC Resource Report for %p\n", prefix, ua);
printf(" Timer Statistics: allocated=%zu, freed=%zu, active=%zd\n",
printf(" Timer Statistics: allocated=%zu, u_freed=%zu, active=%zd\n",
ua->timer_alloc_count, ua->timer_free_count,
(ssize_t)(ua->timer_alloc_count - ua->timer_free_count));
printf(" Socket Statistics: allocated=%zu, freed=%zu, active=%zd\n",
printf(" Socket Statistics: allocated=%zu, u_freed=%zu, active=%zd\n",
ua->socket_alloc_count, ua->socket_free_count,
(ssize_t)(ua->socket_alloc_count - ua->socket_free_count));
@ -1288,10 +1291,10 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
if (ua->timer_alloc_count != ua->timer_free_count || ua->socket_alloc_count != ua->socket_free_count) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Memory leaks detected before cleanup: timers %zu/%zu, sockets %zu/%zu",
ua->timer_alloc_count, ua->timer_free_count, ua->socket_alloc_count, ua->socket_free_count);
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "Timer leak: allocated=%zu, freed=%zu, diff=%zd",
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "Timer leak: allocated=%zu, u_freed=%zu, diff=%zd",
ua->timer_alloc_count, ua->timer_free_count,
(ssize_t)(ua->timer_alloc_count - ua->timer_free_count));
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "Socket leak: allocated=%zu, freed=%zu, diff=%zd",
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "Socket leak: allocated=%zu, u_freed=%zu, diff=%zd",
ua->socket_alloc_count, ua->socket_free_count,
(ssize_t)(ua->socket_alloc_count - ua->socket_free_count));
// Continue cleanup, will abort after if leaks remain
@ -1299,16 +1302,16 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
// Free all remaining timeouts
if (ua->timeout_heap) {
size_t freed_count = 0;
size_t u_freed_count = 0;
while (1) {
TimeoutEntry entry;
if (timeout_heap_pop(ua->timeout_heap, &entry) != 0) break;
struct timeout_node* node = (struct timeout_node*)entry.data;
// Free all timer nodes (avoid double-free bug)
// Free all timer nodes (avoid double-u_free bug)
if (node) {
ua->timer_free_count++;
free(node);
u_free(node);
}
}
timeout_heap_destroy(ua->timeout_heap);
@ -1316,8 +1319,8 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
// Free all socket nodes using array approach
if (ua->sockets) {
// Count and free all active sockets
int freed_count = 0;
// Count and u_free all active sockets
int u_freed_count = 0;
for (int i = 0; i < ua->sockets->capacity; i++) {
if (ua->sockets->sockets[i].active) {
if (close_fds && ua->sockets->sockets[i].fd >= 0) {
@ -1332,10 +1335,10 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
#endif
}
ua->socket_free_count++;
freed_count++;
u_freed_count++;
}
}
DEBUG_DEBUG(DEBUG_CATEGORY_MEMORY, "Freed %d socket nodes in destroy", freed_count);
DEBUG_DEBUG(DEBUG_CATEGORY_MEMORY, "Freed %d socket nodes in destroy", u_freed_count);
socket_array_destroy(ua->sockets);
}
@ -1351,7 +1354,7 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
}
// Free cached poll_fds
free(ua->poll_fds);
u_free(ua->poll_fds);
// Close epoll fd on Linux
#if HAS_EPOLL
@ -1364,10 +1367,10 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
if (ua->timer_alloc_count != ua->timer_free_count || ua->socket_alloc_count != ua->socket_free_count) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Memory leaks detected after cleanup: timers %zu/%zu, sockets %zu/%zu",
ua->timer_alloc_count, ua->timer_free_count, ua->socket_alloc_count, ua->socket_free_count);
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "FINAL Timer leak: allocated=%zu, freed=%zu, diff=%zd",
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "FINAL Timer leak: allocated=%zu, u_freed=%zu, diff=%zd",
ua->timer_alloc_count, ua->timer_free_count,
(ssize_t)(ua->timer_alloc_count - ua->timer_free_count));
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "FINAL Socket leak: allocated=%zu, freed=%zu, diff=%zd",
DEBUG_ERROR(DEBUG_CATEGORY_TIMERS, "FINAL Socket leak: allocated=%zu, u_freed=%zu, diff=%zd",
ua->socket_alloc_count, ua->socket_free_count,
(ssize_t)(ua->socket_alloc_count - ua->socket_free_count));
abort();
@ -1378,7 +1381,7 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
while (ua->posted_tasks_head) {
struct posted_task* t = ua->posted_tasks_head;
ua->posted_tasks_head = t->next;
free(t);
u_free(t);
}
#ifdef _WIN32
DeleteCriticalSection(&ua->posted_lock);
@ -1386,7 +1389,7 @@ void uasync_destroy(struct UASYNC* ua, int close_fds) {
pthread_mutex_destroy(&ua->posted_lock);
#endif
free(ua);
u_free(ua);
// Cleanup socket platform (WSACleanup on Windows)
socket_platform_cleanup();
@ -1409,18 +1412,18 @@ void uasync_init_instance(struct UASYNC* ua) {
}
// Debug statistics
void uasync_get_stats(struct UASYNC* ua, size_t* timer_alloc, size_t* timer_free, size_t* socket_alloc, size_t* socket_free) {
void uasync_get_stats(struct UASYNC* ua, size_t* timer_alloc, size_t* timer_u_free, size_t* socket_alloc, size_t* socket_u_free) {
if (!ua) return;
if (timer_alloc) *timer_alloc = ua->timer_alloc_count;
if (timer_free) *timer_free = ua->timer_free_count;
if (timer_u_free) *timer_u_free = ua->timer_free_count;
if (socket_alloc) *socket_alloc = ua->socket_alloc_count;
if (socket_free) *socket_free = ua->socket_free_count;
if (socket_u_free) *socket_u_free = ua->socket_free_count;
}
void uasync_post(struct UASYNC* ua, uasync_post_callback_t callback, void* arg) {
if (!ua || !callback) return;
struct posted_task* task = malloc(sizeof(struct posted_task));
struct posted_task* task = u_malloc(sizeof(struct posted_task));
if (!task) return;
task->callback = callback;
@ -1432,15 +1435,22 @@ void uasync_post(struct UASYNC* ua, uasync_post_callback_t callback, void* arg)
#else
pthread_mutex_lock(&ua->posted_lock);
#endif
task->next = ua->posted_tasks_head;
ua->posted_tasks_head = task;
if (ua->posted_tasks_tail) {
// есть конец списка — добавляем туда
ua->posted_tasks_tail->next = task;
ua->posted_tasks_tail = task;
} else {
// список пустой — это первая задача
ua->posted_tasks_head = ua->posted_tasks_tail = task;
}
#ifdef _WIN32
LeaveCriticalSection(&ua->posted_lock);
#else
pthread_mutex_unlock(&ua->posted_lock);
#endif
// DEBUG_DEBUG(DEBUG_CATEGORY_TIMERS, "POST: wakeup send");
uasync_wakeup(ua); // будим mainloop
}
@ -1466,7 +1476,7 @@ int uasync_get_wakeup_fd(struct UASYNC* ua) {
return ua->wakeup_pipe[1];
}
/* Lookup socket by file descriptor - returns current pointer even after realloc */
/* Lookup socket by file descriptor - returns current pointer even after u_realloc */
int uasync_lookup_socket(struct UASYNC* ua, int fd, void** socket_id) {
if (!ua || !ua->sockets || !socket_id || fd < 0 || fd >= FD_SETSIZE) {
return -1;

13
lib/u_async.h

@ -27,6 +27,12 @@ typedef int err_t;
typedef void (*uasync_post_callback_t)(void* user_arg);
struct posted_task {
uasync_post_callback_t callback;
void* arg;
struct posted_task* next;
};
// Uasync instance structure
struct UASYNC {
TimeoutHeap* timeout_heap; // Heap for timeout management
@ -47,11 +53,8 @@ struct UASYNC {
// Epoll support (Linux only)
int epoll_fd; // epoll file descriptor (-1 if not using epoll)
int use_epoll; // 1 if using epoll, 0 if using poll
struct posted_task {
uasync_post_callback_t callback;
void* arg;
struct posted_task* next;
} *posted_tasks_head;
struct posted_task* posted_tasks_head;
struct posted_task* posted_tasks_tail;
#ifdef _WIN32
CRITICAL_SECTION posted_lock;

31
src/config_parser.c

@ -14,6 +14,7 @@
#include <ifaddrs.h>
#include <net/if.h>
#endif
#include "../lib/mem.h"
#define MAX_LINE_LEN 1024
#define INITIAL_ARRAY_CAPACITY 8
@ -73,7 +74,7 @@ static uint32_t parse_debug_categories(const char *value) {
token = strtok(NULL, ",");
}
free(value_copy);
u_free(value_copy);
return categories ? categories : DEBUG_CATEGORY_ALL; // Default to all if nothing parsed
}
@ -190,7 +191,7 @@ static uint32_t get_netif_index(const char *ifname) {
}
static struct CFG_CLIENT_LINK* create_client_link(struct CFG_SERVER* local_srv, const char *remote_addr) {
struct CFG_CLIENT_LINK *link = calloc(1, sizeof(struct CFG_CLIENT_LINK));
struct CFG_CLIENT_LINK *link = u_calloc(1, sizeof(struct CFG_CLIENT_LINK));
if (!link) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "create_client_link: failed to allocate memory for client link");
return NULL;
@ -199,7 +200,7 @@ static struct CFG_CLIENT_LINK* create_client_link(struct CFG_SERVER* local_srv,
link->local_srv = local_srv;
if (parse_address_and_port(remote_addr, &link->remote_addr) < 0) {
free(link);
u_free(link);
return NULL;
}
@ -210,20 +211,20 @@ static struct CFG_CLIENT_LINK* create_client_link(struct CFG_SERVER* local_srv,
static void free_cfg_client_links(struct CFG_CLIENT_LINK *links) {
while (links) {
struct CFG_CLIENT_LINK *next = links->next;
free(links);
u_free(links);
links = next;
}
}
static struct CFG_ROUTE_ENTRY* create_route_entry(const char *subnet_str) {
struct CFG_ROUTE_ENTRY *entry = calloc(1, sizeof(struct CFG_ROUTE_ENTRY));
struct CFG_ROUTE_ENTRY *entry = u_calloc(1, sizeof(struct CFG_ROUTE_ENTRY));
if (!entry) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "create_route_entry: failed to allocate memory for route entry");
return NULL;
}
if (parse_ip_with_netmask(subnet_str, &entry->ip, &entry->netmask) < 0) {
free(entry);
u_free(entry);
return NULL;
}
@ -234,7 +235,7 @@ static struct CFG_ROUTE_ENTRY* create_route_entry(const char *subnet_str) {
static void free_route_entries(struct CFG_ROUTE_ENTRY *entries) {
while (entries) {
struct CFG_ROUTE_ENTRY *next = entries->next;
free(entries);
u_free(entries);
entries = next;
}
}
@ -450,7 +451,7 @@ static section_type_t parse_section_header(const char *line, char *name, size_t
}
static struct utun_config* parse_config_internal(FILE *fp, const char *filename) {
struct utun_config *cfg = calloc(1, sizeof(struct utun_config));
struct utun_config *cfg = u_calloc(1, sizeof(struct utun_config));
if (!cfg) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "parse_config_internal: failed to allocate memory for config structure");
return NULL;
@ -490,14 +491,14 @@ static struct utun_config* parse_config_internal(FILE *fp, const char *filename)
cur_section = parse_section_header(trimmed, name, sizeof(name));
if (cur_section == SECTION_SERVER) {
cur_server = calloc(1, sizeof(struct CFG_SERVER));
cur_server = u_calloc(1, sizeof(struct CFG_SERVER));
if (!cur_server) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "parse_config_internal: failed to allocate memory for server %s", name);
goto error;
}
strcpy(cur_server->name, name);
} else if (cur_section == SECTION_CLIENT) {
cur_client = calloc(1, sizeof(struct CFG_CLIENT));
cur_client = u_calloc(1, sizeof(struct CFG_CLIENT));
if (!cur_client) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "parse_config_internal: failed to allocate memory for client %s", name);
goto error;
@ -573,10 +574,10 @@ static struct utun_config* parse_config_internal(FILE *fp, const char *filename)
return cfg;
error:
if (cur_server) free(cur_server);
if (cur_server) u_free(cur_server);
if (cur_client) {
free_cfg_client_links(cur_client->links);
free(cur_client);
u_free(cur_client);
}
free_config(cfg);
return NULL;
@ -603,7 +604,7 @@ void free_config(struct utun_config *config) {
struct CFG_SERVER *server = config->servers;
while (server) {
struct CFG_SERVER *next = server->next;
free(server);
u_free(server);
server = next;
}
@ -612,7 +613,7 @@ void free_config(struct utun_config *config) {
while (client) {
struct CFG_CLIENT *next = client->next;
free_cfg_client_links(client->links);
free(client);
u_free(client);
client = next;
}
@ -620,7 +621,7 @@ void free_config(struct utun_config *config) {
free_route_entries(config->route_subnets);
free_route_entries(config->my_subnets);
free(config);
u_free(config);
}
static const char* ip_to_string(const struct IP *ip, char *buffer, size_t buffer_size) {

17
src/config_updater.c

@ -12,6 +12,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "../lib/mem.h"
#define PRIV_HEXKEY_LEN 65 // 32 bytes * 2 hex chars + null
#define PUB_HEXKEY_LEN 129 // 64 bytes * 2 hex chars + null
@ -68,7 +69,7 @@ static int read_file_to_mem(const char *filename, char **buffer, size_t *size) {
fseek(fp, 0, SEEK_SET);
*buffer = malloc(file_size + 1);
*buffer = u_malloc(file_size + 1);
if (!*buffer) {
fclose(fp);
@ -79,7 +80,7 @@ static int read_file_to_mem(const char *filename, char **buffer, size_t *size) {
size_t read_size = fread(*buffer, 1, file_size, fp);
if (read_size != (size_t)file_size) {
free(*buffer);
u_free(*buffer);
fclose(fp);
@ -168,7 +169,7 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap
// Ensure buffer capacity
if (*buf_len + len_diff + 1 > *buf_capacity) {
*buf_capacity = *buf_len + len_diff + 1024;
char *new_buf = realloc(*buf, *buf_capacity);
char *new_buf = u_realloc(*buf, *buf_capacity);
if (!new_buf) return -1;
*buf = new_buf;
@ -214,7 +215,7 @@ static int insert_or_replace_option(char **buf, size_t *buf_len, size_t *buf_cap
// Ensure buffer capacity
if (*buf_len + new_len + 1 > *buf_capacity) {
*buf_capacity = *buf_len + new_len + 1024;
char *new_buf = realloc(*buf, *buf_capacity);
char *new_buf = u_realloc(*buf, *buf_capacity);
if (!new_buf) return -1;
*buf = new_buf;
@ -357,10 +358,10 @@ int config_ensure_keys_and_node_id(const char *filename) {
// Update config file
size_t buf_capacity = file_size + 1024;
char *work_buf = malloc(buf_capacity);
char *work_buf = u_malloc(buf_capacity);
if (!work_buf) {
free(file_buf);
u_free(file_buf);
return -1;
}
@ -404,9 +405,9 @@ int config_ensure_keys_and_node_id(const char *filename) {
}
}
free(file_buf);
u_free(file_buf);
free(work_buf);
u_free(work_buf);
return ret;

19
src/control_server.c

@ -11,6 +11,7 @@
#include "tun_if.h"
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#include <stdlib.h>
#include <string.h>
@ -332,7 +333,7 @@ static void accept_callback(socket_t fd, void* arg) {
}
/* Allocate client structure */
struct control_client* client = (struct control_client*)calloc(1, sizeof(*client));
struct control_client* client = (struct control_client*)u_calloc(1, sizeof(*client));
if (!client) {
if (server->log_file) {
fprintf(server->log_file, "%llu: [ERROR] Failed to allocate client structure\n",
@ -367,7 +368,7 @@ static void accept_callback(socket_t fd, void* arg) {
fflush(server->log_file);
}
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to register client socket with uasync");
free(client);
u_free(client);
#ifdef _WIN32
closesocket(client_fd);
#else
@ -526,7 +527,7 @@ static void close_client(struct control_server* server, struct control_client* c
}
server->client_count--;
free(client);
u_free(client);
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Control client disconnected (total: %u)",
server->client_count);
@ -642,7 +643,7 @@ static void send_conn_list(struct control_server* server, struct control_client*
/* Build response */
uint16_t rsp_size = ETCPMON_CONN_LIST_SIZE(count);
uint8_t* buffer = (uint8_t*)malloc(rsp_size);
uint8_t* buffer = (uint8_t*)u_malloc(rsp_size);
if (!buffer) {
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to allocate connection list buffer");
return;
@ -679,7 +680,7 @@ static void send_conn_list(struct control_server* server, struct control_client*
send(client->fd, buffer, rsp_size, 0);
#endif
free(buffer);
u_free(buffer);
}
static void send_metrics(struct control_server* server, struct control_client* client) {
@ -702,7 +703,7 @@ static void send_metrics(struct control_server* server, struct control_client* c
/* Build response */
uint16_t rsp_size = ETCPMON_METRICS_SIZE(links_count);
uint8_t* buffer = (uint8_t*)malloc(rsp_size);
uint8_t* buffer = (uint8_t*)u_malloc(rsp_size);
if (!buffer) {
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to allocate metrics buffer");
return;
@ -775,7 +776,7 @@ static void send_metrics(struct control_server* server, struct control_client* c
send(client->fd, buffer, rsp_size, 0);
#endif
free(buffer);
u_free(buffer);
}
static void send_error(struct control_client* client, uint8_t error_code, const char* msg) {
@ -783,7 +784,7 @@ static void send_error(struct control_client* client, uint8_t error_code, const
uint16_t msg_len = (uint16_t)strlen(msg);
uint16_t rsp_size = ETCPMON_ERROR_SIZE(msg_len);
uint8_t* buffer = (uint8_t*)malloc(rsp_size);
uint8_t* buffer = (uint8_t*)u_malloc(rsp_size);
if (!buffer) return;
struct etcpmon_msg_header* hdr = (struct etcpmon_msg_header*)buffer;
@ -808,7 +809,7 @@ static void send_error(struct control_client* client, uint8_t error_code, const
send(client->fd, buffer, rsp_size, 0);
#endif
free(buffer);
u_free(buffer);
}
/* ============================================================================

21
src/dummynet.c

@ -15,6 +15,7 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "../lib/mem.h"
/* Timebase: 0.1 мс */
#define TIMEBASE_US 100
@ -153,7 +154,7 @@ static void dummynet_process_queue(struct dummynet* dn, int dir_idx) {
if (delay_tb == 0) delay_tb = 1;
}
struct shaper_cb_arg* sarg = (struct shaper_cb_arg*)malloc(sizeof(struct shaper_cb_arg));
struct shaper_cb_arg* sarg = (struct shaper_cb_arg*)u_malloc(sizeof(struct shaper_cb_arg));
if (sarg) {
sarg->dn = dn;
sarg->dir_idx = dir_idx;
@ -161,7 +162,7 @@ static void dummynet_process_queue(struct dummynet* dn, int dir_idx) {
if (dir->shaper_timer) {
dir->shaper_timer_set++;
} else {
free(sarg);
u_free(sarg);
dir->shaper_pending = 0;
}
} else {
@ -177,7 +178,7 @@ static void dummynet_shaper_callback(void* user_arg) {
struct shaper_cb_arg* arg = (struct shaper_cb_arg*)user_arg;
struct dummynet* dn = arg->dn;
int dir_idx = arg->dir_idx;
free(arg);
u_free(arg);
dn->dirs[dir_idx].shaper_timer_fire++;
dummynet_process_queue(dn, dir_idx);
@ -259,7 +260,7 @@ static void dummynet_read_callback(socket_t sock, void* user_arg) {
dir_idx, n, delay_ms);
/* Создаём таймер задержки */
struct delay_cb_arg* targ = (struct delay_cb_arg*)malloc(sizeof(struct delay_cb_arg));
struct delay_cb_arg* targ = (struct delay_cb_arg*)u_malloc(sizeof(struct delay_cb_arg));
if (!targ) {
DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to allocate timer arg");
dir->stats.dropped++;
@ -273,7 +274,7 @@ static void dummynet_read_callback(socket_t sock, void* user_arg) {
if (!timer) {
DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to set delay timer");
dir->stats.dropped++;
free(targ);
u_free(targ);
queue_entry_free(entry);
return;
}
@ -285,7 +286,7 @@ static void dummynet_delay_callback(void* user_arg) {
struct delay_cb_arg* arg = (struct delay_cb_arg*)user_arg;
struct dummynet* dn = arg->dn;
struct ll_entry* entry = arg->entry;
free(arg);
u_free(arg);
struct dummynet_pkt* pkt = (struct dummynet_pkt*)entry->data;
int dir_idx = pkt->direction;
@ -321,7 +322,7 @@ static void dummynet_delay_callback(void* user_arg) {
/* Запускаем шейпер если не активен */
if (!dir->shaper_pending) {
dir->shaper_pending = 1;
struct shaper_cb_arg* sarg = (struct shaper_cb_arg*)malloc(sizeof(struct shaper_cb_arg));
struct shaper_cb_arg* sarg = (struct shaper_cb_arg*)u_malloc(sizeof(struct shaper_cb_arg));
if (sarg) {
sarg->dn = dn;
sarg->dir_idx = dir_idx;
@ -339,7 +340,7 @@ struct dummynet* dummynet_create(struct UASYNC* ua, const char* bind_ip, uint16_
return NULL;
}
struct dummynet* dn = (struct dummynet*)calloc(1, sizeof(struct dummynet));
struct dummynet* dn = (struct dummynet*)u_calloc(1, sizeof(struct dummynet));
if (!dn) {
DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to allocate dummynet context");
return NULL;
@ -352,7 +353,7 @@ struct dummynet* dummynet_create(struct UASYNC* ua, const char* bind_ip, uint16_
dn->pkt_pool = memory_pool_init(sizeof(struct ll_entry) + sizeof(struct dummynet_pkt));
if (!dn->pkt_pool) {
DEBUG_ERROR(DEBUG_CATEGORY_DUMMYNET, "Failed to create packet pool");
free(dn);
u_free(dn);
return NULL;
}
@ -447,7 +448,7 @@ void dummynet_destroy(struct dummynet* dn) {
memory_pool_destroy(dn->pkt_pool);
}
free(dn);
u_free(dn);
}
/* Настраивает параметры направления */

6
src/etcp.c

@ -14,6 +14,7 @@
#include <sys/time.h>
#include <math.h> // For bandwidth calcs
#include <limits.h> // For UINT16_MAX
#include "../lib/mem.h"
// Enable comprehensive debug output for ETCP module
#define DEBUG_CATEGORY_ETCP_DETAILED 1
@ -110,7 +111,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
if (!instance) return NULL;
struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN));
struct ETCP_CONN* etcp = u_calloc(1, sizeof(struct ETCP_CONN));
if (!etcp) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_connection_create: creating connection failed for instance %p", instance);
return NULL;
@ -241,7 +242,7 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
etcp->next = NULL;
// TODO: Free rx_list, etc.
free(etcp);
u_free(etcp);
}
// Reset connection
@ -682,6 +683,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
int chk=queue_check_consistency(etcp->ack_q);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] only ACK (size=%d) packet with %d bytes total (chk=%d) rem=%d", etcp->log_name, ack_q_size, ptr, chk, remain_len);
}
if (ptr>=PACKET_DATA_SIZE-50) DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] SIZE ERROR!!! %d", ptr);
dgram->data_len=ptr;

35
src/etcp_connections.c

@ -18,6 +18,7 @@
#include "etcp_loadbalancer.h"
#include <stdlib.h>
#include <time.h>
#include "../lib/mem.h"
// Forward declaration
static void etcp_connections_read_callback_socket(socket_t sock, void* arg);
@ -38,7 +39,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) {
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_init link=%p, is_server=%d, reset=%d", link, link ? link->is_server : -1, reset);
if (!link || !link->etcp || !link->etcp->instance) return;
struct ETCP_DGRAM* dgram = malloc(sizeof(struct ETCP_DGRAM) + 100);
struct ETCP_DGRAM* dgram = u_malloc(sizeof(struct ETCP_DGRAM) + 100);
if (!dgram) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_init: malloc failed");
return;
@ -94,7 +95,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) {
}
etcp_encrypt_send(dgram);
free(dgram);
u_free(dgram);
link->init_retry_count++;
@ -125,7 +126,7 @@ static void etcp_link_send_keepalive(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!link || !link->etcp || !link->etcp->instance) return;
struct ETCP_DGRAM* dgram = malloc(sizeof(struct ETCP_DGRAM) + 2);
struct ETCP_DGRAM* dgram = u_malloc(sizeof(struct ETCP_DGRAM) + 4);
if (!dgram) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_keepalive: malloc failed");
return;
@ -140,7 +141,7 @@ static void etcp_link_send_keepalive(struct ETCP_LINK* link) {
link->etcp->log_name, link, link->local_link_id);
etcp_encrypt_send(dgram);
free(dgram);
u_free(dgram);
}
// Check if all links for an ETCP_CONN are down
@ -260,7 +261,7 @@ static int etcp_link_send_reset(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!link) return -1;
struct ETCP_DGRAM* dgram = malloc(sizeof(struct ETCP_DGRAM) + 1);
struct ETCP_DGRAM* dgram = u_malloc(sizeof(struct ETCP_DGRAM) + 4);
if (!dgram) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_reset: malloc failed");
return -1;
@ -273,7 +274,7 @@ static int etcp_link_send_reset(struct ETCP_LINK* link) {
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Sending RESET to link");
int ret = etcp_encrypt_send(dgram);
free(dgram);
u_free(dgram);
return ret;
}
@ -309,7 +310,7 @@ static int find_link_index(struct ETCP_SOCKET* e_sock, uint32_t hash) {
static int realloc_links(struct ETCP_SOCKET* e_sock) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
size_t new_max = e_sock->max_channels == 0 ? 8 : e_sock->max_channels * 2;
struct ETCP_LINK** new_links = realloc(e_sock->links, new_max * sizeof(struct ETCP_LINK*));
struct ETCP_LINK** new_links = u_realloc(e_sock->links, new_max * sizeof(struct ETCP_LINK*));
if (!new_links) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "realloc_links: realloc failed");
return -1;
@ -410,7 +411,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!instance) return NULL;
struct ETCP_SOCKET* e_sock = calloc(1, sizeof(struct ETCP_SOCKET));
struct ETCP_SOCKET* e_sock = u_calloc(1, sizeof(struct ETCP_SOCKET));
if (!e_sock) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Failed to allocate connection");
return NULL;
@ -422,7 +423,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
family = ip->ss_family;
if (family != AF_INET && family != AF_INET6) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Unsupported address family: %d", family);
free(e_sock);
u_free(e_sock);
return NULL;
}
}
@ -431,7 +432,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
if (e_sock->fd == SOCKET_INVALID) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to create socket: %s",
socket_strerror(socket_get_error()));
free(e_sock);
u_free(e_sock);
return NULL;
}
@ -474,7 +475,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
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);
u_free(e_sock);
return NULL;
}
@ -501,7 +502,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
if (!e_sock->socket_id) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to register socket with uasync");
socket_close_wrapper(e_sock->fd);
free(e_sock);
u_free(e_sock);
return NULL;
}
@ -534,9 +535,9 @@ void etcp_socket_remove(struct ETCP_SOCKET* conn) {
for (size_t i = 0; i < conn->num_channels; i++) {
etcp_link_close(conn->links[i]);
}
free(conn->links);
u_free(conn->links);
free(conn);
u_free(conn);
}
@ -544,7 +545,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
if (!remote_addr) return NULL;
struct ETCP_LINK* link = calloc(1, sizeof(struct ETCP_LINK));
struct ETCP_LINK* link = u_calloc(1, sizeof(struct ETCP_LINK));
if (!link) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_new: calloc failed");
return NULL;
@ -576,7 +577,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
int free_id = etcp_find_free_local_link_id(etcp);
if (free_id < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_new: no free local_link_id available");
free(link);
u_free(link);
return NULL;
}
link->local_link_id = (uint8_t)free_id;
@ -635,7 +636,7 @@ void etcp_link_close(struct ETCP_LINK* link) {
remove_link(link->conn, link->ip_port_hash);
free(link);
u_free(link);
}
// Reset link state (for INIT_RESPONSE with reset)

2
src/etcp_connections.h

@ -8,7 +8,7 @@
#include "../lib/socket_compat.h"
#include <stdint.h>
#define PACKET_DATA_SIZE 1536
#define PACKET_DATA_SIZE 1600//1536
// Типы кодограмм протокола
#define ETCP_INIT_REQUEST 0x02

7
src/etcp_loadbalancer.c

@ -15,6 +15,7 @@
#include <stdint.h> // For UINT64_MAX
#include <time.h> // For timespec
#include <math.h> // For rounding
#include "../lib/mem.h"
// Enable comprehensive debug output for loadbalancer module
#define DEBUG_CATEGORY_LOADBALANCER 1
@ -83,7 +84,7 @@ void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) {
if (!etcp) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] no ETCP_CONN associated with dgram", etcp->log_name);
memory_pool_free(etcp->instance->pkt_pool, dgram);
// free(dgram);
// u_free(dgram);
return;
}
@ -93,7 +94,7 @@ void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) {
if (!dgram->link) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] no link available, dropping dgram", etcp->log_name);
memory_pool_free(etcp->instance->pkt_pool, dgram);
// free(dgram); // Assume free; adjust if pooled
// u_free(dgram); // Assume free; adjust if pooled
return;
}
}
@ -143,7 +144,7 @@ void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) {
// (unsigned long long)link->shaper_load_time_tb, (unsigned long long)link->shaper_sub_nanotime, link->shaper_timer==NULL?1:0);
memory_pool_free(etcp->instance->pkt_pool, dgram);
// free(dgram); // Free the dgram in all cases - we own it
// u_free(dgram); // Free the dgram in all cases - we own it
}
// New: Notify when link is ready (called from timer or external)

11
src/pkt_normalizer.c

@ -10,6 +10,7 @@
#include <string.h>
#include <stdio.h> // For debugging (can be removed if not needed)
#include "../lib/debug_config.h" // For DEBUG macros
#include "../lib/mem.h"
// Forward declarations
static void packer_cb(struct ll_queue* q, void* arg);
@ -26,7 +27,7 @@ struct PKTNORM* pn_init(struct ETCP_CONN* etcp) {
DEBUG_ERROR(DEBUG_CATEGORY_NORMALIZER, "pn_init: ETCP MTU error=%d", etcp->mtu);
}
struct PKTNORM* pn = calloc(1, sizeof(struct PKTNORM));
struct PKTNORM* pn = u_calloc(1, sizeof(struct PKTNORM));
if (!pn) {
DEBUG_ERROR(DEBUG_CATEGORY_NORMALIZER, "pn_init: calloc failed");
return NULL;
@ -79,7 +80,7 @@ void pn_deinit(struct PKTNORM* pn) {
struct ll_entry* entry;
while ((entry = queue_data_get(pn->input)) != NULL) {
if (entry->dgram) {
free(entry->dgram);
u_free(entry->dgram);
}
queue_entry_free(entry);
}
@ -89,7 +90,7 @@ void pn_deinit(struct PKTNORM* pn) {
struct ll_entry* entry;
while ((entry = queue_data_get(pn->output)) != NULL) {
if (entry->dgram) {
free(entry->dgram);
u_free(entry->dgram);
}
queue_entry_free(entry);
}
@ -119,7 +120,7 @@ void pn_deinit(struct PKTNORM* pn) {
}
}
free(pn);
u_free(pn);
}
// Reset unpacker state
@ -324,6 +325,8 @@ static void pn_unpacker_cb(struct ll_queue* q, void* arg) {
// DEBUG_INFO(DEBUG_CATEGORY_NORMALIZER, "pn_unpacker: new fragment pkt_len=%d (at %d)", part_size, ptr);
ptr += 2;
if (part_size<1 || part_size>1500) DEBUG_ERROR(DEBUG_CATEGORY_NORMALIZER, "PART_SIZE ERROR!!! %d", part_size);
pn->recvpart = ll_alloc_lldgram(part_size);
if (!pn->recvpart) {
DEBUG_ERROR(DEBUG_CATEGORY_NORMALIZER, "ll_alloc_lldgram failed");

9
src/route_bgp.c

@ -20,6 +20,7 @@
#include "utun_instance.h"
#include "config_parser.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
// Размер пакета (без заголовка ETCP)
#define BGP_PACKET_SIZE (sizeof(struct ROUTE_BGP_PACKET))
@ -450,7 +451,7 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance)
return NULL;
}
struct ROUTE_BGP* bgp = (struct ROUTE_BGP*)calloc(1, sizeof(struct ROUTE_BGP));
struct ROUTE_BGP* bgp = (struct ROUTE_BGP*)u_calloc(1, sizeof(struct ROUTE_BGP));
if (!bgp) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to allocate BGP structure");
return NULL;
@ -462,7 +463,7 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance)
bgp->senders_list = queue_new(instance->ua, 0);
if (!bgp->senders_list) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to create senders queue");
free(bgp);
u_free(bgp);
return NULL;
}
@ -470,7 +471,7 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance)
if (etcp_bind(instance, ETCP_ID_ROUTE_ENTRY, route_bgp_receive_cbk) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to bind ETCP callback");
queue_free(bgp->senders_list);
free(bgp);
u_free(bgp);
return NULL;
}
@ -510,7 +511,7 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance)
}
queue_free(instance->bgp->senders_list);
}
free(instance->bgp);
u_free(instance->bgp);
instance->bgp = NULL;
}

37
src/route_lib.c

@ -11,6 +11,7 @@
#include <string.h>
#include "../lib/platform_compat.h"
#include <time.h>
#include "../lib/mem.h"
#define INITIAL_ROUTE_CAPACITY 100
#define ROUTE_EXPANSION_FACTOR 2
@ -71,7 +72,7 @@ int parse_subnet(const char *subnet_str, uint32_t *network, uint8_t *prefix_leng
* @return Указатель на созданный массив или NULL
*/
static struct ROUTE_ARRAY* route_array_create(uint32_t capacity) {
struct ROUTE_ARRAY *array = calloc(1, sizeof(struct ROUTE_ARRAY) +
struct ROUTE_ARRAY *array = u_calloc(1, sizeof(struct ROUTE_ARRAY) +
capacity * sizeof(struct ROUTE_ENTRY*));
if (!array) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "route_array_create: failed to allocate memory");
@ -91,7 +92,7 @@ static void route_array_destroy(struct ROUTE_ARRAY *array) {
if (!array) return;
// entries[] содержит только указатели на ROUTE_ENTRY из таблицы,
// их освобождать не нужно - они принадлежат таблице
free(array);
u_free(array);
}
/**
@ -211,30 +212,30 @@ static const char *route_type_to_string(route_type_t type) {
}
struct ROUTE_TABLE *route_table_create(void) {
struct ROUTE_TABLE *table = calloc(1, sizeof(struct ROUTE_TABLE));
struct ROUTE_TABLE *table = u_calloc(1, sizeof(struct ROUTE_TABLE));
if (!table) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "route_table_create: failed to allocate memory for routing table");
return NULL;
}
table->capacity = INITIAL_ROUTE_CAPACITY;
table->entries = calloc(table->capacity, sizeof(struct ROUTE_ENTRY));
table->entries = u_calloc(table->capacity, sizeof(struct ROUTE_ENTRY));
if (!table->entries) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "route_table_create: failed to allocate memory for %zu route entries", table->capacity);
free(table);
u_free(table);
return NULL;
}
// Initialize subnet validation arrays
table->dynamic_subnets = calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t) * 2);
table->local_subnets = calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t) * 2);
table->dynamic_subnets = u_calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t) * 2);
table->local_subnets = u_calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t) * 2);
if (!table->dynamic_subnets || !table->local_subnets) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "route_table_create: failed to allocate memory for subnet validation arrays");
free(table->entries);
free(table->dynamic_subnets);
free(table->local_subnets);
free(table);
u_free(table->entries);
u_free(table->dynamic_subnets);
u_free(table->local_subnets);
u_free(table);
return NULL;
}
@ -245,13 +246,13 @@ void route_table_destroy(struct ROUTE_TABLE *table) {
if (!table) return;
// Free route entries
free(table->entries);
u_free(table->entries);
// Free validation ranges
free(table->dynamic_subnets);
free(table->local_subnets);
u_free(table->dynamic_subnets);
u_free(table->local_subnets);
free(table);
u_free(table);
}
/**
@ -327,7 +328,7 @@ bool route_table_insert(struct ROUTE_TABLE *table, const struct ROUTE_ENTRY *ent
// Check if we need to expand the table
if (table->count >= table->capacity) {
size_t new_capacity = table->capacity * ROUTE_EXPANSION_FACTOR;
struct ROUTE_ENTRY *new_entries = realloc(table->entries, new_capacity * sizeof(struct ROUTE_ENTRY));
struct ROUTE_ENTRY *new_entries = u_realloc(table->entries, new_capacity * sizeof(struct ROUTE_ENTRY));
if (!new_entries) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "route_table_insert: failed to expand routing table to %zu entries", new_capacity);
return false;
@ -570,7 +571,7 @@ static bool enhanced_route_add_subnet_range(struct ROUTE_TABLE *table, uint32_t
// Expand array if needed
if (*ranges == NULL) {
*ranges = calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t));
*ranges = u_calloc(MAX_SUBNET_VALIDATION_RANGES, sizeof(uint32_t));
if (!*ranges) return false;
*count = 0;
}
@ -614,7 +615,7 @@ bool route_get_all_routes(const struct ROUTE_TABLE *table, uint32_t network, uin
if (*count == 0) return true; // No routes found, but not an error
// Allocate result array
*routes = calloc(*count, sizeof(struct ROUTE_ENTRY));
*routes = u_calloc(*count, sizeof(struct ROUTE_ENTRY));
if (!*routes) {
*count = 0;
return false;

19
src/routing.c

@ -12,6 +12,7 @@
#include "../lib/debug_config.h"
#include <string.h>
#include <stdlib.h>
#include "../lib/mem.h"
#define IPv4_VERSION 4
#define IPv6_VERSION 6
@ -116,7 +117,7 @@ static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* en
}
// Allocate packet data (TUN will free it)
uint8_t* packet_data = malloc(ip_len);
uint8_t* packet_data = u_malloc(ip_len);
if (!packet_data) {
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "Failed to allocate packet data");
memory_pool_free(instance->tun->pool, pkt);
@ -135,7 +136,7 @@ static void routing_pkt_from_etcp_cb(struct ETCP_CONN* conn, struct ll_entry* en
// Put to TUN input_queue
if (queue_data_put(instance->tun->input_queue, (struct ll_entry*)pkt, 0) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "Failed to put packet to TUN input_queue");
free(packet_data);
u_free(packet_data);
memory_pool_free(instance->tun->pool, pkt);
} else {
DEBUG_DEBUG(DEBUG_CATEGORY_ROUTING, "Forwarded %zu bytes from ETCP to TUN", ip_len);
@ -169,7 +170,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
uint32_t dst_ip = extract_dst_ip(pkt->ll.dgram, pkt->ll.len);
if (dst_ip == 0) {
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Failed to extract destination IP, dropping packet");
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
} else {
struct in_addr addr;
@ -178,24 +179,24 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
struct ROUTE_ARRAY* routes = route_table_lookup(instance->rt, dst_ip);
if (!routes || routes->routes == 0) {
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "No route to %s, dropping packet", ip_to_str(&addr, AF_INET).str);
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
} else {
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_to_str(&addr, AF_INET).str);
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
} else if (!conn->normalizer) {
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "Connection for %s has no normalizer, dropping packet", ip_to_str(&addr, AF_INET).str);
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
} else {
size_t etcp_data_len = 1 + pkt->ll.len;
struct ll_entry* entry = ll_alloc_lldgram(etcp_data_len);
if (!entry) {
DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "Failed to allocate entry for ETCP send");
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
} else {
entry->dgram[0] = ETCP_ID_DATA;
@ -209,7 +210,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
queue_dgram_free(entry);
}
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(instance->tun->pool, pkt);
}
}
@ -217,7 +218,7 @@ static void routing_pkt_from_tun_cb(struct ll_queue* q, void* arg) {
}
} else {
if (pkt->ll.dgram) {
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
}
memory_pool_free(instance->tun->pool, pkt);
}

35
src/tun_if.c

@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../lib/mem.h"
#ifdef _WIN32
#include <windows.h>
@ -36,7 +37,7 @@ static void tun_read_callback(int fd, void* user_arg)
if (nread == 0) return;
// Allocate packet data
uint8_t* packet_data = malloc(nread);
uint8_t* packet_data = u_malloc(nread);
if (!packet_data) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to allocate packet data (size=%zd)", nread);
tun->read_errors++;
@ -48,7 +49,7 @@ static void tun_read_callback(int fd, void* user_arg)
struct ETCP_FRAGMENT* pkt = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(tun->pool);
if (!pkt) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to allocate ETCP_FRAGMENT from pool");
free(packet_data);
u_free(packet_data);
tun->read_errors++;
return;
}
@ -62,7 +63,7 @@ static void tun_read_callback(int fd, void* user_arg)
// Add to output queue (TUN → routing)
if (queue_data_put(tun->output_queue, (struct ll_entry*)pkt, 0) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to add packet to output queue");
free(packet_data);
u_free(packet_data);
memory_pool_free(tun->pool, pkt);
tun->read_errors++;
return;
@ -100,7 +101,7 @@ static void tun_input_queue_callback(struct ll_queue* q, void* arg)
dump_ip_packet("->TUN", pkt->ll.dgram, pkt->ll.len);
}
}
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
}
memory_pool_free(tun->pool, pkt);
@ -116,7 +117,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
int test_mode = config->global.tun_test_mode;
struct tun_if* tun = calloc(1, sizeof(struct tun_if));
struct tun_if* tun = u_calloc(1, sizeof(struct tun_if));
if (!tun) return NULL;
tun->ua = ua;
@ -130,7 +131,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
if (config->global.tun_ip.family == AF_INET) {
snprintf(ip_str, sizeof(ip_str), "%s/32", ip_to_str(&config->global.tun_ip.addr.v4, AF_INET).str);
} else {
free(tun);
u_free(tun);
return NULL;
}
@ -138,7 +139,7 @@ struct tun_if* tun_init(struct UASYNC* ua, struct utun_config* config)
if (!test_mode) {
if (tun_platform_init(tun, tun->ifname, ip_str, mtu) != 0) {
free(tun);
u_free(tun);
return NULL;
}
} else if (tun->ifname[0] == '\0') {
@ -196,7 +197,7 @@ fail:
if (tun->input_queue) queue_free(tun->input_queue);
if (tun->pool) memory_pool_destroy(tun->pool);
if (!test_mode) tun_platform_cleanup(tun);
free(tun);
u_free(tun);
return NULL;
}
@ -223,20 +224,20 @@ void tun_close(struct tun_if* tun)
struct ETCP_FRAGMENT* pkt;
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(tun->input_queue)) != NULL) {
if (pkt->ll.dgram) free(pkt->ll.dgram);
if (pkt->ll.dgram) u_free(pkt->ll.dgram);
memory_pool_free(tun->pool, pkt);
}
queue_free(tun->input_queue);
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(tun->output_queue)) != NULL) {
if (pkt->ll.dgram) free(pkt->ll.dgram);
if (pkt->ll.dgram) u_free(pkt->ll.dgram);
memory_pool_free(tun->pool, pkt);
}
queue_free(tun->output_queue);
memory_pool_destroy(tun->pool);
if (!tun->test_mode) tun_platform_cleanup(tun);
free(tun);
u_free(tun);
}
ssize_t tun_write(struct tun_if* tun, const uint8_t* buf, size_t len)
@ -270,7 +271,7 @@ void tun_packet_handler(void* arg) {
struct tun_packet_data* pd = (struct tun_packet_data*)arg;
if (!pd || !pd->tun || !pd->entry) {
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "ARG ZERO");
if (pd) free(pd);
if (pd) u_free(pd);
return;
}
@ -278,7 +279,7 @@ void tun_packet_handler(void* arg) {
struct ll_entry* entry = pd->entry;
// Освободить временную структуру
free(pd);
u_free(pd);
dump_ip_packet("TUNh->", entry->dgram, entry->len);
@ -296,12 +297,12 @@ int tun_inject_packet(struct tun_if* tun, const uint8_t* buf, size_t len)
{
if (!tun || !buf || len == 0 || len > TUN_MAX_PACKET_SIZE) return -1;
uint8_t* data = malloc(len);
uint8_t* data = u_malloc(len);
if (!data) { tun->read_errors++; return -1; }
memcpy(data, buf, len);
struct ETCP_FRAGMENT* pkt = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(tun->pool);
if (!pkt) { free(data); tun->read_errors++; return -1; }
if (!pkt) { u_free(data); tun->read_errors++; return -1; }
pkt->seq = 0;
pkt->timestamp = 0;
@ -311,7 +312,7 @@ int tun_inject_packet(struct tun_if* tun, const uint8_t* buf, size_t len)
int ret = queue_data_put(tun->output_queue, (struct ll_entry*)pkt, 0);
if (ret != 0) {
free(data);
u_free(data);
memory_pool_free(tun->pool, pkt);
tun->read_errors++;
return -1;
@ -337,7 +338,7 @@ ssize_t tun_read_packet(struct tun_if* tun, uint8_t* buf, size_t len)
memcpy(buf, pkt->ll.dgram, pkt->ll.len);
ssize_t ret = pkt->ll.len;
free(pkt->ll.dgram);
u_free(pkt->ll.dgram);
memory_pool_free(tun->pool, pkt);
tun->bytes_written += ret;

1
src/tun_linux.c

@ -18,6 +18,7 @@
#include <linux/if.h>
#include <linux/if_tun.h>
#include <errno.h>
#include "../lib/mem.h"
// Helper for interface ioctl operations
static int if_ioctl(const char *ifname, unsigned long request, struct ifreq *ifr) {

7
src/tun_route.c

@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "../lib/mem.h"
// Platform detection
#ifdef _WIN32
@ -345,12 +346,12 @@ int tun_route_flush(const char *ifname) {
return -1;
}
table = (PMIB_IPFORWARDTABLE)malloc(size);
table = (PMIB_IPFORWARDTABLE)u_malloc(size);
if (!table) return -1;
ret = GetIpForwardTable(table, &size, 0);
if (ret != NO_ERROR) {
free(table);
u_free(table);
return -1;
}
@ -361,7 +362,7 @@ int tun_route_flush(const char *ifname) {
}
}
free(table);
u_free(table);
return 0;
}

13
src/tun_windows.c

@ -10,6 +10,7 @@
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include "../lib/mem.h"
// Wintun function pointers
static HMODULE wintun_dll = NULL;
@ -262,7 +263,7 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
}
/* === ОДНО копирование === */
uint8_t* data = malloc(size);
uint8_t* data = u_malloc(size);
if (!data) {
WintunReleaseReceivePacket(session, wintun_pkt);
tun->read_errors++;
@ -273,7 +274,7 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
struct ETCP_FRAGMENT* pkt = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(tun->pool);
if (!pkt) {
free(data);
u_free(data);
tun->read_errors++;
continue;
}
@ -281,9 +282,9 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
pkt->ll.dgram = data;
pkt->ll.len = size;
struct tun_packet_data* pd = malloc(sizeof(*pd));
struct tun_packet_data* pd = u_malloc(sizeof(*pd));
if (!pd) {
free(data);
u_free(data);
memory_pool_free(tun->pool, pkt);
tun->read_errors++;
continue;
@ -295,10 +296,12 @@ DWORD WINAPI tun_read_thread_proc(LPVOID arg)
tun->bytes_read += size;
tun->packets_read ++;
// dump_ip_packet("TUN->", data, size); // теперь data вместо buf
dump_ip_packet("TUN_THREAD->", data, size); // теперь data вместо buf
uasync_post(tun->ua, tun_packet_handler, pd);
// DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "POST done");
}
}
DEBUG_DEBUG(DEBUG_CATEGORY_TUN, "TUN exit");
return 0;
}

1
src/utun.c

@ -21,6 +21,7 @@
#include <getopt.h>
#include "../lib/platform_compat.h"
#include "../lib/socket_compat.h"
#include "../lib/mem.h"
#ifdef _WIN32
#include <windows.h>

17
src/utun_instance.c

@ -18,6 +18,7 @@
#include <errno.h>
#include <unistd.h>
#include "../lib/platform_compat.h"
#include "../lib/mem.h"
@ -197,7 +198,7 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
}
// Allocate instance
struct UTUN_INSTANCE *instance = calloc(1, sizeof(struct UTUN_INSTANCE));
struct UTUN_INSTANCE *instance = u_calloc(1, sizeof(struct UTUN_INSTANCE));
if (!instance) {
free_config(config);
return NULL;
@ -207,7 +208,7 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
if (instance_init_common(instance, ua, config) != 0) {
// Cleanup on error
if (instance->config) free_config(instance->config);
free(instance);
u_free(instance);
return NULL;
}
@ -222,7 +223,7 @@ struct UTUN_INSTANCE* utun_instance_create_from_config(struct UASYNC* ua, struct
}
// Allocate instance
struct UTUN_INSTANCE *instance = calloc(1, sizeof(struct UTUN_INSTANCE));
struct UTUN_INSTANCE *instance = u_calloc(1, sizeof(struct UTUN_INSTANCE));
if (!instance) {
DEBUG_ERROR(DEBUG_CATEGORY_MEMORY, "Failed to allocate UTUN_INSTANCE");
return NULL;
@ -231,7 +232,7 @@ struct UTUN_INSTANCE* utun_instance_create_from_config(struct UASYNC* ua, struct
// Initialize using common function (config ownership transferred to instance)
if (instance_init_common(instance, ua, config) != 0) {
// Cleanup on error - caller still owns config since we failed
free(instance);
u_free(instance);
return NULL;
}
@ -254,7 +255,7 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
if (instance->control_srv) {
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Shutting down control server");
control_server_shutdown(instance->control_srv);
free(instance->control_srv);
u_free(instance->control_srv);
instance->control_srv = NULL;
}
@ -346,7 +347,7 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
// Free the instance memory
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] Freeing instance memory");
free(instance);
u_free(instance);
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] Instance destroyed completely");
}
@ -390,12 +391,12 @@ int utun_instance_init(struct UTUN_INSTANCE *instance) {
// Initialize control server if configured
if (instance->config->global.control_sock.ss_family != 0) {
instance->control_srv = (struct control_server*)calloc(1, sizeof(struct control_server));
instance->control_srv = (struct control_server*)u_calloc(1, sizeof(struct control_server));
if (instance->control_srv) {
if (control_server_init(instance->control_srv, instance->ua, instance,
&instance->config->global.control_sock, 8) != 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Failed to initialize control server, continuing without monitoring");
free(instance->control_srv);
u_free(instance->control_srv);
instance->control_srv = NULL;
} else {
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Control server initialized successfully");

17
tests/test_etcp_dummynet.c

@ -26,6 +26,7 @@
#include "../src/config_updater.h"
#include "../src/routing.h"
#include "../src/crc32.h"
#include "../lib/mem.h"
#define SEND_MS 1000
#define WAIT_MS 1000
@ -98,7 +99,7 @@ static void send_pkt(void* arg) {
static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
const char* priv_hex, const char* pub_hex) {
struct UTUN_INSTANCE* inst = calloc(1, sizeof(*inst));
struct UTUN_INSTANCE* inst = u_calloc(1, sizeof(*inst));
if (!inst) return NULL;
inst->ua = u;
@ -106,7 +107,7 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
/* Инициализируем ключи из hex строк */
if (sc_init_local_keys(&inst->my_keys, pub_hex, priv_hex) != SC_OK) {
free(inst);
u_free(inst);
return NULL;
}
@ -115,13 +116,13 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
inst->pkt_pool = memory_pool_init(sizeof(struct ETCP_DGRAM) + PACKET_DATA_SIZE);
if (!inst->ack_pool || !inst->data_pool || !inst->pkt_pool) {
free(inst);
u_free(inst);
return NULL;
}
struct utun_config* cfg = calloc(1, sizeof(*cfg));
struct utun_config* cfg = u_calloc(1, sizeof(*cfg));
if (!cfg) {
free(inst);
u_free(inst);
return NULL;
}
@ -135,7 +136,7 @@ static struct UTUN_INSTANCE* create_instance(struct UASYNC* u, uint64_t node_id,
}
static int add_server(struct UTUN_INSTANCE* inst, const char* name, int port) {
struct CFG_SERVER* srv = calloc(1, sizeof(*srv));
struct CFG_SERVER* srv = u_calloc(1, sizeof(*srv));
if (!srv) return -1;
strncpy(srv->name, name, MAX_CONN_NAME_LEN-1);
srv->ip.ss_family = AF_INET;
@ -149,7 +150,7 @@ static int add_server(struct UTUN_INSTANCE* inst, const char* name, int port) {
static int add_client(struct UTUN_INSTANCE* inst, struct UTUN_INSTANCE* srv_inst,
const char* name, const char* peer_pubkey, int remote_port) {
struct CFG_CLIENT* cli = calloc(1, sizeof(*cli));
struct CFG_CLIENT* cli = u_calloc(1, sizeof(*cli));
if (!cli) return -1;
strncpy(cli->name, name, MAX_CONN_NAME_LEN-1);
strncpy(cli->peer_public_key_hex, peer_pubkey, MAX_KEY_LEN-1);
@ -158,7 +159,7 @@ static int add_client(struct UTUN_INSTANCE* inst, struct UTUN_INSTANCE* srv_inst
/* Находим локальный сервер */
struct CFG_SERVER* local_srv = inst->config->servers;
struct CFG_CLIENT_LINK* link = calloc(1, sizeof(*link));
struct CFG_CLIENT_LINK* link = u_calloc(1, sizeof(*link));
link->remote_addr.ss_family = AF_INET;
((struct sockaddr_in*)&link->remote_addr)->sin_addr.s_addr = inet_addr("127.0.0.1");
((struct sockaddr_in*)&link->remote_addr)->sin_port = htons(remote_port);

21
tests/test_etcp_link_id.c

@ -8,6 +8,7 @@
#include <string.h>
#include <time.h>
#include <assert.h>
#include "../lib/mem.h"
// Mock ETCP_LINK structure for testing (minimal version)
struct TEST_LINK {
@ -17,7 +18,7 @@ struct TEST_LINK {
// Helper function to create a mock ETCP_CONN with empty links list
static struct ETCP_CONN* create_test_conn(void) {
struct ETCP_CONN* conn = calloc(1, sizeof(struct ETCP_CONN));
struct ETCP_CONN* conn = u_calloc(1, sizeof(struct ETCP_CONN));
if (!conn) {
fprintf(stderr, "Failed to allocate test connection\n");
exit(1);
@ -28,7 +29,7 @@ static struct ETCP_CONN* create_test_conn(void) {
// Helper function to add a link with specific id to connection
static void add_link_with_id(struct ETCP_CONN* conn, uint8_t id) {
struct ETCP_LINK* link = calloc(1, sizeof(struct ETCP_LINK));
struct ETCP_LINK* link = u_calloc(1, sizeof(struct ETCP_LINK));
if (!link) {
fprintf(stderr, "Failed to allocate test link\n");
exit(1);
@ -45,7 +46,7 @@ static int remove_link_with_id(struct ETCP_CONN* conn, uint8_t id) {
if ((*pp)->local_link_id == id) {
struct ETCP_LINK* to_remove = *pp;
*pp = (*pp)->next;
free(to_remove);
u_free(to_remove);
return 1; // Success
}
pp = &(*pp)->next;
@ -69,7 +70,7 @@ static void free_all_links(struct ETCP_CONN* conn) {
struct ETCP_LINK* link = conn->links;
while (link) {
struct ETCP_LINK* next = link->next;
free(link);
u_free(link);
link = next;
}
conn->links = NULL;
@ -89,7 +90,7 @@ static void test_empty_connection(void) {
struct ETCP_CONN* conn = create_test_conn();
int result = etcp_find_free_local_link_id(conn);
assert(result == 0);
free(conn);
u_free(conn);
printf("PASSED\n");
}
@ -165,7 +166,7 @@ static void test_random_deletion_addition(void) {
// Cleanup
free_all_links(conn);
free(conn);
u_free(conn);
if ((cycle + 1) % 10 == 0) {
printf(" Completed %d cycles...\n", cycle + 1);
@ -189,7 +190,7 @@ static void test_all_occupied(void) {
assert(result == -1);
free_all_links(conn);
free(conn);
u_free(conn);
printf("PASSED\n");
}
@ -213,7 +214,7 @@ static void test_specific_deletion(void) {
assert(result == 5);
free_all_links(conn);
free(conn);
u_free(conn);
printf("PASSED\n");
}
@ -235,7 +236,7 @@ static void test_delete_zero(void) {
assert(result == 0);
free_all_links(conn);
free(conn);
u_free(conn);
printf("PASSED\n");
}
@ -256,7 +257,7 @@ static void test_delete_all(void) {
int result = etcp_find_free_local_link_id(conn);
assert(result == 0);
free(conn);
u_free(conn);
printf("PASSED\n");
}

5
tests/test_offset.c

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "../lib/mem.h"
typedef struct {
int a;
@ -10,7 +11,7 @@ typedef struct {
} test_struct;
int main() {
test_struct* entry = malloc(sizeof(test_struct) + 100);
test_struct* entry = u_malloc(sizeof(test_struct) + 100);
entry->a = 1;
entry->b = 2;
entry->ref_count = 3;
@ -35,6 +36,6 @@ int main() {
printf("back2 ref_count: %d\n", back2->ref_count);
printf("back3 ref_count: %d\n", back3->ref_count);
free(entry);
u_free(entry);
return 0;
}

9
tests/test_pkt_normalizer_etcp.c

@ -23,6 +23,7 @@
#include "../lib/u_async.h"
#include "../lib/ll_queue.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#define TEST_TIMEOUT_MS 3000 // 3 second timeout
#define TOTAL_PACKETS 100 // Total packets to send
@ -238,14 +239,14 @@ static void send_packets_fwd(void) {
// Send while we have packets
while (packets_sent_fwd < TOTAL_PACKETS) {
int size = packet_sizes[packets_sent_fwd];
uint8_t* buffer = malloc(size);
uint8_t* buffer = u_malloc(size);
if (!buffer) break;
generate_packet_data(current_packet_seq_fwd, buffer, size);
pn_packer_send(client_pn, buffer, size);
free(buffer);
u_free(buffer);
packets_sent_fwd++;
current_packet_seq_fwd++;
}
@ -269,14 +270,14 @@ static void send_packets_back(void) {
// Send while we have packets
while (packets_sent_back < TOTAL_PACKETS) {
int size = packet_sizes[packets_sent_back];
uint8_t* buffer = malloc(size);
uint8_t* buffer = u_malloc(size);
if (!buffer) break;
generate_packet_data(current_packet_seq_back, buffer, size);
pn_packer_send(server_pn, buffer, size);
free(buffer);
u_free(buffer);
packets_sent_back++;
current_packet_seq_back++;
}

5
tests/test_pkt_normalizer_standalone.c

@ -20,6 +20,7 @@
// Use the real UTUN_INSTANCE structure but only initialize fields we need
#include "../src/utun_instance.h"
#include "../lib/mem.h"
// Test state
static struct UTUN_INSTANCE mock_instance;
@ -85,7 +86,7 @@ static void send_packets(void) {
for (int i = 0; i < TOTAL_PACKETS; i++) {
int size = packet_sizes[i];
uint8_t* buffer = malloc(size);
uint8_t* buffer = u_malloc(size);
if (!buffer) {
printf("Failed to allocate buffer for packet %d\n", i);
test_completed = 2;
@ -94,7 +95,7 @@ static void send_packets(void) {
generate_packet_data(i, buffer, size);
pn_packer_send(pn, buffer, size);
free(buffer);
u_free(buffer);
packets_sent++;
}

3
tests/test_route_lib.c

@ -11,6 +11,7 @@
#include "route_lib.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#ifndef DEBUG_CATEGORY_ROUTING
#define DEBUG_CATEGORY_ROUTING 1
@ -347,7 +348,7 @@ static void test_get_all_routes(void) {
ASSERT_EQ(count, 2, "should find 2 routes for 192.168.1.0/24");
ASSERT(routes != NULL, "routes should not be NULL");
free(routes);
u_free(routes);
route_table_destroy(table);
PASS();
}

19
tests/test_routing_mesh.c

@ -21,6 +21,7 @@
#include "../src/secure_channel.h"
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#define TEST_TIMEOUT_MS 10000 // 10 seconds timeout
@ -60,11 +61,11 @@ static int make_sockaddr(const char* ip_port, struct sockaddr_storage* ss) {
// Helper: create CFG_SERVER
static struct CFG_SERVER* create_server(const char* name, const char* ip_port, uint8_t type) {
struct CFG_SERVER* srv = calloc(1, sizeof(struct CFG_SERVER));
struct CFG_SERVER* srv = u_calloc(1, sizeof(struct CFG_SERVER));
if (!srv) return NULL;
strncpy(srv->name, name, MAX_CONN_NAME_LEN-1);
if (make_sockaddr(ip_port, &srv->ip) < 0) {
free(srv);
u_free(srv);
return NULL;
}
srv->type = type;
@ -73,12 +74,12 @@ static struct CFG_SERVER* create_server(const char* name, const char* ip_port, u
// Helper: create CFG_CLIENT_LINK
static struct CFG_CLIENT_LINK* create_link(struct CFG_SERVER* local_srv, const char* remote_ip_port) {
struct CFG_CLIENT_LINK* link = calloc(1, sizeof(struct CFG_CLIENT_LINK));
struct CFG_CLIENT_LINK* link = u_calloc(1, sizeof(struct CFG_CLIENT_LINK));
if (!link) return NULL;
link->local_srv = local_srv;
strncpy(link->server_name, local_srv->name, MAX_CONN_NAME_LEN-1);
if (make_sockaddr(remote_ip_port, &link->remote_addr) < 0) {
free(link);
u_free(link);
return NULL;
}
return link;
@ -86,7 +87,7 @@ static struct CFG_CLIENT_LINK* create_link(struct CFG_SERVER* local_srv, const c
// Helper: create CFG_CLIENT
static struct CFG_CLIENT* create_client(const char* name, const char* peer_key, int keepalive) {
struct CFG_CLIENT* cli = calloc(1, sizeof(struct CFG_CLIENT));
struct CFG_CLIENT* cli = u_calloc(1, sizeof(struct CFG_CLIENT));
if (!cli) return NULL;
strncpy(cli->name, name, MAX_CONN_NAME_LEN-1);
strncpy(cli->peer_public_key_hex, peer_key, MAX_KEY_LEN-1);
@ -129,7 +130,7 @@ static void add_client(struct utun_config* cfg, struct CFG_CLIENT* cli) {
// Helper: add subnet
static void add_subnet(struct CFG_ROUTE_ENTRY** list, const char* cidr) {
struct CFG_ROUTE_ENTRY* entry = calloc(1, sizeof(struct CFG_ROUTE_ENTRY));
struct CFG_ROUTE_ENTRY* entry = u_calloc(1, sizeof(struct CFG_ROUTE_ENTRY));
if (!entry) return;
char buf[32];
@ -148,7 +149,7 @@ static void add_subnet(struct CFG_ROUTE_ENTRY** list, const char* cidr) {
// Create config for instance A
static struct utun_config* create_config_a(const char* key_c_pub) {
struct utun_config* cfg = calloc(1, sizeof(struct utun_config));
struct utun_config* cfg = u_calloc(1, sizeof(struct utun_config));
if (!cfg) return NULL;
// Global settings
@ -183,7 +184,7 @@ static struct utun_config* create_config_a(const char* key_c_pub) {
// Create config for instance B
static struct utun_config* create_config_b(const char* key_c_pub) {
struct utun_config* cfg = calloc(1, sizeof(struct utun_config));
struct utun_config* cfg = u_calloc(1, sizeof(struct utun_config));
if (!cfg) return NULL;
// Global settings
@ -218,7 +219,7 @@ static struct utun_config* create_config_b(const char* key_c_pub) {
// Create config for instance C
static struct utun_config* create_config_c(const char* key_c_priv, const char* key_c_pub) {
struct utun_config* cfg = calloc(1, sizeof(struct utun_config));
struct utun_config* cfg = u_calloc(1, sizeof(struct utun_config));
if (!cfg) return NULL;
// Global settings

2
tests/test_u_async_comprehensive.c

@ -426,7 +426,7 @@ static void test_concurrent_operations(void) {
void* timers[10];
for (int i = 0; i < 10; i++) {
// Use unique contexts to avoid all timers having timeout_ms = 0
test_context_t* individual_ctx = malloc(sizeof(test_context_t));
test_context_t* individual_ctx = u_malloc(sizeof(test_context_t));
ASSERT_NOT_NULL(individual_ctx, "Failed to allocate timer context");
individual_ctx->callback_count = 0;
individual_ctx->expected_count = 0;

25
tests/test_u_async_performance.c

@ -16,6 +16,7 @@
#include <errno.h>
#include "u_async.h"
#include "../lib/mem.h"
/* Performance measurement */
static uint64_t get_time_us(void) {
@ -48,12 +49,12 @@ static void test_socket_callback(int fd, void* arg) {
}
/* Create socket array */
int* sockets = malloc(num_sockets * sizeof(int));
int* socket_fds = malloc(num_sockets * sizeof(int)); // Store FDs instead of pointers
int* sockets = u_malloc(num_sockets * sizeof(int));
int* socket_fds = u_malloc(num_sockets * sizeof(int)); // Store FDs instead of pointers
if (!sockets || !socket_fds) {
printf("Memory allocation failed\n");
free(sockets);
free(socket_fds);
u_free(sockets);
u_free(socket_fds);
uasync_destroy(ua, 0);
return;
}
@ -67,8 +68,8 @@ static void test_socket_callback(int fd, void* arg) {
for (int j = 0; j < i; j++) {
close(sockets[j]);
}
free(sockets);
free(socket_fds);
u_free(sockets);
u_free(socket_fds);
uasync_destroy(ua, 0);
return;
}
@ -158,8 +159,8 @@ static void test_socket_callback(int fd, void* arg) {
for (int i = 0; i < num_sockets; i++) {
close(sockets[i]);
}
free(sockets);
free(socket_fds);
u_free(sockets);
u_free(socket_fds);
uasync_destroy(ua, 0);
}
@ -237,8 +238,8 @@ static void benchmark_scalability(void) {
if (!ua) continue;
/* Create sockets */
int* sockets = malloc(num_sockets * sizeof(int));
void** socket_ids = malloc(num_sockets * sizeof(void*));
int* sockets = u_malloc(num_sockets * sizeof(int));
void** socket_ids = u_malloc(num_sockets * sizeof(void*));
for (int i = 0; i < num_sockets; i++) {
sockets[i] = socket(AF_INET, SOCK_DGRAM, 0);
@ -263,8 +264,8 @@ static void benchmark_scalability(void) {
for (int i = 0; i < num_sockets; i++) {
close(sockets[i]);
}
free(sockets);
free(socket_ids);
u_free(sockets);
u_free(socket_ids);
uasync_destroy(ua, 0);
}
}

Loading…
Cancel
Save