Browse Source

Fix build: rename u_async to lib, add missing constants, out-of-tree build support

v2_dev
Evgeny 3 months ago
parent
commit
3f0a23aa93
  1. 2
      Makefile.am
  2. 0
      README.md
  3. 2
      configure.ac
  4. 5
      lib/Makefile.am
  5. 1
      lib/debug_config.c
  6. 0
      lib/debug_config.h
  7. 0
      lib/timeout_heap.c
  8. 0
      lib/timeout_heap.h
  9. 0
      lib/u_async.c
  10. 0
      lib/u_async.h
  11. 33
      src/Makefile.am
  12. 6
      src/etcp.c
  13. 10
      src/etcp.h
  14. 29
      src/etcp_connections.c
  15. 10
      src/etcp_connections.h
  16. 4
      src/ll_queue.c
  17. 64
      src/pkt_normalizer.c
  18. 6
      src/pkt_normalizer.h
  19. 46
      src/secure_channel.h
  20. 2
      src/tun_if.c
  21. 2
      src/utun_fixes.c
  22. 2
      src/utun_instance.c
  23. 4
      src/utun_instance.h
  24. 36
      tests/Makefile.am
  25. 2
      tests/simple_uasync.c
  26. 2
      tests/simple_uasync.h
  27. 2
      tests/test_debug_config.c
  28. 4
      tests/test_intensive_memory_pool.c
  29. 4
      tests/test_ll_queue_comprehensive.c
  30. 4
      tests/test_memory_pool_and_config.c
  31. 4
      tests/test_u_async_comprehensive.c
  32. 4
      tests/test_u_async_performance.c
  33. 4
      tests/test_u_async_simple.c

2
Makefile.am

@ -1,5 +1,5 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = u_async src tests SUBDIRS = lib src tests
EXTRA_DIST = \ EXTRA_DIST = \
README.md \ README.md \

2
configure.ac

@ -52,7 +52,7 @@ AC_CONFIG_FILES([
Makefile Makefile
src/Makefile src/Makefile
tests/Makefile tests/Makefile
u_async/Makefile lib/Makefile
]) ])
AC_OUTPUT AC_OUTPUT

5
u_async/Makefile.am → lib/Makefile.am

@ -6,10 +6,11 @@ libuasync_a_SOURCES = \
$(top_srcdir)/src/ll_queue.h \ $(top_srcdir)/src/ll_queue.h \
$(top_srcdir)/src/ll_queue.c \ $(top_srcdir)/src/ll_queue.c \
debug_config.c \ debug_config.c \
debug_config.h debug_config.h \
timeout_heap.c \
timeout_heap.h
libuasync_a_CFLAGS = \ libuasync_a_CFLAGS = \
-D_ISOC99_SOURCE \ -D_ISOC99_SOURCE \
-DDEBUG_OUTPUT_STDERR \ -DDEBUG_OUTPUT_STDERR \
-I$(top_srcdir)/src -I$(top_srcdir)/src

1
u_async/debug_config.c → lib/debug_config.c

@ -14,6 +14,7 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
FILE* debug_output_file = NULL;
/* Global debug configuration */ /* Global debug configuration */
debug_config_t g_debug_config = { debug_config_t g_debug_config = {

0
u_async/debug_config.h → lib/debug_config.h

0
u_async/timeout_heap.c → lib/timeout_heap.c

0
u_async/timeout_heap.h → lib/timeout_heap.h

0
u_async/u_async.c → lib/u_async.c

0
u_async/u_async.h → lib/u_async.h

33
src/Makefile.am

@ -8,27 +8,13 @@ utun_SOURCES = \
tun_if.c \ tun_if.c \
etcp.c \ etcp.c \
etcp_connections.c \ etcp_connections.c \
etcp_sockets.c \
secure_channel.c \ secure_channel.c \
crc32.c \ crc32.c \
pkt_normalizer.c \ pkt_normalizer.c \
packet_pool.c \ packet_pool.c \
packet_buffer.c \ memory_pool.c \
memory_pool.c $(top_srcdir)/tinycrypt/lib/source/aes_encrypt.c \
$(top_srcdir)/tinycrypt/lib/source/aes_decrypt.c \
utun_CFLAGS = \
-I$(top_srcdir)/u_async \
-I$(top_srcdir)/tinycrypt/lib/include \
-I$(top_srcdir)/tinycrypt/lib/source \
$(DEBUG_FLAGS)
utun_LDADD = \
$(top_builddir)/u_async/libuasync.a \
-lpthread
# tinycrypt library sources
tinycrypt_lib_sources = \
$(top_srcdir)/tinycrypt/lib/source/aes.c \
$(top_srcdir)/tinycrypt/lib/source/cbc_mode.c \ $(top_srcdir)/tinycrypt/lib/source/cbc_mode.c \
$(top_srcdir)/tinycrypt/lib/source/ccm_mode.c \ $(top_srcdir)/tinycrypt/lib/source/ccm_mode.c \
$(top_srcdir)/tinycrypt/lib/source/cmac_mode.c \ $(top_srcdir)/tinycrypt/lib/source/cmac_mode.c \
@ -39,12 +25,19 @@ tinycrypt_lib_sources = \
$(top_srcdir)/tinycrypt/lib/source/ecc_platform_specific.c \ $(top_srcdir)/tinycrypt/lib/source/ecc_platform_specific.c \
$(top_srcdir)/tinycrypt/lib/source/hmac.c \ $(top_srcdir)/tinycrypt/lib/source/hmac.c \
$(top_srcdir)/tinycrypt/lib/source/sha256.c \ $(top_srcdir)/tinycrypt/lib/source/sha256.c \
$(top_srcdir)/tinycrypt/lib/source/sha256_init.c $(top_srcdir)/tinycrypt/lib/source/utils.c
utun_SOURCES += $(tinycrypt_lib_sources) utun_CFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/tinycrypt/lib/include \
-I$(top_srcdir)/tinycrypt/lib/source \
$(DEBUG_FLAGS)
utun_LDADD = \
$(top_builddir)/lib/libuasync.a \
-lpthread
# Install directories # Install directories
install-exec-hook: install-exec-hook:
$(MKDIR_P) $(DESTDIR)$(bindir) $(MKDIR_P) $(DESTDIR)$(bindir)
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/utun $(MKDIR_P) $(DESTDIR)$(sysconfdir)/utun

6
src/etcp.c

@ -1,13 +1,13 @@
// etcp.c - ETCP Protocol Implementation // etcp.c - ETCP Protocol Implementation
#include "etcp.h" #include "etcp.h"
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
#include "crc32.h" #include "crc32.h"
#include "secure_channel.h" #include "secure_channel.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
// Creating ETCP instance // Creating ETCP instance
struct ETCP_CONN* etcp_create(struct UTUN_INSTANCE* *instance) { struct ETCP_CONN* etcp_create(struct UTUN_INSTANCE* instance) {
if (!instance) return NULL; if (!instance) return NULL;
struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN)); struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN));
@ -21,7 +21,7 @@ struct ETCP_CONN* etcp_create(struct UTUN_INSTANCE* *instance) {
etcp->state = 0; etcp->state = 0;
// Initialize crypto context // Initialize crypto context
etcp->crypto_ctx = calloc(1, sizeof(sc_context_t)); etcp->crypto_ctx = calloc(1, sizeof(struct secure_channel));
if (!etcp->crypto_ctx) { if (!etcp->crypto_ctx) {
free(etcp); free(etcp);
return NULL; return NULL;

10
src/etcp.h

@ -22,7 +22,7 @@ struct ETCP_CONN {
uint64_t node_id; uint64_t node_id;
int mtu; int mtu;
struct UTUN_INSTANCE* *instance; struct UTUN_INSTANCE* instance;
// Каналы (соединения) - linked list // Каналы (соединения) - linked list
struct ETCP_LINK* channels; struct ETCP_LINK* channels;
@ -33,15 +33,15 @@ struct ETCP_CONN {
uint8_t state; // 0 - just created, 1 - initialized, 2 - connection established uint8_t state; // 0 - just created, 1 - initialized, 2 - connection established
// Криптография и состояние // Криптография и состояние
sc_context_t* crypto_ctx; struct secure_channel* crypto_ctx;
ll_queue_t* input_queue;// отправитель -> input_queue -> etcp -> etcp_channel -> отправка (etcp_sockets) struct ll_queue* input_queue;// отправитель -> input_queue -> etcp -> etcp_channel -> отправка (etcp_sockets)
ll_queue_t* output_queue;// etcp_sockets -> etcp_channel -> etcp -> output_queue -> получатель struct ll_queue* output_queue;// etcp_sockets -> etcp_channel -> etcp -> output_queue -> получатель
}; };
// Создание пустого ETCP instance (после надо добавить ключи, каналы) // Создание пустого ETCP instance (после надо добавить ключи, каналы)
struct ETCP_CONN* etcp_create(struct UTUN_INSTANCE* *instance); struct ETCP_CONN* etcp_create(struct UTUN_INSTANCE* instance);
// Уничтожение ETCP instance // Уничтожение ETCP instance
void etcp_destroy(struct ETCP_CONN* etcp); void etcp_destroy(struct ETCP_CONN* etcp);

29
src/etcp_connections.c

@ -3,6 +3,7 @@
#include "debug_config.h" #include "debug_config.h"
#include "routing.h" #include "routing.h"
#include "utun_instance.h" #include "utun_instance.h"
#include "config_parser.h"
#include "crc32.h" #include "crc32.h"
#include "etcp.h" #include "etcp.h"
#include <stdlib.h> #include <stdlib.h>
@ -502,7 +503,7 @@ static int parse_ip_port(const char* addr_str, struct sockaddr_storage* addr, so
} }
// Initialize connections from configuration // Initialize connections from configuration
int init_connections(struct utun_instance* instance) { int init_connections(struct UTUN_INSTANCE* instance) {
if (!instance || !instance->config) { if (!instance || !instance->config) {
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Invalid instance or config"); DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Invalid instance or config");
return -1; return -1;
@ -653,7 +654,33 @@ void conn_destroy(conn_handle_t* handle) {
free(handle); free(handle);
} }
int conn_send(conn_handle_t* conn, const uint8_t* data, size_t len) {
if (!conn || !conn->etcp || !data || len == 0) {
return -1;
}
struct ETCP_CONN* etcp = conn->etcp;
struct packet_buffer* pkt = packet_pool_get(&etcp->packet_pool);
if (!pkt) {
return -1;
}
if (len > 1500) {
len = 1500;
}
memcpy(packet_data(pkt), data, len);
pkt->metadata.data_len = len;
etcp_conn_input(etcp, pkt);
return 0;
}
size_t etcp_connections_get_channel_count(const struct ETCP_CONNECTIONS* conns) { size_t etcp_connections_get_channel_count(const struct ETCP_CONNECTIONS* conns) {
if (!conns) return 0; if (!conns) return 0;
return conns->num_channels; return conns->num_channels;
} }

10
src/etcp_connections.h

@ -8,7 +8,7 @@
#include <sys/socket.h> #include <sys/socket.h>
// Forward declarations // Forward declarations
struct utun_instance; struct UTUN_INSTANCE;
// Типы кодограмм протокола // Типы кодограмм протокола
#define ETCP_INIT_REQUEST 0x02 #define ETCP_INIT_REQUEST 0x02
@ -28,6 +28,10 @@ struct ETCP_CONNECTIONS {
size_t max_channels; // сколько выделено памяти size_t max_channels; // сколько выделено памяти
size_t num_channels; // сколько активно size_t num_channels; // сколько активно
struct ETCP_LINK** links;// массив указателей на линки, сортированный по ip_port_hash struct ETCP_LINK** links;// массив указателей на линки, сортированный по ip_port_hash
// Дополнительные поля для управления соединениями
struct ETCP_CONN* etcp; // Родительский ETCP instance
struct ETCP_CONNECTIONS* conns;// Указатель на себя (для совместимости)
}; };
// ETCP Link - одно динамическое соединение (один путь) // ETCP Link - одно динамическое соединение (один путь)
@ -77,8 +81,8 @@ struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_CONNECTIONS* conns, const s
int etcp_link_add_to_connections(struct ETCP_CONNECTIONS* conns, struct ETCP_LINK* link); int etcp_link_add_to_connections(struct ETCP_CONNECTIONS* conns, struct ETCP_LINK* link);
void etcp_link_remove_from_connections(struct ETCP_CONNECTIONS* conns, struct ETCP_LINK* link); void etcp_link_remove_from_connections(struct ETCP_CONNECTIONS* conns, struct ETCP_LINK* link);
// INITIALIZATION // INITIALIZATION (создаёт listen-сокеты и подключения из конфига)
int init_connections(struct utun_instance* instance); int init_connections(struct UTUN_INSTANCE* instance);
// Отправка кодограмм протокола // Отправка кодограмм протокола
int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval); int etcp_link_send_init(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval);

4
src/ll_queue.c

@ -3,8 +3,8 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
// Предварительное объявление для отложенного возобновления // Предварительное объявление для отложенного возобновления
static void queue_resume_timeout_cb(void* arg); static void queue_resume_timeout_cb(void* arg);

64
src/pkt_normalizer.c

@ -1,16 +1,16 @@
#include "pkt_normalizer.h" #include "pkt_normalizer.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
static void packer_handler(ll_queue_t* q, ll_entry_t* unused, void* arg); static void packer_handler(struct ll_queue* q, struct ll_entry* unused, void* arg);
static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg); static void unpacker_handler(struct ll_queue* q, struct ll_entry* unused, void* arg);
static void send_buf(pn_struct* pn); static void send_buf(struct pn_struct* pn);
static int get_header(uint8_t* header, size_t L); static int get_header(uint8_t* header, size_t L);
/* Calculate fragment size from mtu */ /* Calculate fragment size from mtu */
pn_struct* pkt_normalizer_init(uasync_t* ua, int is_packer, int mtu) { struct pn_struct* pkt_normalizer_init(uasync_t* ua, int is_packer, int mtu) {
pn_struct* pn = malloc(sizeof(pn_struct)); struct pn_struct* pn = malloc(sizeof(struct pn_struct));
if (!pn) return NULL; if (!pn) return NULL;
pn->ua = ua; pn->ua = ua;
pn->input = queue_new(ua); pn->input = queue_new(ua);
@ -51,7 +51,7 @@ pn_struct* pkt_normalizer_init(uasync_t* ua, int is_packer, int mtu) {
return pn; return pn;
} }
void pkt_normalizer_deinit(pn_struct* pn) { void pkt_normalizer_deinit(struct pn_struct* pn) {
if (!pn) return; if (!pn) return;
queue_free(pn->input); queue_free(pn->input);
queue_free(pn->output); queue_free(pn->output);
@ -63,8 +63,8 @@ void pkt_normalizer_deinit(pn_struct* pn) {
} }
free(pn); free(pn);
} }
pkt_normalizer_pair* pkt_normalizer_pair_init(uasync_t* ua, int mtu) { struct pkt_normalizer_pair* pkt_normalizer_pair_init(uasync_t* ua, int mtu) {
pkt_normalizer_pair* pair = malloc(sizeof(pkt_normalizer_pair)); struct pkt_normalizer_pair* pair = malloc(sizeof(struct pkt_normalizer_pair));
if (!pair) return NULL; if (!pair) return NULL;
pair->packer = pkt_normalizer_init(ua, 1, mtu); pair->packer = pkt_normalizer_init(ua, 1, mtu);
if (!pair->packer) { if (!pair->packer) {
@ -79,7 +79,7 @@ pkt_normalizer_pair* pkt_normalizer_pair_init(uasync_t* ua, int mtu) {
} }
return pair; return pair;
} }
void pkt_normalizer_pair_deinit(pkt_normalizer_pair* pair) { void pkt_normalizer_pair_deinit(struct pkt_normalizer_pair* pair) {
if (!pair) return; if (!pair) return;
pkt_normalizer_deinit(pair->packer); pkt_normalizer_deinit(pair->packer);
pkt_normalizer_deinit(pair->unpacker); pkt_normalizer_deinit(pair->unpacker);
@ -99,7 +99,7 @@ static int get_header(uint8_t* header, size_t L) {
} }
} }
/* Сбросить состояние сборки фрагментов */ /* Сбросить состояние сборки фрагментов */
static void reset_fragment_state(pn_struct* pn) { static void reset_fragment_state(struct pn_struct* pn) {
if (!pn->is_packer) { if (!pn->is_packer) {
pn->u.unpacker.len = 0; pn->u.unpacker.len = 0;
pn->u.unpacker.total_len = 0; pn->u.unpacker.total_len = 0;
@ -107,10 +107,10 @@ static void reset_fragment_state(pn_struct* pn) {
} }
} }
/* Таймаут для сборки фрагментов */ /* Таймаут для сборки фрагментов */
static void send_buf(pn_struct* pn) { static void send_buf(struct pn_struct* pn) {
if (pn->u.packer.len == 0) return; if (pn->u.packer.len == 0) return;
size_t payload_len = pn->u.packer.len; size_t payload_len = pn->u.packer.len;
ll_entry_t* out = queue_entry_new(2 + payload_len); struct ll_entry* out = queue_entry_new(2 + payload_len);
if (!out) return; if (!out) return;
uint8_t* d = ll_entry_data(out); uint8_t* d = ll_entry_data(out);
*(uint16_t*)d = (uint16_t)payload_len; *(uint16_t*)d = (uint16_t)payload_len;
@ -118,11 +118,11 @@ static void send_buf(pn_struct* pn) {
queue_entry_put(pn->output, out); queue_entry_put(pn->output, out);
pn->u.packer.len = 0; pn->u.packer.len = 0;
} }
static void packer_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) { static void packer_handler(struct ll_queue* q, struct ll_entry* unused, void* arg) {
(void)unused; (void)unused;
pn_struct* pn = arg; struct pn_struct* pn = arg;
size_t max = (size_t)1400; size_t max = (size_t)1400;
ll_entry_t* entry = queue_entry_get(q); struct ll_entry* entry = queue_entry_get(q);
if (!entry) { if (!entry) {
queue_resume_callback(q); queue_resume_callback(q);
return; return;
@ -143,7 +143,7 @@ static void packer_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
while (remaining > 0) { while (remaining > 0) {
size_t chunk; size_t chunk;
size_t payload_len; size_t payload_len;
ll_entry_t* fout; struct ll_entry* fout;
uint8_t* fd; uint8_t* fd;
uint8_t frag_header[2]; uint8_t frag_header[2];
int frag_hsize; int frag_hsize;
@ -270,12 +270,12 @@ static void packer_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
} }
queue_resume_callback(q); queue_resume_callback(q);
} }
void pkt_normalizer_set_service_callback(pn_struct* pn, pkt_normalizer_service_callback_t callback, void* user_data) { void pkt_normalizer_set_service_callback(struct pn_struct* pn, pkt_normalizer_service_callback_t callback, void* user_data) {
if (!pn) return; if (!pn) return;
pn->service_callback = callback; pn->service_callback = callback;
pn->service_callback_user_data = user_data; pn->service_callback_user_data = user_data;
} }
void pkt_normalizer_reset_service_state(pn_struct* pn) { void pkt_normalizer_reset_service_state(struct pn_struct* pn) {
if (!pn || pn->is_packer) return; if (!pn || pn->is_packer) return;
if (pn->u.unpacker.in_service) { if (pn->u.unpacker.in_service) {
// Deliver pending service packet // Deliver pending service packet
@ -292,7 +292,7 @@ void pkt_normalizer_reset_service_state(pn_struct* pn) {
pn->u.unpacker.in_service = 0; pn->u.unpacker.in_service = 0;
} }
} }
void pkt_normalizer_reset_state(pn_struct* pn) { void pkt_normalizer_reset_state(struct pn_struct* pn) {
if (!pn) return; if (!pn) return;
if (pn->is_packer) { if (pn->is_packer) {
// Flush packer buffer // Flush packer buffer
@ -306,7 +306,7 @@ void pkt_normalizer_reset_state(pn_struct* pn) {
pkt_normalizer_reset_service_state(pn); pkt_normalizer_reset_service_state(pn);
} }
} }
int pkt_normalizer_send_service(pn_struct* pn, uint8_t type, const void* data, size_t len) { int pkt_normalizer_send_service(struct pn_struct* pn, uint8_t type, const void* data, size_t len) {
if (!pn || !pn->is_packer) return -1; if (!pn || !pn->is_packer) return -1;
// Service packet ограничен 256 байтами всего // Service packet ограничен 256 байтами всего
if (len > 256 - 2) return -1; // 2 байта на заголовок (0xFC + тип) if (len > 256 - 2) return -1; // 2 байта на заголовок (0xFC + тип)
@ -338,7 +338,7 @@ int pkt_normalizer_send_service(pn_struct* pn, uint8_t type, const void* data, s
} }
if (chunk == 0) break; if (chunk == 0) break;
size_t payload_len = 1 + chunk + (pos == 0 ? 1 : 0); // +1 байт типа для первого пакета size_t payload_len = 1 + chunk + (pos == 0 ? 1 : 0); // +1 байт типа для первого пакета
ll_entry_t* entry = queue_entry_new(2 + payload_len); struct ll_entry* entry = queue_entry_new(2 + payload_len);
if (!entry) return -1; if (!entry) return -1;
uint8_t* d = ll_entry_data(entry); uint8_t* d = ll_entry_data(entry);
*(uint16_t*)d = (uint16_t)payload_len; *(uint16_t*)d = (uint16_t)payload_len;
@ -354,14 +354,14 @@ int pkt_normalizer_send_service(pn_struct* pn, uint8_t type, const void* data, s
} }
return 0; return 0;
} }
int pkt_normalizer_get_error_count(const pn_struct* pn) { int pkt_normalizer_get_error_count(const struct pn_struct* pn) {
if (!pn) return 0; if (!pn) return 0;
if (pn->is_packer) { if (pn->is_packer) {
return pn->u.packer.error_count; return pn->u.packer.error_count;
} }
return pn->u.unpacker.error_count; return pn->u.unpacker.error_count;
} }
void pkt_normalizer_reset_error_count(pn_struct* pn) { void pkt_normalizer_reset_error_count(struct pn_struct* pn) {
if (!pn) return; if (!pn) return;
if (pn->is_packer) { if (pn->is_packer) {
pn->u.packer.error_count = 0; pn->u.packer.error_count = 0;
@ -369,17 +369,17 @@ void pkt_normalizer_reset_error_count(pn_struct* pn) {
pn->u.unpacker.error_count = 0; pn->u.unpacker.error_count = 0;
} }
} }
void pkt_normalizer_flush(pn_struct* pn) { void pkt_normalizer_flush(struct pn_struct* pn) {
if (!pn || !pn->is_packer) return; if (!pn || !pn->is_packer) return;
if (pn->u.packer.len > 0) { if (pn->u.packer.len > 0) {
send_buf(pn); send_buf(pn);
} }
} }
static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) { static void unpacker_handler(struct ll_queue* q, struct ll_entry* unused, void* arg) {
(void)unused; (void)unused;
pn_struct* pn = arg; struct pn_struct* pn = arg;
while (queue_entry_count(q) > 0) { while (queue_entry_count(q) > 0) {
ll_entry_t* entry = queue_entry_get(q); struct ll_entry* entry = queue_entry_get(q);
uint8_t* data = ll_entry_data(entry); uint8_t* data = ll_entry_data(entry);
size_t total = ll_entry_size(entry); size_t total = ll_entry_size(entry);
uint16_t payload_len = *(uint16_t*)data; uint16_t payload_len = *(uint16_t*)data;
@ -424,7 +424,7 @@ static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
/* Проверить, не собрали ли уже весь пакет */ /* Проверить, не собрали ли уже весь пакет */
if (pn->u.unpacker.len >= pn->u.unpacker.total_len) { if (pn->u.unpacker.len >= pn->u.unpacker.total_len) {
if (pn->u.unpacker.len == pn->u.unpacker.total_len) { if (pn->u.unpacker.len == pn->u.unpacker.total_len) {
ll_entry_t* out = queue_entry_new(pn->u.unpacker.total_len); struct ll_entry* out = queue_entry_new(pn->u.unpacker.total_len);
if (out) { if (out) {
memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len); memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len);
queue_entry_put(pn->output, out); queue_entry_put(pn->output, out);
@ -458,7 +458,7 @@ static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
/* Проверить, не собрали ли уже весь пакет */ /* Проверить, не собрали ли уже весь пакет */
if (pn->u.unpacker.len >= pn->u.unpacker.total_len) { if (pn->u.unpacker.len >= pn->u.unpacker.total_len) {
if (pn->u.unpacker.len == pn->u.unpacker.total_len) { if (pn->u.unpacker.len == pn->u.unpacker.total_len) {
ll_entry_t* out = queue_entry_new(pn->u.unpacker.total_len); struct ll_entry* out = queue_entry_new(pn->u.unpacker.total_len);
if (out) { if (out) {
memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len); memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len);
queue_entry_put(pn->output, out); queue_entry_put(pn->output, out);
@ -576,7 +576,7 @@ static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
/* Проверить, собрали ли весь пакет */ /* Проверить, собрали ли весь пакет */
if (pn->u.unpacker.len >= pn->u.unpacker.total_len) { if (pn->u.unpacker.len >= pn->u.unpacker.total_len) {
if (pn->u.unpacker.len == pn->u.unpacker.total_len) { if (pn->u.unpacker.len == pn->u.unpacker.total_len) {
ll_entry_t* out = queue_entry_new(pn->u.unpacker.total_len); struct ll_entry* out = queue_entry_new(pn->u.unpacker.total_len);
if (out) { if (out) {
memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len); memcpy(ll_entry_data(out), pn->u.unpacker.buf, pn->u.unpacker.total_len);
queue_entry_put(pn->output, out); queue_entry_put(pn->output, out);
@ -589,7 +589,7 @@ static void unpacker_handler(ll_queue_t* q, ll_entry_t* unused, void* arg) {
} }
} else { } else {
/* Обычная запись (не часть фрагмента) */ /* Обычная запись (не часть фрагмента) */
ll_entry_t* out = queue_entry_new(L); struct ll_entry* out = queue_entry_new(L);
if (out) { if (out) {
memcpy(ll_entry_data(out), cg + cg_pos, L); memcpy(ll_entry_data(out), cg + cg_pos, L);
queue_entry_put(pn->output, out); queue_entry_put(pn->output, out);

6
src/pkt_normalizer.h

@ -3,7 +3,7 @@
#define PKT_NORMALIZER_H #define PKT_NORMALIZER_H
#include "ll_queue.h" #include "ll_queue.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include <stdint.h> #include <stdint.h>
/* Default fragment reassembly timeout in uasync timebase units (0.1 ms) */ /* Default fragment reassembly timeout in uasync timebase units (0.1 ms) */
@ -18,8 +18,8 @@
typedef void (*pkt_normalizer_service_callback_t)(void* user_data, uint8_t type, const uint8_t* data, size_t len); typedef void (*pkt_normalizer_service_callback_t)(void* user_data, uint8_t type, const uint8_t* data, size_t len);
struct pn_struct { struct pn_struct {
ll_queue_t* input; struct ll_queue* input;
ll_queue_t* output; struct ll_queue* output;
uasync_t* ua; uasync_t* ua;
int is_packer; int is_packer;
union { union {

46
src/secure_channel.h

@ -10,6 +10,22 @@
#define SC_PUBKEY_SIZE 32 #define SC_PUBKEY_SIZE 32
#define SC_HASH_SIZE 32 #define SC_HASH_SIZE 32
#define SC_NONCE_SIZE 24 #define SC_NONCE_SIZE 24
#define SC_SHARED_SECRET_SIZE SC_HASH_SIZE
#define SC_SESSION_KEY_SIZE 16
#define SC_TAG_SIZE 8
#define SC_CRC32_SIZE 4
// Коды возврата
#define SC_OK 0
#define SC_ERR_INVALID_ARG -1
#define SC_ERR_CRYPTO -2
#define SC_ERR_NOT_INITIALIZED -3
#define SC_ERR_AUTH_FAILED -4
#define SC_ERR_CRC_FAILED -5
// Типы
typedef int sc_status_t;
typedef struct secure_channel sc_context_t;
// Контекст защищенного канала // Контекст защищенного канала
struct secure_channel { struct secure_channel {
@ -19,28 +35,36 @@ struct secure_channel {
/* Ключи пира (после key exchange) */ /* Ключи пира (после key exchange) */
uint8_t peer_public_key[SC_PUBKEY_SIZE]; uint8_t peer_public_key[SC_PUBKEY_SIZE];
uint8_t shared_key[SC_HASH_SIZE]; /* Derived shared key */ uint8_t session_key[SC_SESSION_KEY_SIZE]; /* Derived session key */
/* Nonces для отправки и приема */ /* Nonces для отправки и приема */
uint8_t send_nonce[SC_NONCE_SIZE]; uint8_t send_nonce[SC_NONCE_SIZE];
uint8_t recv_nonce[SC_NONCE_SIZE]; uint8_t recv_nonce[SC_NONCE_SIZE];
uint8_t has_peer_key; uint8_t initialized;
uint8_t peer_key_set;
uint8_t session_ready;
uint32_t tx_counter;
uint32_t rx_counter;
}; };
// Функции инициализации // Функции инициализации
void sc_init(void); sc_status_t sc_generate_keypair(sc_context_t *ctx);
int sc_generate_keypair(uint8_t *private_key, uint8_t *public_key); sc_status_t sc_init_local_keys(sc_context_t *ctx,
const uint8_t *public_key,
const uint8_t *private_key);
sc_status_t sc_set_peer_public_key(sc_context_t *ctx,
const uint8_t *peer_public_key);
// Криптографические операции // Криптографические операции
int sc_encrypt(const struct secure_channel *ctx, sc_status_t sc_encrypt(sc_context_t *ctx,
const uint8_t *plaintext, size_t plaintext_len, const uint8_t *plaintext, size_t plaintext_len,
uint8_t *ciphertext, size_t *ciphertext_len); uint8_t *ciphertext, size_t *ciphertext_len);
int sc_decrypt(struct secure_channel *ctx, sc_status_t sc_decrypt(sc_context_t *ctx,
const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *ciphertext, size_t ciphertext_len,
uint8_t *plaintext, size_t *plaintext_len); uint8_t *plaintext, size_t *plaintext_len);
void sc_derive_shared_key(struct secure_channel *ctx); void sc_derive_shared_key(sc_context_t *ctx);
#endif // SECURE_CHANNEL_H #endif // SECURE_CHANNEL_H

2
src/tun_if.c

@ -116,7 +116,7 @@ int tun_create(struct tun_config *config) {
if (config->mtu > 0) { if (config->mtu > 0) {
if (tun_set_mtu(config->ifname, config->mtu) < 0) { if (tun_set_mtu(config->ifname, config->mtu) < 0) {
// Non-fatal error, just warn // Non-fatal error, just warn
DEBUG_WARNING(DEBUG_CATEGORY_TUN, "Failed to set MTU on %s", config->ifname); DEBUG_WARN(DEBUG_CATEGORY_TUN, "Failed to set MTU on %s", config->ifname);
} }
} }

2
src/utun_fixes.c

@ -2,7 +2,7 @@
#include "routing.h" #include "routing.h"
#include "etcp_connections.h" #include "etcp_connections.h"
#include "config_parser.h" #include "config_parser.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
conn_handle_t* route_get_next_hop(routing_table_t* rt, uint32_t dest_ip) { conn_handle_t* route_get_next_hop(routing_table_t* rt, uint32_t dest_ip) {
route_entry_t route = {0}; route_entry_t route = {0};

2
src/utun_instance.c

@ -4,7 +4,7 @@
#include "tun_if.h" #include "tun_if.h"
#include "routing.h" #include "routing.h"
#include "etcp_connections.h" #include "etcp_connections.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include "debug_config.h" #include "debug_config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>

4
src/utun_instance.h

@ -12,6 +12,7 @@ struct uasync_s;
struct routing_table; struct routing_table;
struct ETCP_CONNECTIONS; struct ETCP_CONNECTIONS;
typedef struct ETCP_CONNECTIONS conn_handle_t; typedef struct ETCP_CONNECTIONS conn_handle_t;
struct ETCP_SOCKET;
// uTun instance configuration // uTun instance configuration
struct UTUN_INSTANCE { struct UTUN_INSTANCE {
@ -41,6 +42,9 @@ struct UTUN_INSTANCE {
// Connections // Connections
conn_handle_t **connections; conn_handle_t **connections;
int connection_count; int connection_count;
// First listen socket
struct ETCP_SOCKET* first_listen_socket;
}; };
// Functions // Functions

36
tests/Makefile.am

@ -3,52 +3,52 @@ check_PROGRAMS = \
test_etcp \ test_etcp \
test_etcp_stress \ test_etcp_stress \
test_etcp_simple \ test_etcp_simple \
test_u_async_comprehensive \ test_lib_comprehensive \
test_u_async_simple \ test_lib_simple \
test_u_async_performance \ test_lib_performance \
test_debug_config \ test_debug_config \
test_ll_queue_comprehensive \ test_ll_queue_comprehensive \
test_ecc_encrypt \ test_ecc_encrypt \
test_routing test_routing
test_pkt_normalizer_SOURCES = test_pkt_normalizer.c test_pkt_normalizer_SOURCES = test_pkt_normalizer.c
test_pkt_normalizer_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_pkt_normalizer_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_SOURCES = test_etcp.c test_etcp_SOURCES = test_etcp.c
test_etcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_etcp_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_stress_SOURCES = test_etcp_stress.c test_etcp_stress_SOURCES = test_etcp_stress.c
test_etcp_stress_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_etcp_stress_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_etcp_simple_SOURCES = test_etcp_simple.c test_etcp_simple_SOURCES = test_etcp_simple.c
test_etcp_simple_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_etcp_simple_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_u_async_comprehensive_SOURCES = test_u_async_comprehensive.c test_lib_comprehensive_SOURCES = test_lib_comprehensive.c
test_u_async_comprehensive_CFLAGS = -I$(top_srcdir)/u_async test_lib_comprehensive_CFLAGS = -I$(top_srcdir)/lib
test_u_async_simple_SOURCES = test_u_async_simple.c test_lib_simple_SOURCES = test_lib_simple.c
test_u_async_simple_CFLAGS = -I$(top_srcdir)/u_async test_lib_simple_CFLAGS = -I$(top_srcdir)/lib
test_u_async_performance_SOURCES = test_u_async_performance.c test_lib_performance_SOURCES = test_lib_performance.c
test_u_async_performance_CFLAGS = -I$(top_srcdir)/u_async test_lib_performance_CFLAGS = -I$(top_srcdir)/lib
test_debug_config_SOURCES = test_debug_config.c test_debug_config_SOURCES = test_debug_config.c
test_debug_config_CFLAGS = -I$(top_srcdir)/u_async test_debug_config_CFLAGS = -I$(top_srcdir)/lib
test_ll_queue_comprehensive_SOURCES = test_ll_queue_comprehensive.c test_ll_queue_comprehensive_SOURCES = test_ll_queue_comprehensive.c
test_ll_queue_comprehensive_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_ll_queue_comprehensive_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_ecc_encrypt_SOURCES = test_ecc_encrypt.c test_ecc_encrypt_SOURCES = test_ecc_encrypt.c
test_ecc_encrypt_CFLAGS = -I$(top_srcdir)/tinycrypt/lib/include \ test_ecc_encrypt_CFLAGS = -I$(top_srcdir)/tinycrypt/lib/include \
-I$(top_srcdir)/tinycrypt/lib/source \ -I$(top_srcdir)/tinycrypt/lib/source \
-I$(top_srcdir)/src -I$(top_srcdir)/u_async -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_routing_SOURCES = test_routing.c test_routing_SOURCES = test_routing.c
test_routing_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/u_async test_routing_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
# Link all tests against the libraries # Link all tests against the libraries
LDADD = \ LDADD = \
$(top_builddir)/u_async/libuasync.a \ $(top_builddir)/lib/libuasync.a \
-lpthread -lpthread
# Register tests with automake # Register tests with automake

2
tests/simple_uasync.c

@ -1,6 +1,6 @@
// simple_uasync.c - Minimal uasync implementation for tests // simple_uasync.c - Minimal uasync implementation for tests
#include "simple_uasync.h" #include "simple_uasync.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>

2
tests/simple_uasync.h

@ -6,7 +6,7 @@
#include <stdint.h> #include <stdint.h>
// These functions are only available when linking with simple_uasync.o // These functions are only available when linking with simple_uasync.o
// instead of u_async.o // instead of lib.o
// Advance time by delta_tb timebase units and process expired timers // Advance time by delta_tb timebase units and process expired timers
void simple_uasync_advance_time(uint32_t delta_tb); void simple_uasync_advance_time(uint32_t delta_tb);

2
tests/test_debug_config.c

@ -9,7 +9,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
static int test_passed = 0; static int test_passed = 0;
static int test_failed = 0; static int test_failed = 0;

4
tests/test_intensive_memory_pool.c

@ -11,8 +11,8 @@
#include "../src/ll_queue.h" #include "../src/ll_queue.h"
#include "../src/memory_pool.h" #include "../src/memory_pool.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
static int waiter_callback_count = 0; static int waiter_callback_count = 0;

4
tests/test_ll_queue_comprehensive.c

@ -11,8 +11,8 @@
#include <sys/time.h> #include <sys/time.h>
#include "../src/ll_queue.h" #include "../src/ll_queue.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
/* Test statistics */ /* Test statistics */
static struct { static struct {

4
tests/test_memory_pool_and_config.c

@ -10,8 +10,8 @@
#include "../src/ll_queue.h" #include "../src/ll_queue.h"
#include "../src/memory_pool.h" #include "../src/memory_pool.h"
#include "../u_async/u_async.h" #include "../lib/u_async.h"
#include "../u_async/debug_config.h" #include "../lib/debug_config.h"
static int test_callback_count = 0; static int test_callback_count = 0;

4
tests/test_u_async_comprehensive.c

@ -1,5 +1,5 @@
/** /**
* Comprehensive unit tests for u_async module * Comprehensive unit tests for lib module
* Focus on: timers, sockets, error handling, race conditions * Focus on: timers, sockets, error handling, race conditions
*/ */
@ -439,7 +439,7 @@ static void test_concurrent_operations(void) {
/* Main test runner */ /* Main test runner */
int main(void) { int main(void) {
printf("=== u_async Comprehensive Unit Tests ===\n"); printf("=== lib Comprehensive Unit Tests ===\n");
printf("Testing race conditions, memory management, and error handling\n\n"); printf("Testing race conditions, memory management, and error handling\n\n");
/* Run all tests */ /* Run all tests */

4
tests/test_u_async_performance.c

@ -1,5 +1,5 @@
/** /**
* Performance benchmark for u_async socket management * Performance benchmark for lib socket management
* Compares array-based vs linked list implementation * Compares array-based vs linked list implementation
*/ */
@ -238,7 +238,7 @@ static void benchmark_scalability(void) {
} }
int main(void) { int main(void) {
printf("u_async Socket Management Performance Benchmark\n"); printf("lib Socket Management Performance Benchmark\n");
printf("================================================\n\n"); printf("================================================\n\n");
/* Run benchmarks */ /* Run benchmarks */

4
tests/test_u_async_simple.c

@ -1,5 +1,5 @@
/** /**
* Simple test for u_async race condition fix * Simple test for lib race condition fix
*/ */
#include <stdio.h> #include <stdio.h>
@ -19,7 +19,7 @@ static void simple_timer_callback(void* arg) {
} }
int main(void) { int main(void) {
printf("=== Simple u_async race condition test ===\n"); printf("=== Simple lib race condition test ===\n");
uasync_t* ua = uasync_create(); uasync_t* ua = uasync_create();
if (!ua) { if (!ua) {

Loading…
Cancel
Save