Refactor etcp_api: per-instance bindings with struct ETCP_BINDINGS
Changed from global bindings to per-instance bindings: 1. Added struct ETCP_BINDINGS in etcp_api.h: - Contains array of callbacks[ETCP_MAX_BINDINGS] - NULL means not bound 2. Updated UTUN_INSTANCE (utun_instance.h): - Added field: struct ETCP_BINDINGS api_bindings - Initialized to NULL by calloc in utun_instance_create 3. Updated API functions (etcp_api.h/c): - etcp_bind(inst, id, callback) - per-instance binding - etcp_unbind(inst, id) - per-instance unbinding - Removed etcp_api_init/etcp_api_deinit (not needed) - etcp_int_recv now uses conn->instance->api_bindings.callbacks[id] 4. Updated test_etcp_api.c: - Separate callbacks for server and client - Register via etcp_bind(server_instance, ...) and etcp_bind(client_instance, ...) - Removed global etcp_api_init/etcp_api_deinit calls Test passes: All 100 packets transmitted in each direction.
This commit is contained in:
1 parent
1a7356e923
commit
d694c92b1f
4 files changed
+124
-126
No files matched your search
+58
-48
@@ -143,11 +143,12 @@ static int verify_packet_data(uint8_t* buffer, int size, int expected_seq) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Универсальный callback для получения пакетов
|
||||
// Определяет направление по соединению (client_conn vs server_conn)
|
||||
static void recv_callback(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
// Callback для получения пакетов на сервере (forward direction)
|
||||
static void server_recv_callback(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
(void)conn;
|
||||
|
||||
if (!entry || !entry->dgram || entry->len < PACKET_HEADER_SIZE + 1) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Received invalid packet");
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Server received invalid packet");
|
||||
if (entry) {
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
@@ -155,30 +156,39 @@ static void recv_callback(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Определяем направление по соединению
|
||||
if (conn == server_conn) {
|
||||
// Пакет пришел на сервер (forward direction: client->server)
|
||||
if (verify_packet_data(entry->dgram, entry->len, packets_received_fwd)) {
|
||||
packets_received_fwd++;
|
||||
} else {
|
||||
int seq = entry->dgram[1] | (entry->dgram[2] << 8);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Server packet verification failed, seq=%d, expected=%d",
|
||||
seq, packets_received_fwd);
|
||||
}
|
||||
} else if (conn == client_conn) {
|
||||
// Пакет пришел на клиент (backward direction: server->client)
|
||||
if (verify_packet_data(entry->dgram, entry->len, packets_received_back)) {
|
||||
packets_received_back++;
|
||||
} else {
|
||||
int seq = entry->dgram[1] | (entry->dgram[2] << 8);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Client packet verification failed, seq=%d, expected=%d",
|
||||
seq, packets_received_back);
|
||||
}
|
||||
if (verify_packet_data(entry->dgram, entry->len, packets_received_fwd)) {
|
||||
packets_received_fwd++;
|
||||
} else {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Unknown connection %p", (void*)conn);
|
||||
int seq = entry->dgram[1] | (entry->dgram[2] << 8);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Server packet verification failed, seq=%d, expected=%d",
|
||||
seq, packets_received_fwd);
|
||||
}
|
||||
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
}
|
||||
|
||||
// Callback для получения пакетов на клиенте (backward direction)
|
||||
static void client_recv_callback(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
(void)conn;
|
||||
|
||||
if (!entry || !entry->dgram || entry->len < PACKET_HEADER_SIZE + 1) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Client received invalid packet");
|
||||
if (entry) {
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (verify_packet_data(entry->dgram, entry->len, packets_received_back)) {
|
||||
packets_received_back++;
|
||||
} else {
|
||||
int seq = entry->dgram[1] | (entry->dgram[2] << 8);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Client packet verification failed, seq=%d, expected=%d",
|
||||
seq, packets_received_back);
|
||||
}
|
||||
|
||||
// Освобождаем entry и dgram
|
||||
queue_entry_free(entry);
|
||||
queue_dgram_free(entry);
|
||||
}
|
||||
@@ -456,26 +466,12 @@ int main() {
|
||||
debug_set_categories(DEBUG_CATEGORY_ALL);
|
||||
|
||||
utun_instance_set_tun_init_enabled(0);
|
||||
|
||||
// Инициализация ETCP API
|
||||
etcp_api_init();
|
||||
|
||||
// Регистрируем callback для получения пакетов (один на все соединения)
|
||||
if (etcp_bind(DATA_PACKET_ID, recv_callback) != 0) {
|
||||
printf("Failed to bind callback\n");
|
||||
etcp_api_deinit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Callback registered for ID=%d\n", DATA_PACKET_ID);
|
||||
|
||||
printf("Creating server...\n");
|
||||
ua = uasync_create();
|
||||
server_instance = utun_instance_create(ua, "test_pkt_normalizer_etcp_server.conf");
|
||||
if (!server_instance || init_connections(server_instance) < 0) {
|
||||
printf("Failed to create server\n");
|
||||
etcp_unbind(DATA_PACKET_ID);
|
||||
etcp_api_deinit();
|
||||
return 1;
|
||||
}
|
||||
printf("Server created, waiting for connection...\n\n");
|
||||
@@ -484,11 +480,23 @@ int main() {
|
||||
client_instance = utun_instance_create(ua, "test_pkt_normalizer_etcp_client.conf");
|
||||
if (!client_instance || init_connections(client_instance) < 0) {
|
||||
printf("Failed to create client\n");
|
||||
etcp_unbind(DATA_PACKET_ID);
|
||||
etcp_api_deinit();
|
||||
return 1;
|
||||
}
|
||||
printf("Client created\n\n");
|
||||
|
||||
// Регистрируем callbacks для получения пакетов (per-instance)
|
||||
if (etcp_bind(server_instance, DATA_PACKET_ID, server_recv_callback) != 0) {
|
||||
printf("Failed to bind server callback\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (etcp_bind(client_instance, DATA_PACKET_ID, client_recv_callback) != 0) {
|
||||
printf("Failed to bind client callback\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Callbacks registered for ID=%d (server=%p, client=%p)\n",
|
||||
DATA_PACKET_ID, (void*)server_recv_callback, (void*)client_recv_callback);
|
||||
|
||||
printf("Sending %d packets in each direction via etcp_send...\n", TOTAL_PACKETS);
|
||||
packet_timeout_id = uasync_set_timeout(ua, 1000, NULL, monitor_and_send);
|
||||
@@ -499,16 +507,18 @@ int main() {
|
||||
}
|
||||
|
||||
printf("\nCleaning up...\n");
|
||||
|
||||
|
||||
if (packet_timeout_id) uasync_cancel_timeout(ua, packet_timeout_id);
|
||||
if (global_timeout_id) uasync_cancel_timeout(ua, global_timeout_id);
|
||||
|
||||
|
||||
// Отписываемся от callbacks
|
||||
etcp_unbind(DATA_PACKET_ID);
|
||||
|
||||
// Деинициализация ETCP API
|
||||
etcp_api_deinit();
|
||||
|
||||
if (server_instance) {
|
||||
etcp_unbind(server_instance, DATA_PACKET_ID);
|
||||
}
|
||||
if (client_instance) {
|
||||
etcp_unbind(client_instance, DATA_PACKET_ID);
|
||||
}
|
||||
|
||||
if (server_instance) {
|
||||
server_instance->running = 0;
|
||||
utun_instance_destroy(server_instance);
|
||||
|
||||
Reference in new issue
Block a user