Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ compile_commands.json

/build/output/

**/run_tests

*.dSYM/
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ set(SOURCE_FILES
internal/get_default_interface_and_mac.c
internal/datatype_allocator.c
internal/datatype_vector.c
internal/datatype_hashmap.c
internal/pcap_open.c
internal/pcap_send.c
internal/check_existing_listener.c
Expand Down
65 changes: 25 additions & 40 deletions src/cleanup_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdatomic.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static inline void cleanup_connection_resources(const enum ConnectionType connection_type, void* const connection) {
Expand All @@ -13,65 +14,49 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec
allocator_destroy(&client->pending_messages_memory_allocator);
allocator_destroy(&client->packets_completed_memory_allocator);

vector_destroy(&client->packets_sending);
vector_destroy(&client->pending_messages);
vector_destroy(&client->packets_completed);
hashmap_destroy(&client->pending_messages);
hashmap_destroy(&client->packets_sending);
hashmap_destroy(&client->packets_completed);
} else {
struct SwiftNetServer* const server = (struct SwiftNetServer*)connection;

allocator_destroy(&server->packets_sending_memory_allocator);
allocator_destroy(&server->pending_messages_memory_allocator);
allocator_destroy(&server->packets_completed_memory_allocator);

vector_destroy(&server->packets_sending);
vector_destroy(&server->pending_messages);
vector_destroy(&server->packets_completed);
hashmap_destroy(&server->pending_messages);
hashmap_destroy(&server->packets_sending);
hashmap_destroy(&server->packets_completed);
}
}

static inline void remove_listener(const enum ConnectionType connection_type, const char* interface_name, void* const connection) {
vector_lock(&listeners);
static inline void remove_listener(const enum ConnectionType connection_type, const char* const interface_name, void* const connection) {
LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock);

for (uint16_t i = 0; i < listeners.size; i++) {
struct Listener* const current_listener = vector_get(&listeners, i);
if (strcmp(interface_name, current_listener->interface_name) == 0) {
if (connection_type == CONNECTION_TYPE_CLIENT) {
vector_lock(&current_listener->client_connections);
const uint32_t interface_len = strlen(interface_name);

for (uint16_t inx = 0; inx < current_listener->client_connections.size; inx++) {
struct SwiftNetClientConnection* const current_connection = vector_get(&current_listener->client_connections, i);
if (current_connection != connection) {
continue;
}
struct Listener* const listener = hashmap_get(interface_name, interface_len, &listeners);
if (listener == NULL) {
UNLOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock);

vector_remove(&current_listener->client_connections, inx);

break;
}

vector_unlock(&current_listener->client_connections);
} else {
vector_lock(&current_listener->servers);
return;
}

for (uint16_t inx = 0; inx < current_listener->servers.size; inx++) {
struct SwiftNetClientConnection* const current_connection = vector_get(&current_listener->servers, i);
if (current_connection != connection) {
continue;
}
if (connection_type == CONNECTION_TYPE_CLIENT) {
LOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);

vector_remove(&current_listener->servers, inx);
hashmap_remove(&((struct SwiftNetClientConnection*)connection)->port_info.source_port, sizeof(uint16_t), &listener->client_connections);

break;
}
UNLOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);
} else {
LOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock);

vector_unlock(&current_listener->servers);
}
hashmap_remove(&((struct SwiftNetServer*)connection)->server_port, sizeof(uint16_t), &listener->servers);

break;
}
UNLOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock);
}

vector_unlock(&listeners);
UNLOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock);
}

static inline const char* get_interface_name(const bool loopback) {
Expand Down Expand Up @@ -127,7 +112,7 @@ static inline void close_threads(const enum ConnectionType connection_type, void
void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) {
cleanup_connection_resources(CONNECTION_TYPE_CLIENT, client);

const char* interface_name = get_interface_name(client->loopback);
const char* const interface_name = get_interface_name(client->loopback);

remove_listener(CONNECTION_TYPE_CLIENT, interface_name, client);

Expand Down
20 changes: 12 additions & 8 deletions src/cleanup_swiftnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@
#include <stdio.h>

static inline void close_listeners() {
vector_lock(&listeners);
LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock);

for (uint16_t i = 0; i < listeners.size; i++) {
struct Listener* const current_listener = vector_get(&listeners, i);
struct SwiftNetHashMap* const listeners_map = &listeners;

LOOP_HASHMAP(listeners_map,
struct Listener* const current_listener = hashmap_data;

pcap_breakloop(current_listener->pcap);

pthread_join(current_listener->listener_thread, NULL);

pcap_close(current_listener->pcap);

vector_destroy(&current_listener->client_connections);
vector_destroy(&current_listener->servers);
}
hashmap_destroy(&current_listener->client_connections);
hashmap_destroy(&current_listener->servers);
)

vector_destroy(&listeners);
hashmap_destroy(&listeners);
}

static inline void close_background_service() {
Expand All @@ -35,11 +37,12 @@ void swiftnet_cleanup() {
allocator_destroy(&server_packet_data_memory_allocator);
allocator_destroy(&client_packet_data_memory_allocator);
allocator_destroy(&packet_buffer_memory_allocator);
allocator_destroy(&hashmap_item_memory_allocator);

#ifdef SWIFT_NET_REQUESTS
allocator_destroy(&requests_sent_memory_allocator);

vector_destroy(&requests_sent);
hashmap_destroy(&requests_sent);
#endif

close_listeners();
Expand All @@ -48,6 +51,7 @@ void swiftnet_cleanup() {
allocator_destroy(&client_connection_memory_allocator);

allocator_destroy(&listener_memory_allocator);
allocator_destroy(&uint16_memory_allocator);

#ifdef SWIFT_NET_INTERNAL_TESTING
printf("Bytes leaked: %d\nItems leaked: %d\n", bytes_leaked, items_leaked);
Expand Down
32 changes: 10 additions & 22 deletions src/execute_packet_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@
#include <unistd.h>
#include <pthread.h>

static inline void lock_packet_queue(struct PacketCallbackQueue* const packet_queue) {
enum PacketQueueOwner owner_none = NONE;
while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, SOME, memory_order_acquire, memory_order_relaxed)) {
owner_none = NONE;
}
}

static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) {
lock_packet_queue(packet_queue);
LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);

if(packet_queue->first_node == NULL) {
atomic_store_explicit(&packet_queue->owner, NONE, memory_order_release);
UNLOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);
return NULL;
}

Expand All @@ -28,29 +21,24 @@ static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struc
packet_queue->first_node = NULL;
packet_queue->last_node = NULL;

atomic_store_explicit(&packet_queue->owner, NONE, memory_order_release);
UNLOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);

return node_to_process;
}

packet_queue->first_node = node_to_process->next;

atomic_store_explicit(&packet_queue->owner, NONE, memory_order_release);
UNLOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);

return node_to_process;
}

static inline void remove_pending_message_from_vector(struct SwiftNetVector* const pending_messages, struct SwiftNetPendingMessage* const pending_message) {
vector_lock(pending_messages);
static inline void remove_pending_message_from_hashmap(struct SwiftNetHashMap* const pending_messages, struct SwiftNetPendingMessage* const pending_message) {
LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock);

for (uint32_t i = 0; i < pending_messages->size; i++) {
const struct SwiftNetPendingMessage* const current_pending_message = vector_get(pending_messages, i);
if (current_pending_message == pending_message) {
vector_remove(pending_messages, i);
}
}
hashmap_remove(&pending_message->packet_id, sizeof(uint16_t), pending_messages);

vector_unlock(pending_messages);
UNLOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock);
}

void execute_packet_callback(
Expand All @@ -61,7 +49,7 @@ void execute_packet_callback(
struct SwiftNetMemoryAllocator* const pending_message_memory_allocator,
_Atomic bool* closing,
void* const connection,
struct SwiftNetVector* const pending_messages,
struct SwiftNetHashMap* const pending_messages,
_Atomic(void*)* user_data,
pthread_mutex_t* const execute_callback_mtx,
pthread_cond_t* const execute_callback_cond
Expand Down Expand Up @@ -92,7 +80,7 @@ void execute_packet_callback(
}

if(node->pending_message != NULL) {
remove_pending_message_from_vector(pending_messages, node->pending_message);
remove_pending_message_from_hashmap(pending_messages, node->pending_message);
}

void (*const packet_handler_loaded)(void* const, void* const) = atomic_load(packet_handler);
Expand Down
57 changes: 19 additions & 38 deletions src/handle_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@
#include "internal/internal.h"
#include <stddef.h>

static inline void lock_packet_queue(struct PacketQueue* const packet_queue) {
enum PacketQueueOwner owner_none = NONE;
while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, SOME, memory_order_acquire, memory_order_relaxed)) {
owner_none = NONE;
}
}

static inline void unlock_packet_queue(struct PacketQueue* const packet_queue) {
atomic_store_explicit(&packet_queue->owner, NONE, memory_order_release);
}

static inline void insert_queue_node(
struct PacketQueueNode* const new_node,
struct PacketQueue* const packet_queue,
Expand All @@ -31,7 +20,7 @@ static inline void insert_queue_node(
return;
}

lock_packet_queue(packet_queue);
LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);

if(packet_queue->last_node == NULL) {
packet_queue->last_node = new_node;
Expand All @@ -45,7 +34,7 @@ static inline void insert_queue_node(
packet_queue->first_node = new_node;
}

unlock_packet_queue(packet_queue);
UNLOCK_ATOMIC_DATA_TYPE(&packet_queue->locked);

return;
}
Expand Down Expand Up @@ -174,41 +163,33 @@ static void handle_client_init(struct SwiftNetClientConnection* user, const stru
atomic_store_explicit(&client_connection->initialized, true, memory_order_release);
}

static inline void handle_correct_receiver(const enum ConnectionType connection_type, struct Listener* const listener, const struct pcap_pkthdr* const hdr, const uint8_t* const packet, const struct SwiftNetPortInfo* const port_info) {
static inline void handle_correct_receiver(const enum ConnectionType connection_type, struct Listener* const listener, const struct pcap_pkthdr* const hdr, const uint8_t* const packet, struct SwiftNetPortInfo* const port_info) {
if (connection_type == CONNECTION_TYPE_CLIENT) {
vector_lock(&listener->client_connections);

for (uint16_t i = 0; i < listener->client_connections.size; i++) {
struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i);
if (client_connection->port_info.source_port == port_info->destination_port) {
vector_unlock(&listener->client_connections);
LOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);

if (client_connection->initialized == false) {
handle_client_init(client_connection, hdr, packet);
} else {
swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet, &client_connection->process_packets_mtx, &client_connection->process_packets_cond);
}
struct SwiftNetClientConnection* const client_connection = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->client_connections);
UNLOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);

return;
}
if (client_connection == NULL) {
return;
}

vector_unlock(&listener->client_connections);
if (client_connection->initialized == false) {
handle_client_init(client_connection, hdr, packet);
} else {
swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet, &client_connection->process_packets_mtx, &client_connection->process_packets_cond);
}
} else {
vector_lock(&listener->servers);
LOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock);

for (uint16_t i = 0; i < listener->servers.size; i++) {
struct SwiftNetServer* const server = vector_get(&listener->servers, i);
if (server->server_port == port_info->destination_port) {
vector_unlock(&listener->servers);
struct SwiftNetServer* const server = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->servers);
UNLOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock);

swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet, &server->process_packets_mtx, &server->process_packets_cond);

return;
}
if (server == NULL) {
return;
}

vector_unlock(&listener->servers);
swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet, &server->process_packets_mtx, &server->process_packets_cond);
}
}

Expand Down
24 changes: 10 additions & 14 deletions src/initialize_client_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,39 +84,35 @@ static inline struct SwiftNetClientConnection* const construct_client_connection
new_connection->prepend_size = PACKET_PREPEND_SIZE(new_connection->addr_type);

new_connection->pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 100);
new_connection->pending_messages = vector_create(100);
new_connection->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100);
new_connection->packets_sending = vector_create(100);
new_connection->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100);
new_connection->packets_completed = vector_create(100);
new_connection->packets_completed = hashmap_create(&uint16_memory_allocator);
new_connection->packets_sending = hashmap_create(&uint16_memory_allocator);
new_connection->pending_messages = hashmap_create(&uint16_memory_allocator);

new_connection->packet_queue = (struct PacketQueue){
.first_node = NULL,
.last_node = NULL
};

atomic_store_explicit(&new_connection->packet_queue.owner, NONE, memory_order_release);
UNLOCK_ATOMIC_DATA_TYPE(&new_connection->packet_queue.locked);
UNLOCK_ATOMIC_DATA_TYPE(&new_connection->packet_callback_queue.locked);

atomic_store_explicit(&new_connection->closing, false, memory_order_release);
atomic_store_explicit(&new_connection->initialized, false, memory_order_release);
atomic_store_explicit(&new_connection->packet_handler_user_arg, NULL, memory_order_release);

memset(&new_connection->packet_callback_queue, 0x00, sizeof(struct PacketCallbackQueue));
atomic_store_explicit(&new_connection->packet_callback_queue.owner, NONE, memory_order_release);

return new_connection;
}

static inline void remove_con_from_listener(const struct SwiftNetClientConnection* const con, struct Listener* const listener) {
vector_lock(&listener->client_connections);
static inline void remove_con_from_listener(struct SwiftNetClientConnection* const con, struct Listener* const listener) {
LOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);

for (uint16_t i = 0; i < listener->client_connections.size; i++) {
struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i);
if (client_connection == con) {
vector_remove(&listener->client_connections, i);
}
}
hashmap_remove(&con->port_info.source_port, sizeof(uint16_t), &listener->client_connections);

vector_unlock(&listener->client_connections);
UNLOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock);
}

struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_address, const uint16_t port, const uint32_t timeout_ms) {
Expand Down
Loading
Loading