You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

117 lines
3.2 KiB

#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;
}