- Fixed incorrect init_connections() call in test_etcp_simple_traffic.c (was calling server_instance instead of client_instance) - Fixed double free in timeout_heap_pop() when handling deleted elements - Enhanced NULL pointer safety in uasync_print_resources() by removing complex heap manipulation - Added debug logging to timeout_heap_pop() for better error tracking Test results: test_etcp_simple_traffic now passes without double free errors
117 lines
3.2 KiB
C
117 lines
3.2 KiB
C
#include "utun_test_socket_api.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
void utun_test_packet_queue_init(struct utun_test_packet_queue* queue) {
|
|
if (!queue) return;
|
|
queue->head = NULL;
|
|
queue->tail = NULL;
|
|
queue->count = 0;
|
|
}
|
|
|
|
void utun_test_packet_queue_cleanup(struct utun_test_packet_queue* queue) {
|
|
if (!queue) return;
|
|
|
|
struct utun_test_packet* pkt = queue->head;
|
|
while (pkt) {
|
|
struct utun_test_packet* next = pkt->next;
|
|
free(pkt->data);
|
|
free(pkt);
|
|
pkt = next;
|
|
}
|
|
|
|
queue->head = NULL;
|
|
queue->tail = NULL;
|
|
queue->count = 0;
|
|
}
|
|
|
|
void utun_test_packet_queue_push(struct utun_test_packet_queue* queue,
|
|
const uint8_t* data, size_t len,
|
|
const struct sockaddr* addr, socklen_t addrlen) {
|
|
if (!queue || !data) return;
|
|
|
|
struct utun_test_packet* pkt = calloc(1, sizeof(*pkt));
|
|
if (!pkt) return;
|
|
|
|
pkt->data = malloc(len);
|
|
if (!pkt->data) {
|
|
free(pkt);
|
|
return;
|
|
}
|
|
|
|
memcpy(pkt->data, data, len);
|
|
pkt->len = len;
|
|
|
|
if (addr && addrlen > 0 && addrlen <= sizeof(pkt->addr)) {
|
|
memcpy(&pkt->addr, addr, addrlen);
|
|
pkt->addrlen = addrlen;
|
|
}
|
|
|
|
pkt->next = NULL;
|
|
|
|
if (queue->tail) {
|
|
queue->tail->next = pkt;
|
|
} else {
|
|
queue->head = pkt;
|
|
}
|
|
queue->tail = pkt;
|
|
queue->count++;
|
|
}
|
|
|
|
struct utun_test_packet* utun_test_packet_queue_pop(struct utun_test_packet_queue* queue) {
|
|
if (!queue || !queue->head) return NULL;
|
|
|
|
struct utun_test_packet* pkt = queue->head;
|
|
queue->head = pkt->next;
|
|
|
|
if (!queue->head) {
|
|
queue->tail = NULL;
|
|
}
|
|
|
|
queue->count--;
|
|
pkt->next = NULL;
|
|
|
|
return pkt;
|
|
}
|
|
|
|
size_t utun_test_packet_queue_count(struct utun_test_packet_queue* queue) {
|
|
return queue ? queue->count : 0;
|
|
}
|
|
|
|
ssize_t utun_test_default_on_send(const uint8_t* data, size_t len,
|
|
const struct sockaddr* dest_addr, socklen_t dest_addrlen,
|
|
void* user_data) {
|
|
struct utun_test_socket_api* api = (struct utun_test_socket_api*)user_data;
|
|
if (!api || !data || len == 0) return -1;
|
|
|
|
utun_test_packet_queue_push(&api->send_queue, data, len, dest_addr, dest_addrlen);
|
|
return len;
|
|
}
|
|
|
|
ssize_t utun_test_default_on_recv(uint8_t* buffer, size_t buffer_size,
|
|
struct sockaddr* src_addr, socklen_t* src_addrlen,
|
|
void* user_data) {
|
|
struct utun_test_socket_api* api = (struct utun_test_socket_api*)user_data;
|
|
if (!api || !buffer || buffer_size == 0) return -1;
|
|
|
|
struct utun_test_packet* pkt = utun_test_packet_queue_pop(&api->recv_queue);
|
|
if (!pkt) {
|
|
errno = EAGAIN;
|
|
return -1;
|
|
}
|
|
|
|
size_t to_copy = (pkt->len < buffer_size) ? pkt->len : buffer_size;
|
|
memcpy(buffer, pkt->data, to_copy);
|
|
|
|
if (src_addr && src_addrlen && *src_addrlen > 0) {
|
|
socklen_t copy_len = (pkt->addrlen < *src_addrlen) ? pkt->addrlen : *src_addrlen;
|
|
memcpy(src_addr, &pkt->addr, copy_len);
|
|
*src_addrlen = copy_len;
|
|
}
|
|
|
|
free(pkt->data);
|
|
free(pkt);
|
|
|
|
return to_copy;
|
|
} |