From 89ff5adb56dbfb1c49963ca646173e631ea7bf90 Mon Sep 17 00:00:00 2001 From: Morcules Date: Tue, 16 Jun 2026 09:34:23 +0200 Subject: [PATCH 1/2] Most files finished besides processing, sending and internal --- README.md | 30 +++- docs/usage.md | 222 +++++++++++++++++------- src/; | 192 ++++++++++++++++++++ src/CMakeLists.txt | 43 ++++- src/cleanup_connection.c | 25 ++- src/cleanup_swiftnet.c | 8 +- src/execute_packet_callback.c | 110 ++++++++---- src/generic_functions.c | 19 +- src/handle_packets.c | 139 +++++++++++---- src/initialize_client_connection.c | 98 +++++++---- src/initialize_server.c | 14 +- src/initialize_swiftnet.c | 24 ++- src/internal/internal.h | 8 +- src/make_request.c | 99 ++++++----- src/make_response.c | 6 +- src/memory_cleanup_background_service.c | 35 ++-- src/packet_buffer.c | 28 +-- src/process_packets.c | 207 +++++++++++----------- tests/performance_tests/src/main.c | 8 +- 19 files changed, 915 insertions(+), 400 deletions(-) create mode 100644 src/; diff --git a/README.md b/README.md index 604400a..07732c2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # SwiftNet - Networking Library -## SwiftNet is a lightweight networking library built on top of pcap, operating at Layer 2. It is designed for developers who value simplicity, readability, and performance. +## SwiftNet is a lightweight networking library built on top of pcap, operating at Layer 2. It is designed for developers who value simplicity, readability, and performance. It handles chunked delivery for large payloads, automatic lost-chunk recovery, callback handlers, and has an optional request/response model. Call swiftnet_initialize() before creating clients or servers. - [Features](#features) - [Installation](#installation) - [Future Version Goals](#future-version-goals) - [Example](#example) +- [Syntax](#syntax) - [Contributing](#contributing) - [Goals](#goals) - [License](#license) @@ -22,7 +23,7 @@ - **Linux arm64** (Release build works, but testing is disabled due to TSAN issues) ## Features -- **💡 Ease of Use**: Simple API designed to get up and running quickly, without needing to deal directly with scokets, ip/eth headers or complicated libraries. +- **💡 Ease of Use**: Simple API designed to get up and running quickly, without needing to deal directly with sockets, ip/eth headers or complicated libraries. - **📂 Lightweight**: No dependencies except PCAP and a small footprint. ## Why Use SwiftNet? @@ -99,7 +100,7 @@ cd SwiftNet/build ./build_for_release.sh ``` 4. To use SwiftNet in your project: -- Include the SwiftNet.h header from the `src` directory in your main source file (e.g., `main.c`). +- Include `swift_net.h` in your main source file (e.g., `main.c`). - Link against the static library `libswiftnet.a` using your compiler. ## Important note @@ -108,6 +109,8 @@ cd SwiftNet/build ## Example ``` +swiftnet_initialize(); + struct SwiftNetClientConnection* const client_conn = swiftnet_create_client("127.0.0.1", 8080, 1000); if (client_conn == NULL) { printf("Failed to create client connection\n"); @@ -116,15 +119,30 @@ if (client_conn == NULL) { swiftnet_client_set_message_handler(client_conn, on_client_packet, NULL); -struct SwiftNetPacketBuffer buf = swiftnet_client_create_packet_buffer(sizeof(int)); +struct SwiftNetPacketBuffer buf = swiftnet_create_packet_buffer(1024); int code = 0xFF; +swiftnet_append_to_buffer(&code, sizeof(code), &buf); -swiftnet_client_append_to_packet(&code, sizeof(code), &buf); swiftnet_client_send_packet(client_conn, &buf); -swiftnet_client_destroy_packet_buffer(&buf); +swiftnet_destroy_packet_buffer(&buf); + +/* later */ +swiftnet_client_cleanup(client_conn); +swiftnet_cleanup(); ``` +Handlers get called with `struct SwiftNetClientPacketData*` (or the server equivalent). Use `swiftnet_client_read_packet` to pull data out, then `swiftnet_client_destroy_packet_data`. Server side is symmetric. Requests/responses are available when `SWIFT_NET_REQUESTS` is enabled. + +## Syntax + +- Every stack var has to be declared on top for easier variable clarity. +- New scopes can declare at top of the scope. +- Use gotos and labels for labeled progression. +- Trying to avoid many scopes in one function. + +(only some files have the new style i'm working on it) + ## Contributing Contributions are very welcome no matter how small. Every single PR, issue, question, or typo fix is admired and appreciated. diff --git a/docs/usage.md b/docs/usage.md index d31cd89..1a80cc5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,63 +1,159 @@ -# OUTDATED!!!!!!!! - -# Explanation of every single function - -## SWIFT_NET_SERVER AND SWIFT_NET_CLIENT -### Usage: -- Sets the current thread to operate in either client or server mode. The library then executes different functions depending on the selected mode. - -- When the thread is set to SWIFT_NET_SERVER, the system will handle incoming connections and process server-side functionality. -- When the thread is set to SWIFT_NET_CLIENT, the system will connect to a server and execute client-side operations. -- This allows you to easily switch between server and client behavior within the same application, depending on the configuration. - -## InitializeSwiftNet -### Usage: -- Initializes the Swift Net library. -- **Note:** As of now, this function does not perform any actions, but it may be used in the future for setting up configurations or performing initialization tasks related to networking. - -# SwiftNetSetBufferSize -### Arguments: -1. unsigned int - New Buffer Size: Specifies the desired size of the packet buffer. -2. Pointer to either SwiftNetClientConnection or SwiftNetServer: A pointer to the appropriate connection object (either client or server). The function will terminate if a null pointer is provided. -### Usage: -- Changes the packet buffer size to the specified new size. - -# SwiftNetCreateClient -### Arguments: -1. char* - IP address of the server: The server's IP address to which the client will connect. -2. uint16_t - Port of the server: The port number on which the server is listening for connections. -### Usage: -- Establishes a client connection to the specified server at the given IP address and port. This function initiates the process of connecting the client to the server. -### Return: -- Pointer to SwiftNetClientConnection: Returns a pointer to the client connection struct that represents the established connection to the server. - -# SwiftNetCreateServer -### Arguments: -1. char* - IP address of the server: The server's IP address to bind the server to. -2. uint16_t - Port of the server: The port number on which the server will listen for incoming client connections. -### Usage: -- Creates and initializes a server on the specified IP address and port. This function binds the server to the provided IP address and port, enabling it to accept incoming client connections on that address. The server will start listening for connections and handle requests accordingly. -### Return: -- Pointer to SwiftNetServer: Returns a pointer to the server struct that represents the server. - -# SwiftNetSetMessageHandler -### Arguments: -1. void(uint8_t* data) - A function pointer to the handler function that will be called when a new packet is received. The handler function should accept a single argument: a uint8_t* (pointer to data), which represents the data sent with the packet. -2. Pointer to either SwiftNetClientConnection or SwiftNetServer: A pointer to the appropriate connection object (either client or server). -### Usage: -- Registers a callback function (handler) to handle incoming packet data. When a new packet is received, the specified handler function is called with the packet data as its argument. - -# SwiftNetAppendToPacket -### Arguments: -1. Pointer to either SwiftNetClientConnection or SwiftNetServer: A pointer to the appropriate connection object (either client or server). -2. void* - Pointer to the data: The data that will be appended to the packet buffer. -3. unsigned int - Size in bytes of the data: The size of the data to be appended, in bytes. -### Usage: -- Appends the provided data to the current packet buffer for the specified connection and then increments the internal pointer to the next available space in the buffer. - -# SwiftNetSendPacket -### Arguments: -1. Pointer to either SwiftNetClientConnection or SwiftNetServer: A pointer to the appropriate connection object (either client or server). -2. ClientAddress* (only necessary in SERVER mode, otherwise set it to NULL): The address of the client to which the packet should be sent. This argument is only required when the mode is set to SERVER, as the server may need to send a packet to a specific client. If using CLIENT mode, this should be set to NULL. -### Usage: -- Sends the constructed packet to the specified destination. In SERVER mode, the packet is sent to the provided client's address, while in CLIENT mode, the packet is sent to the connected server. +# SwiftNet Usage + +**You must run with sudo** (pcap raw access). + +Call `swiftnet_initialize()` once at startup and `swiftnet_cleanup()` at shutdown. + +## Initialize / Cleanup + +```c +swiftnet_initialize(); + +// ... create connections, send, etc ... + +swiftnet_cleanup(); +``` + +## Create Server + +```c +struct SwiftNetServer* server = swiftnet_create_server(8080, false /* loopback */); +if (server == NULL) { + // failed to open interface etc. +} +``` + +- `loopback = true` uses the loopback interface (good for local tests). +- Server will start its own listener + processing threads. + +## Create Client + +```c +struct SwiftNetClientConnection* client = swiftnet_create_client("127.0.0.1", 8080, 1000 /* timeout ms */); +if (client == NULL) { + // failed to reach server or complete initial handshake +} +``` + +Client performs a short handshake to learn the server's MTU. + +## Message Handlers + +```c +void on_client_packet(struct SwiftNetClientPacketData* packet, void* user) { + // packet->metadata has data_length, packet_id, port_info, expecting_response (if requests enabled) + uint8_t byte = *(uint8_t*)swiftnet_client_read_packet(packet, 1); + + swiftnet_client_destroy_packet_data(packet, client); +} + +swiftnet_client_set_message_handler(client, on_client_packet, NULL /* user arg */); +``` + +Server side is identical but uses `struct SwiftNetServerPacketData*` and `swiftnet_server_set_message_handler`. + +The handler is invoked (on a background thread) after the library has fully reassembled any chunked packet. + +When sending from a server handler back to that client, use the address that came in: + +```c +swiftnet_server_send_packet(server, &buf, packet->metadata.sender); +``` + +`metadata.sender` contains the address, port, mac, and MTU for that client. + +## Packet Buffers + +```c +struct SwiftNetPacketBuffer buf = swiftnet_create_packet_buffer(1024); + +int32_t value = 42; +swiftnet_append_to_buffer(&value, sizeof(value), &buf); + +// or write at an offset +swiftnet_write_packet_buffer(0, &buf, &value, sizeof(value)); + +swiftnet_client_send_packet(client, &buf); +swiftnet_destroy_packet_buffer(&buf); +``` + +Other helpers: +- `swiftnet_resize_packet_buffer(new_size, &buf)` +- `swiftnet_create_packet_buffer`, `swiftnet_destroy_packet_buffer` + +## Sending + +Client (to its server): + +```c +swiftnet_client_send_packet(client, &buf); +``` + +Server (to a specific client): + +```c +swiftnet_server_send_packet(server, &buf, target_addr_data); +``` + +The library handles splitting > MTU payloads into chunks and retransmitting lost ones automatically. + +## Reading Received Packets + +Inside your handler: + +```c +void* data = swiftnet_client_read_packet(packet, packet->metadata.data_length); +// or read piecemeal: +uint8_t first = *(uint8_t*)swiftnet_client_read_packet(packet, 1); +``` + +Always call the destroy function when you are done with the packet data: + +- `swiftnet_client_destroy_packet_data(packet, client_conn)` +- `swiftnet_server_destroy_packet_data(packet, server)` + +## Requests / Responses (enabled unless SWIFT_NET_DISABLE_REQUESTS) + +Synchronous request from client: + +```c +struct SwiftNetPacketBuffer req_buf = swiftnet_create_packet_buffer(size); +swiftnet_append_to_buffer(data, size, &req_buf); + +struct SwiftNetClientPacketData* reply = swiftnet_client_make_request(client, &req_buf, 1000 /* ms */); +if (reply) { + // read from reply the same way + swiftnet_client_destroy_packet_data(reply, client); +} +swiftnet_destroy_packet_buffer(&req_buf); +``` + +Server can also send requests to clients using `swiftnet_server_make_request(server, &buf, client_addr, timeout)`. + +In a handler, if `packet->metadata.expecting_response` is true you can reply without the caller blocking on a new make_request: + +```c +swiftnet_client_make_response(client, packet, &response_buf); +``` + +Same pattern exists for server. + +## Debug Output (enabled unless SWIFT_NET_DISABLE_DEBUGGING) + +```c +swiftnet_add_debug_flags(SWIFTNET_DEBUG_FLAGS( + SWIFTNET_DEBUG_PACKETS_SENDING | + SWIFTNET_DEBUG_PACKETS_RECEIVING | + SWIFTNET_DEBUG_INITIALIZATION | + SWIFTNET_DEBUG_LOST_PACKETS +)); +``` + +Remove flags with `swiftnet_remove_debug_flags(...)`. + +## Important Notes + +- Always run the binary as root / with sudo. +- The library owns several background threads per connection (listener, packet processor, callback executor). +- Cleanup functions stop threads and free the allocators / hashmaps used by that connection. +- All the heavy lifting (reassembly, lost packet recovery, checksums) happens inside the library. diff --git a/src/; b/src/; new file mode 100644 index 0000000..d28a196 --- /dev/null +++ b/src/; @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/internal.h" +#include "swift_net.h" +#include +#include +#include +#include + +struct RequestServerInformationArgs { + const uint32_t size; + const struct in_addr server_addr; + pcap_t* const pcap; + const uint32_t timeout_ms; + const void* const data; + struct SwiftNetClientConnection* const connection; +}; + +void* request_server_information(void* restrict const request_server_information_args_void) { + struct timeval tv; + gettimeofday(&tv, NULL); + + uint32_t start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + const struct RequestServerInformationArgs* const request_server_information_args = (struct RequestServerInformationArgs*)request_server_information_args_void; + + while (1) { + struct timeval tv; + gettimeofday(&tv, NULL); + + uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if (end > start + request_server_information_args->timeout_ms) { + break; + } + + if(atomic_load_explicit(&request_server_information_args->connection->initialized, memory_order_acquire) == true) { + return NULL; + } + + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { + send_debug_message("Requested server information: {\"server_ip_address\": \"%s\"}\n", inet_ntoa(request_server_information_args->server_addr)); + } + #endif + + SWIFTNET_PCAP_SEND_SAFE(request_server_information_args->pcap, request_server_information_args->data, request_server_information_args->size); + + usleep(250000); + } + + return NULL; +} + +static inline struct SwiftNetClientConnection* const construct_client_connection(const bool loopback, const uint16_t destination_port, const in_addr_t server_address, pcap_t* const pcap) { + struct SwiftNetClientConnection* const new_connection = allocator_allocate(&client_connection_memory_allocator); + + struct ether_header eth_header = { + .ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, + .ether_type = htons(0x0800) + }; + + memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); + + new_connection->eth_header = eth_header; + new_connection->pcap = pcap; + new_connection->port_info = (struct SwiftNetPortInfo){.source_port = rand(), .destination_port = destination_port}; + new_connection->server_addr.s_addr = server_address; + new_connection->packet_handler = NULL; + new_connection->loopback = loopback; + new_connection->addr_type = pcap_datalink(pcap); + 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->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100); + new_connection->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); + new_connection->packets_completed = hashmap_create(&packet_completed_key_allocator); + new_connection->packets_sending = hashmap_create(&uint16_memory_allocator); + new_connection->pending_messages = hashmap_create(&pending_message_key_allocator); + + new_connection->packet_queue = (struct PacketQueue){ + .first_node = NULL, + .last_node = NULL + }; + + UNLOCK_ATOMIC_DATA_TYPE(&new_connection->packet_queue.locked); + UNLOCK_ATOMIC_DATA_TYPE(&new_connection->packet_callback_queue.locked); + + atomic_store_explicit(&new_connection->processing_packets, true, memory_order_release); + 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)); + + return new_connection; +} + +static inline void remove_con_from_listener(struct SwiftNetClientConnection* const con, struct Listener* const listener) { + LOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock); + + hashmap_remove(&con->port_info.source_port, sizeof(uint16_t), &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) { + struct in_addr addr; + inet_aton(ip_address, &addr); + const uint32_t ip = ntohl(addr.s_addr); + const bool loopback = (ip >> 24) == 127; + + pcap_t* const pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + if (unlikely(pcap == NULL)) { + return NULL; + } + + struct SwiftNetClientConnection* const new_connection = construct_client_connection(loopback, port, addr.s_addr, pcap); + + // Request the server information, and proccess it + const struct SwiftNetPacketInfo request_server_information_packet_info = construct_packet_info( + 0x00, + REQUEST_INFORMATION, + 1, + 0, + new_connection->port_info + ); + + const struct ip request_server_info_ip_header = construct_ip_header(new_connection->server_addr, PACKET_HEADER_SIZE, rand()); + + HANDLE_PACKET_CONSTRUCTION(&request_server_info_ip_header, &request_server_information_packet_info, new_connection->addr_type, &new_connection->eth_header, PACKET_HEADER_SIZE + new_connection->prepend_size, request_server_info_buffer) + + HANDLE_CHECKSUM(request_server_info_buffer, sizeof(request_server_info_buffer), new_connection->prepend_size); + + pthread_t send_request_thread; + + const struct RequestServerInformationArgs thread_args = { + .pcap = pcap, + .data = request_server_info_buffer, + .size = sizeof(request_server_info_buffer), + .server_addr = addr, + .timeout_ms = timeout_ms, + .connection = new_connection + }; + + struct Listener* const listener = check_existing_listener(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface, new_connection, CONNECTION_TYPE_CLIENT, loopback); + + pthread_create(&send_request_thread, NULL, request_server_information, (void*)&thread_args); + + pthread_join(send_request_thread, NULL); + + if (atomic_load_explicit(&new_connection->initialized, memory_order_acquire) == false) { + atomic_store_explicit(&new_connection->closing, true, memory_order_release); + + pcap_close(new_connection->pcap); + + allocator_free(&client_connection_memory_allocator, new_connection); + + remove_con_from_listener(new_connection, listener); + + return NULL; + } + + pthread_create(&new_connection->process_packets_thread, NULL, swiftnet_client_process_packets, new_connection); + pthread_create(&new_connection->execute_callback_thread, NULL, execute_packet_callback_client, new_connection); + + pthread_mutex_init(&new_connection->process_packets_mtx, NULL); + pthread_mutex_init(&new_connection->execute_callback_mtx, NULL); + + pthread_cond_init(&new_connection->process_packets_cond, NULL); + pthread_cond_init(&new_connection->execute_callback_cond, NULL); + + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { + send_debug_message("Successfully initialized client\n"); + } + #endif + + return new_connection; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31dc96c..75993fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,6 +4,7 @@ project(swiftnet C CXX) include(GNUInstallDirs) set(CMAKE_C_STANDARD 99) +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) set(SOURCE_FILES initialize_swiftnet.c @@ -67,10 +68,48 @@ if (SWIFT_NET_INTERNAL_TESTING) else() message("Internal Testing Disabled") - target_compile_options(swiftnet PRIVATE -O3) + target_compile_options(swiftnet PRIVATE + -O3 + -march=native + -mtune=native + -flto=auto + -funroll-loops + -fomit-frame-pointer + + -ffast-math + -fno-math-errno + -funsafe-math-optimizations + -ffinite-math-only + + -fvectorize + -falign-functions=64 + -falign-loops=64 + + -flto + ) + target_link_options(swiftnet PRIVATE -O3) - target_compile_options(swiftnet_shared PRIVATE -O3) + target_compile_options(swiftnet_shared PRIVATE + -O3 + -march=native + -mtune=native + -flto=auto + -funroll-loops + -fomit-frame-pointer + + -ffast-math + -fno-math-errno + -funsafe-math-optimizations + -ffinite-math-only + + -fvectorize + -falign-functions=64 + -falign-loops=64 + + -flto + ) + target_link_options(swiftnet_shared PRIVATE -O3) endif() diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index 50da9b5..7ccf07e 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -8,7 +8,7 @@ static inline void cleanup_connection_resources(const enum ConnectionType connection_type, void* const connection) { if (connection_type == CONNECTION_TYPE_CLIENT) { - struct SwiftNetClientConnection* const client = (struct SwiftNetClientConnection*)connection; + struct SwiftNetClientConnection* const client = connection; allocator_destroy(&client->packets_sending_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&client->pending_messages_memory_allocator ENABLE_INTERNAL_CHECK); @@ -18,7 +18,7 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec hashmap_destroy(&client->packets_sending); hashmap_destroy(&client->packets_completed); } else { - struct SwiftNetServer* const server = (struct SwiftNetServer*)connection; + struct SwiftNetServer* const server = connection; allocator_destroy(&server->packets_sending_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&server->pending_messages_memory_allocator ENABLE_INTERNAL_CHECK); @@ -30,13 +30,16 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec } } -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); +static inline void remove_listener(const enum ConnectionType connection_type, const char* const restrict interface_name, void* const connection) { + uint32_t interface_len; + struct Listener* restrict listener; - const uint32_t interface_len = strlen(interface_name); + interface_len = strlen(interface_name); - struct Listener* const listener = hashmap_get(interface_name, interface_len, &listeners); - if (listener == NULL) { + LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); + + listener = hashmap_get(interface_name, interface_len, &listeners); + if (unlikely(listener == NULL)) { UNLOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); return; @@ -110,9 +113,11 @@ static inline void close_threads(const enum ConnectionType connection_type, void } void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) { + const char* restrict interface_name; + cleanup_connection_resources(CONNECTION_TYPE_CLIENT, client); - const char* const interface_name = get_interface_name(client->loopback); + interface_name = get_interface_name(client->loopback); remove_listener(CONNECTION_TYPE_CLIENT, interface_name, client); @@ -124,9 +129,11 @@ void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) { } void swiftnet_server_cleanup(struct SwiftNetServer* const server) { + const char* restrict interface_name; + cleanup_connection_resources(CONNECTION_TYPE_SERVER, server); - const char* interface_name = get_interface_name(server->loopback); + interface_name = get_interface_name(server->loopback); remove_listener(CONNECTION_TYPE_SERVER, interface_name, server); diff --git a/src/cleanup_swiftnet.c b/src/cleanup_swiftnet.c index bc7a0f4..36fdc92 100644 --- a/src/cleanup_swiftnet.c +++ b/src/cleanup_swiftnet.c @@ -6,11 +6,9 @@ static inline void close_listeners() { LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); - - struct SwiftNetHashMap* const listeners_map = &listeners; - - LOOP_HASHMAP(listeners_map, - struct Listener* const current_listener = hashmap_data; + + LOOP_HASHMAP(&listeners, + struct Listener* restrict const current_listener = hashmap_data; pcap_breakloop(current_listener->pcap); diff --git a/src/execute_packet_callback.c b/src/execute_packet_callback.c index e5086e1..eef2bc3 100644 --- a/src/execute_packet_callback.c +++ b/src/execute_packet_callback.c @@ -1,23 +1,26 @@ #include "internal/internal.h" #include "swift_net.h" +#include #include #include #include #include #include -#include -static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) { +static struct PacketCallbackQueueNode *const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) { + struct PacketCallbackQueueNode* restrict node_to_process; + + LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked); - if(packet_queue->first_node == NULL) { + if (packet_queue->first_node == NULL) { UNLOCK_ATOMIC_DATA_TYPE(&packet_queue->locked); return NULL; } - struct PacketCallbackQueueNode* const node_to_process = packet_queue->first_node; + node_to_process = packet_queue->first_node; - if(node_to_process->next == NULL) { + if (node_to_process->next == NULL) { packet_queue->first_node = NULL; packet_queue->last_node = NULL; @@ -33,13 +36,11 @@ static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struc return node_to_process; } -static inline void remove_pending_message_from_hashmap(struct SwiftNetHashMap* const pending_messages, struct SwiftNetPendingMessage* const pending_message) { +static inline void remove_pending_message_from_hashmap(struct SwiftNetHashMap* const pending_messages, struct SwiftNetPendingMessage* restrict const pending_message) { + struct PendingMessagesKey key = {.source_port = pending_message->source_port, .packet_id = pending_message->packet_id}; + + LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); - - struct PendingMessagesKey key = { - .source_port = pending_message->source_port, - .packet_id = pending_message->packet_id - }; hashmap_remove(&key, sizeof(key), pending_messages); @@ -48,17 +49,24 @@ static inline void remove_pending_message_from_hashmap(struct SwiftNetHashMap* c void execute_packet_callback( struct PacketCallbackQueue* const queue, - void (* const _Atomic * const packet_handler) (void* const, - void* const), - const enum ConnectionType connection_type, - struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, - _Atomic bool* closing, - void* const connection, - struct SwiftNetHashMap* const pending_messages, - _Atomic(void*)* user_data, - pthread_mutex_t* const execute_callback_mtx, - pthread_cond_t* const execute_callback_cond + void (*const _Atomic * const packet_handler)(void *const, void *const), + const enum ConnectionType connection_type, + struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, + const _Atomic bool * const closing, + void * const connection, + struct SwiftNetHashMap * const pending_messages, + _Atomic(void *) *user_data, + pthread_mutex_t* restrict const execute_callback_mtx, + pthread_cond_t* restrict const execute_callback_cond ) { + void (*packet_handler_loaded)(void *const, void *const); + + struct PacketCallbackQueueNode* restrict current_node; + + + goto check_packet; + + check_packet: if (unlikely(atomic_load_explicit(closing, memory_order_acquire) == true)) { return; @@ -66,8 +74,8 @@ void execute_packet_callback( pthread_mutex_lock(execute_callback_mtx); - const struct PacketCallbackQueueNode* const node = wait_for_next_packet_callback(queue); - if(node == NULL) { + current_node = wait_for_next_packet_callback(queue); + if (current_node == NULL) { pthread_cond_wait(execute_callback_cond, execute_callback_mtx); pthread_mutex_unlock(execute_callback_mtx); @@ -77,31 +85,37 @@ void execute_packet_callback( pthread_mutex_unlock(execute_callback_mtx); - if(node->packet_data == NULL) { - allocator_free(&packet_callback_queue_node_memory_allocator, (void*)node); - goto check_packet; + packet_handler_loaded = atomic_load_explicit(packet_handler, memory_order_acquire); + + if (current_node->packet_data == NULL) { + goto next; } - if(node->pending_message != NULL) { - remove_pending_message_from_hashmap(pending_messages, node->pending_message); + if (current_node->pending_message != NULL) { + remove_pending_message_from_hashmap(pending_messages, current_node->pending_message); } - void (*const packet_handler_loaded)(void* const, void* const) = atomic_load(packet_handler); + goto execute_callback; + + +execute_callback: if (unlikely(packet_handler_loaded == NULL)) { if (connection_type == CONNECTION_TYPE_CLIENT) { - swiftnet_client_destroy_packet_data(node->packet_data, connection); + swiftnet_client_destroy_packet_data(current_node->packet_data, connection); } else { - swiftnet_client_destroy_packet_data(node->packet_data, connection); + swiftnet_server_destroy_packet_data(current_node->packet_data, connection); } - allocator_free(&packet_callback_queue_node_memory_allocator, (void*)node); - - goto check_packet; + goto next; } - (*packet_handler_loaded)(node->packet_data, atomic_load_explicit(user_data, memory_order_acquire)); + (*packet_handler_loaded)(current_node->packet_data, atomic_load_explicit(user_data, memory_order_acquire)); + + goto next; + - allocator_free(&packet_callback_queue_node_memory_allocator, (void*)node); +next: + allocator_free(&packet_callback_queue_node_memory_allocator, current_node); goto check_packet; } @@ -109,7 +123,17 @@ void execute_packet_callback( void* execute_packet_callback_client(void* const void_client) { struct SwiftNetClientConnection* const client = void_client; - execute_packet_callback(&client->packet_callback_queue, (void*)&client->packet_handler, CONNECTION_TYPE_CLIENT, &client->pending_messages_memory_allocator, &client->closing, void_client, &client->pending_messages, &client->packet_handler_user_arg, &client->execute_callback_mtx, &client->execute_callback_cond); + execute_packet_callback( + &client->packet_callback_queue, + (void *)&client->packet_handler, + CONNECTION_TYPE_CLIENT, + &client->pending_messages_memory_allocator, + &client->closing, void_client, + &client->pending_messages, + &client->packet_handler_user_arg, + &client->execute_callback_mtx, + &client->execute_callback_cond + ); return NULL; } @@ -117,7 +141,17 @@ void* execute_packet_callback_client(void* const void_client) { void* execute_packet_callback_server(void* const void_server) { struct SwiftNetServer* const server = void_server; - execute_packet_callback(&server->packet_callback_queue, (void*)&server->packet_handler, CONNECTION_TYPE_SERVER, &server->pending_messages_memory_allocator, &server->closing, void_server, &server->pending_messages, &server->packet_handler_user_arg, &server->execute_callback_mtx, &server->execute_callback_cond); + execute_packet_callback( + &server->packet_callback_queue, + (void *)&server->packet_handler, + CONNECTION_TYPE_SERVER, + &server->pending_messages_memory_allocator, + &server->closing, + void_server, &server->pending_messages, + &server->packet_handler_user_arg, + &server->execute_callback_mtx, + &server->execute_callback_cond + ); return NULL; } diff --git a/src/generic_functions.c b/src/generic_functions.c index 3a056ed..e6fdb20 100644 --- a/src/generic_functions.c +++ b/src/generic_functions.c @@ -6,7 +6,6 @@ #include // These functions append data to a packet buffer and advance the current pointer by the data size. - static inline void validate_append_to_packet_args(const void* const data, const uint32_t data_size) { if(unlikely(data == NULL || data_size == 0)) { PRINT_ERROR("Error: Invalid arguments given"); @@ -14,13 +13,13 @@ static inline void validate_append_to_packet_args(const void* const data, const } } -static inline void append_data(uint8_t** const append_pointer, const void* const data, const uint32_t data_size) { +static inline void append_data(uint8_t* restrict * restrict const append_pointer, const void* restrict const data, const uint32_t data_size) { memcpy(*append_pointer, data, data_size); (*append_pointer) += data_size; } -void swiftnet_append_to_buffer(const void* const data, const uint32_t data_size, struct SwiftNetPacketBuffer* const buffer) { +void swiftnet_append_to_buffer(const void* restrict const data, const uint32_t data_size, struct SwiftNetPacketBuffer* restrict const buffer) { #ifdef SWIFT_NET_ERROR validate_append_to_packet_args(data, data_size); #endif @@ -29,7 +28,6 @@ void swiftnet_append_to_buffer(const void* const data, const uint32_t data_size, } // Set the handler for incoming packets/messages on the server or client -// static inline void swiftnet_validate_new_handler(const void* const new_handler) { #ifdef SWIFT_NET_ERROR if(unlikely(new_handler == NULL)) { @@ -54,36 +52,35 @@ void swiftnet_server_set_message_handler(struct SwiftNetServer* const server, vo } // Read packet data into buffers - -void* swiftnet_client_read_packet(struct SwiftNetClientPacketData* const packet_data, const uint32_t data_size) { +void* swiftnet_client_read_packet(struct SwiftNetClientPacketData* restrict const packet_data, const uint32_t data_size) { const uint32_t data_already_read = (packet_data->current_pointer - packet_data->data) + data_size; if (data_already_read > packet_data->metadata.data_length) { PRINT_ERROR("Error: Tried to read more data than there actually is"); return NULL; } - void* const ptr = packet_data->current_pointer; + void* restrict const ptr = packet_data->current_pointer; packet_data->current_pointer += data_size; return ptr; } -void* swiftnet_server_read_packet(struct SwiftNetServerPacketData* const packet_data, const uint32_t data_size) { +void* swiftnet_server_read_packet(struct SwiftNetServerPacketData* restrict const packet_data, const uint32_t data_size) { const uint32_t data_already_read = (packet_data->current_pointer - packet_data->data) + data_size; if (data_already_read > packet_data->metadata.data_length) { PRINT_ERROR("Error: Tried to read more data than there actually is"); return NULL; } - void* const ptr = packet_data->current_pointer; + void* restrict const ptr = packet_data->current_pointer; packet_data->current_pointer += data_size; return ptr; } -void swiftnet_client_destroy_packet_data(struct SwiftNetClientPacketData* const packet_data, struct SwiftNetClientConnection* const client_conn) { +void swiftnet_client_destroy_packet_data(struct SwiftNetClientPacketData* restrict const packet_data, struct SwiftNetClientConnection* const client_conn) { if(packet_data->internal_pending_message != NULL) { free(packet_data->internal_pending_message->chunks_received); @@ -96,7 +93,7 @@ void swiftnet_client_destroy_packet_data(struct SwiftNetClientPacketData* const } } -void swiftnet_server_destroy_packet_data(struct SwiftNetServerPacketData* const packet_data, struct SwiftNetServer* const server) { +void swiftnet_server_destroy_packet_data(struct SwiftNetServerPacketData* restrict const packet_data, struct SwiftNetServer* const server) { if(packet_data->internal_pending_message != NULL) { free(packet_data->internal_pending_message->chunks_received); diff --git a/src/handle_packets.c b/src/handle_packets.c index c9f5870..c5c21eb 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -11,12 +11,11 @@ #include static inline void insert_queue_node( - struct PacketQueueNode* const new_node, + struct PacketQueueNode* restrict const new_node, struct PacketQueue* const packet_queue, const enum ConnectionType contype - ) { - if(new_node == NULL) { + if(unlikely(new_node == NULL)) { return; } @@ -40,57 +39,74 @@ static inline void insert_queue_node( } static inline struct PacketQueueNode* construct_node(const uint32_t data_read, void* const data, const uint32_t sender_address) { - struct PacketQueueNode* const node = allocator_allocate(&packet_queue_node_memory_allocator); + struct PacketQueueNode* restrict node; + + + node = allocator_allocate(&packet_queue_node_memory_allocator); if (unlikely(node == NULL)) { return NULL; } + goto node_assign_values; + + +node_assign_values: node->data = data; node->data_read = data_read; node->sender_address.s_addr = sender_address; node->next = NULL; + goto exit; + + +exit: return node; } static inline void swiftnet_handle_packets( const uint16_t source_port, pthread_t* const process_packets_thread, - void* connection, + void* const connection, const enum ConnectionType connection_type, struct PacketQueue* const packet_queue, const _Atomic bool* closing, const bool loopback, const uint16_t addr_type, const struct pcap_pkthdr* hdr, - const uint8_t* packet, + const uint8_t* const packet, pthread_mutex_t* const process_packets_mtx, pthread_cond_t* const process_packets_cond, _Atomic bool *const processing_packets ) { - uint8_t* const packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); + uint32_t sender_address; + uint8_t* restrict packet_buffer; + uint32_t packet_len; + + + packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); if (unlikely(packet_buffer == NULL)) { - return; + goto exit; } - const uint32_t len = hdr->caplen; - memcpy(packet_buffer, packet, len); + packet_len = hdr->caplen; + + memcpy(packet_buffer, packet, packet_len); - if (unlikely(len == 0)) { + if (unlikely(packet_len == 0)) { allocator_free(&packet_buffer_memory_allocator, packet_buffer); return; } - uint32_t sender_address = 0; + goto get_sender_addr; - if (addr_type == DLT_EN10MB) { - struct ether_header* const eth = (struct ether_header *)packet_buffer; - if (ntohs(eth->ether_type) == ETHERTYPE_IP) { - struct ip *ip_header = (struct ip *)(packet_buffer + sizeof(struct ether_header)); +get_sender_addr: + sender_address = 0; - sender_address = ip_header->ip_src.s_addr; + if (addr_type == DLT_EN10MB) { + if (ntohs(((struct ether_header *)packet_buffer)->ether_type) == ETHERTYPE_IP) { + sender_address = ((struct ip *)(packet_buffer + sizeof(struct ether_header)))->ip_src.s_addr; } else { allocator_free(&packet_buffer_memory_allocator, packet_buffer); @@ -98,10 +114,16 @@ static inline void swiftnet_handle_packets( } } - struct PacketQueueNode* const node = construct_node(len, packet_buffer, sender_address); + goto insert_node; + + +insert_node: + insert_queue_node(construct_node(packet_len, packet_buffer, sender_address), packet_queue, connection_type); - insert_queue_node(node, packet_queue, connection_type); + goto unlock_processing_thread; + +unlock_processing_thread: if (atomic_load_explicit(processing_packets, memory_order_acquire) != true) { pthread_mutex_lock(process_packets_mtx); @@ -109,16 +131,38 @@ static inline void swiftnet_handle_packets( pthread_mutex_unlock(process_packets_mtx); } + + goto exit; + + +exit: + return; } -static void handle_client_init(struct SwiftNetClientConnection* user, const struct pcap_pkthdr* hdr, const uint8_t* buffer) { - struct SwiftNetClientConnection* const client_connection = (struct SwiftNetClientConnection*)user; +static void handle_client_init(struct SwiftNetClientConnection* const user, const struct pcap_pkthdr* restrict const hdr, const uint8_t* restrict const buffer) { + struct SwiftNetClientConnection* client_connection; + + struct SwiftNetPacketInfo* restrict packet_info; + struct SwiftNetServerInformation* restrict server_information; + + uint32_t bytes_received; + + + goto check_closing; + + +check_closing: + client_connection = user; if (atomic_load_explicit(&client_connection->closing, memory_order_acquire) == true) { return; } - const uint32_t bytes_received = hdr->caplen; + goto validate_packet_size; + + +validate_packet_size: + bytes_received = hdr->caplen; if(bytes_received != PACKET_HEADER_SIZE + sizeof(struct SwiftNetServerInformation) + client_connection->prepend_size) { #ifdef SWIFT_NET_DEBUG @@ -130,23 +174,29 @@ static void handle_client_init(struct SwiftNetClientConnection* user, const stru return; } - struct ip* const ip_header = (struct ip*)(buffer + client_connection->prepend_size); + goto handle_mac_address; + +handle_mac_address: if (client_connection->addr_type == DLT_EN10MB) { memcpy(client_connection->eth_header.ether_dhost, ((struct ether_header*)buffer)->ether_shost, sizeof(client_connection->eth_header.ether_dhost)); } - struct SwiftNetPacketInfo* const packet_info = (struct SwiftNetPacketInfo*)(buffer + client_connection->prepend_size + sizeof(struct ip)); - struct SwiftNetServerInformation* const server_information = (struct SwiftNetServerInformation*)(buffer + client_connection->prepend_size + sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo)); + goto validate_target; + + +validate_target: + packet_info = (struct SwiftNetPacketInfo*)(buffer + client_connection->prepend_size + sizeof(struct ip)); + server_information = (struct SwiftNetServerInformation*)(buffer + client_connection->prepend_size + sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo)); if(packet_info->port_info.destination_port != client_connection->port_info.source_port || packet_info->port_info.source_port != client_connection->port_info.destination_port) { #ifdef SWIFT_NET_DEBUG if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { - send_debug_message("Port info does not match: {\"destination_port\": %d, \"source_port\": %d, \"source_ip_address\": \"%s\"}\n", packet_info->port_info.destination_port, packet_info->port_info.source_port, inet_ntoa(ip_header->ip_src)); + send_debug_message("Port info does not match: {\"destination_port\": %d, \"source_port\": %d, \"source_ip_address\": \"%s\"}\n", packet_info->port_info.destination_port, packet_info->port_info.source_port, inet_ntoa(((struct ip*)(buffer + client_connection->prepend_size))->ip_src)); } #endif - return; + goto exit; } if(packet_info->packet_type != REQUEST_INFORMATION) { @@ -155,19 +205,33 @@ static void handle_client_init(struct SwiftNetClientConnection* user, const stru send_debug_message("Invalid packet type: {\"packet_type\": %d}\n", packet_info->packet_type); } #endif - return; + + goto exit; } + + goto finalize_initialization; + + +finalize_initialization: client_connection->maximum_transmission_unit = server_information->maximum_transmission_unit; atomic_store_explicit(&client_connection->initialized, true, memory_order_release); + + goto exit; + + +exit: + return; } -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) { +static inline void handle_correct_receiver(const enum ConnectionType connection_type, struct Listener* const listener, const struct pcap_pkthdr* restrict const hdr, const uint8_t* restrict const packet, const struct SwiftNetPortInfo* restrict const port_info) { if (connection_type == CONNECTION_TYPE_CLIENT) { + struct SwiftNetClientConnection* client_connection; + LOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock); - struct SwiftNetClientConnection* const client_connection = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->client_connections); + client_connection = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->client_connections); UNLOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock); if (client_connection == NULL) { @@ -180,9 +244,12 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ 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, &client_connection->processing_packets); } } else { + struct SwiftNetServer* server; + LOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock); - struct SwiftNetServer* const server = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->servers); + server = hashmap_get(&port_info->destination_port, sizeof(uint16_t), &listener->servers); + UNLOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock); if (server == NULL) { @@ -193,19 +260,17 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ } } -static void pcap_packet_handle(uint8_t* const user, const struct pcap_pkthdr* const hdr, const uint8_t* const packet) { +static void pcap_packet_handle(uint8_t* const user, const struct pcap_pkthdr* restrict const hdr, const uint8_t* restrict const packet) { struct Listener* const listener = (struct Listener*)user; + struct SwiftNetPortInfo* restrict const port_info = (struct SwiftNetPortInfo*)(packet + PACKET_PREPEND_SIZE(listener->addr_type) + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, port_info)); - struct SwiftNetPortInfo* const port_info = (struct SwiftNetPortInfo*)(packet + PACKET_PREPEND_SIZE(listener->addr_type) + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, port_info)); handle_correct_receiver(CONNECTION_TYPE_CLIENT, listener, hdr, packet, port_info); handle_correct_receiver(CONNECTION_TYPE_SERVER, listener, hdr, packet, port_info); } -void* interface_start_listening(void* listener_void) { - struct Listener* listener = listener_void; - - pcap_loop(listener->pcap, 0, pcap_packet_handle, listener_void); +void* interface_start_listening(void* const listener) { + pcap_loop(((struct Listener*)listener)->pcap, 0, pcap_packet_handle, listener); return NULL; } diff --git a/src/initialize_client_connection.c b/src/initialize_client_connection.c index 382a6a7..bfff0e9 100644 --- a/src/initialize_client_connection.c +++ b/src/initialize_client_connection.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -20,47 +21,55 @@ #include struct RequestServerInformationArgs { - const uint32_t size; - const struct in_addr server_addr; + uint32_t size; + struct in_addr server_addr; pcap_t* pcap; - const uint32_t timeout_ms; - const void* const data; - struct SwiftNetClientConnection* const connection; + uint32_t timeout_ms; + void* data; + struct SwiftNetClientConnection* connection; }; -void* request_server_information(void* const request_server_information_args_void) { +void* request_server_information(void* restrict const request_server_information_args_void) { + const struct RequestServerInformationArgs* const request_server_information_args = request_server_information_args_void; + struct timeval tv; + uint32_t start; + uint32_t end; + gettimeofday(&tv, NULL); - uint32_t start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; - const struct RequestServerInformationArgs* const request_server_information_args = (struct RequestServerInformationArgs*)request_server_information_args_void; + goto init_connection_request; - while (1) { - struct timeval tv; - gettimeofday(&tv, NULL); - uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; +init_connection_request: + gettimeofday(&tv, NULL); - if (end > start + request_server_information_args->timeout_ms) { - break; - } + end = (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); - if(atomic_load_explicit(&request_server_information_args->connection->initialized, memory_order_acquire) == true) { - return NULL; + if (end > start + request_server_information_args->timeout_ms) { + goto exit; + } + + if(atomic_load_explicit(&request_server_information_args->connection->initialized, memory_order_acquire) == true) { + goto exit; + } + + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { + send_debug_message("Requested server information: {\"server_ip_address\": \"%s\"}\n", inet_ntoa(request_server_information_args->server_addr)); } + #endif - #ifdef SWIFT_NET_DEBUG - if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { - send_debug_message("Requested server information: {\"server_ip_address\": \"%s\"}\n", inet_ntoa(request_server_information_args->server_addr)); - } - #endif + SWIFTNET_PCAP_SEND_SAFE(request_server_information_args->pcap, request_server_information_args->data, request_server_information_args->size); - SWIFTNET_PCAP_SEND_SAFE(request_server_information_args->pcap, request_server_information_args->data, request_server_information_args->size); + usleep(250000); + + goto init_connection_request; - usleep(250000); - } +exit: return NULL; } @@ -72,6 +81,7 @@ static inline struct SwiftNetClientConnection* const construct_client_connection .ether_type = htons(0x0800) }; + memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); new_connection->eth_header = eth_header; @@ -118,19 +128,39 @@ static inline void remove_con_from_listener(struct SwiftNetClientConnection* con struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_address, const uint16_t port, const uint32_t timeout_ms) { struct in_addr addr; + uint32_t ip; + bool loopback; + pcap_t* pcap; + struct SwiftNetClientConnection* restrict new_connection; + struct SwiftNetPacketInfo request_server_information_packet_info; + struct ip request_server_info_ip_header; + pthread_t send_request_thread; + struct RequestServerInformationArgs thread_args; + struct Listener* listener; + + goto init_connection; + + +init_connection: inet_aton(ip_address, &addr); - const uint32_t ip = ntohl(addr.s_addr); - const bool loopback = (ip >> 24) == 127; - pcap_t* const pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + ip = ntohl(addr.s_addr); + + loopback = (ip >> 24) == 127; + + pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); if (unlikely(pcap == NULL)) { return NULL; } - struct SwiftNetClientConnection* const new_connection = construct_client_connection(loopback, port, addr.s_addr, pcap); + new_connection = construct_client_connection(loopback, port, addr.s_addr, pcap); + + goto request_initialization; + +request_initialization: // Request the server information, and proccess it - const struct SwiftNetPacketInfo request_server_information_packet_info = construct_packet_info( + request_server_information_packet_info = construct_packet_info( 0x00, REQUEST_INFORMATION, 1, @@ -138,15 +168,13 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add new_connection->port_info ); - const struct ip request_server_info_ip_header = construct_ip_header(new_connection->server_addr, PACKET_HEADER_SIZE, rand()); + request_server_info_ip_header = construct_ip_header(new_connection->server_addr, PACKET_HEADER_SIZE, rand()); HANDLE_PACKET_CONSTRUCTION(&request_server_info_ip_header, &request_server_information_packet_info, new_connection->addr_type, &new_connection->eth_header, PACKET_HEADER_SIZE + new_connection->prepend_size, request_server_info_buffer) HANDLE_CHECKSUM(request_server_info_buffer, sizeof(request_server_info_buffer), new_connection->prepend_size); - pthread_t send_request_thread; - - const struct RequestServerInformationArgs thread_args = { + thread_args = (struct RequestServerInformationArgs){ .pcap = pcap, .data = request_server_info_buffer, .size = sizeof(request_server_info_buffer), @@ -155,7 +183,7 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add .connection = new_connection }; - struct Listener* const listener = check_existing_listener(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface, new_connection, CONNECTION_TYPE_CLIENT, loopback); + listener = check_existing_listener(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface, new_connection, CONNECTION_TYPE_CLIENT, loopback); pthread_create(&send_request_thread, NULL, request_server_information, (void*)&thread_args); diff --git a/src/initialize_server.c b/src/initialize_server.c index f5c585d..7a9778f 100644 --- a/src/initialize_server.c +++ b/src/initialize_server.c @@ -15,11 +15,7 @@ static inline struct SwiftNetServer* const construct_server(const bool loopback, const uint16_t server_port, pcap_t* const pcap) { struct SwiftNetServer* const new_server = allocator_allocate(&server_memory_allocator); - - struct ether_header eth_header = { - .ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, - .ether_type = htons(0x0800) - }; + struct ether_header eth_header = DEFAULT_MAC_ADDRESS_STRUCT; memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); @@ -57,13 +53,17 @@ static inline struct SwiftNetServer* const construct_server(const bool loopback, struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool loopback) { // Init pcap device - pcap_t* const pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + struct SwiftNetServer* new_server; + pcap_t* pcap; + + + pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); if (unlikely(pcap == NULL)) { PRINT_ERROR("Failed to open bpf"); return NULL; } - struct SwiftNetServer* const new_server = construct_server(loopback, port, pcap); + new_server = construct_server(loopback, port, pcap); // Create a new thread that will handle all packets received check_existing_listener(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface, new_server, CONNECTION_TYPE_SERVER, loopback); diff --git a/src/initialize_swiftnet.c b/src/initialize_swiftnet.c index 37d8480..53336aa 100644 --- a/src/initialize_swiftnet.c +++ b/src/initialize_swiftnet.c @@ -82,17 +82,25 @@ static inline void initialize_memory_cleanup_thread() { } void swiftnet_initialize() { + int temp_socket; + struct sockaddr_in remote = {0}; + struct sockaddr private_sockaddr; + socklen_t private_sockaddr_len = sizeof(private_sockaddr); + seed = rand(); atomic_store_explicit(&swiftnet_closing, false, memory_order_release); - const int temp_socket = socket(AF_INET, SOCK_DGRAM, 0); + goto create_temp_socket; + + +create_temp_socket: + temp_socket= socket(AF_INET, SOCK_DGRAM, 0); if (temp_socket < 0) { PRINT_ERROR("Failed to create temp socket"); exit(EXIT_FAILURE); } - struct sockaddr_in remote = {0}; remote.sin_family = AF_INET; remote.sin_port = htons(53); inet_pton(AF_INET, "8.8.8.8", &remote.sin_addr); @@ -103,9 +111,10 @@ void swiftnet_initialize() { exit(EXIT_FAILURE); } - struct sockaddr private_sockaddr; - socklen_t private_sockaddr_len = sizeof(private_sockaddr); + goto extract_network_data; + +extract_network_data: if(getsockname(temp_socket, &private_sockaddr, &private_sockaddr_len) == -1) { PRINT_ERROR("Failed to get private ip address"); close(temp_socket); @@ -114,8 +123,7 @@ void swiftnet_initialize() { private_ip_address = ((struct sockaddr_in *)&private_sockaddr)->sin_addr; - const int got_default_interface = get_default_interface_and_mac(default_network_interface, sizeof(default_network_interface), mac_address, temp_socket); - if(unlikely(got_default_interface != 0)) { + if(unlikely(get_default_interface_and_mac(default_network_interface, sizeof(default_network_interface), mac_address, temp_socket) != 0)) { PRINT_ERROR("Failed to get the default interface"); close(temp_socket); exit(EXIT_FAILURE); @@ -129,7 +137,11 @@ void swiftnet_initialize() { } close(temp_socket); + + goto finish; + +finish: initialize_allocators(); initialize_vectors(); diff --git a/src/internal/internal.h b/src/internal/internal.h index eab8919..f22b35d 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -48,8 +48,8 @@ enum RequestLostPacketsReturnType { // "hashmap_item" contains pointer to current struct SwiftNetHashMapItem // "hashmap_data" contains data stored inside struct SwiftNetHashMapItem #define LOOP_HASHMAP(hashmap, loop_body) \ - for(uint32_t i = 0; i < (hashmap->capacity + 31) / 32; i++) { \ - uint32_t current_index = *(hashmap->item_occupation + i); \ + for(uint32_t i = 0; i < ((hashmap)->capacity + 31) / 32; i++) { \ + uint32_t current_index = *((hashmap)->item_occupation + i); \ if(current_index == 0x00) { \ continue; \ } \ @@ -57,7 +57,7 @@ enum RequestLostPacketsReturnType { while(inverted != UINT32_MAX) { \ uint32_t bit_index = __builtin_ctz(inverted); \ inverted |= 1 << bit_index; \ - for(struct SwiftNetHashMapItem* hashmap_item = hashmap->items + ((i * 32) + bit_index); hashmap_item != NULL; hashmap_item = hashmap_item->next) { \ + for(struct SwiftNetHashMapItem* hashmap_item = (hashmap)->items + ((i * 32) + bit_index); hashmap_item != NULL; hashmap_item = hashmap_item->next) { \ void* const hashmap_data = hashmap_item->value; \ loop_body \ } \ @@ -97,6 +97,8 @@ enum RequestLostPacketsReturnType { const uint32_t checksum = crc32(buffer, size); \ memcpy(buffer + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, checksum), &checksum, sizeof(checksum)); +#define DEFAULT_MAC_ADDRESS_STRUCT {.ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, .ether_type = htons(0x0800)} + // Number used in ip.proto #define PROT_NUMBER 253 diff --git a/src/make_request.c b/src/make_request.c index ac63024..336b49a 100644 --- a/src/make_request.c +++ b/src/make_request.c @@ -20,81 +20,98 @@ static inline void delete_request_sent(struct RequestSent* request_sent) { static inline struct RequestSent* const construct_request_sent(const struct in_addr address) { struct RequestSent* const request_sent = allocator_allocate(&requests_sent_memory_allocator); - request_sent->packet_data = NULL; - request_sent->address = address; + + *request_sent = (struct RequestSent){.address = address, .packet_data = NULL}; return request_sent; } -struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetClientConnection* const client, struct SwiftNetPacketBuffer* const packet, const uint32_t timeout_ms) { - struct RequestSent* const request_sent = construct_request_sent(client->server_addr); +struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetClientConnection* const client, struct SwiftNetPacketBuffer* restrict const packet, const uint32_t timeout_ms) { + struct RequestSent* request_sent; + uint32_t packet_length; + struct timeval tv; + uint32_t start; + uint32_t end; + + request_sent = construct_request_sent(client->server_addr); - const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; + packet_length = packet->packet_append_pointer - packet->packet_data_start; swiftnet_send_packet(client, client->maximum_transmission_unit, client->port_info, packet, packet_length, &client->server_addr, &client->packets_sending, &client->packets_sending_memory_allocator, client->pcap, client->eth_header, client->loopback, client->addr_type, client->prepend_size, request_sent, false, 0); - struct timeval tv; + gettimeofday(&tv, NULL); - uint32_t start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; - while (1) { - gettimeofday(&tv, NULL); - uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + goto check_response; - if (start + timeout_ms < end) { - delete_request_sent(request_sent); - return NULL; - } +check_response: + gettimeofday(&tv, NULL); + end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if (start + timeout_ms < end) { + delete_request_sent(request_sent); - if (atomic_load_explicit(&request_sent->packet_data, memory_order_acquire) != NULL) { - struct SwiftNetClientPacketData* const packet_data = request_sent->packet_data; + return NULL; + } - allocator_free(&requests_sent_memory_allocator, request_sent); + if (atomic_load_explicit(&request_sent->packet_data, memory_order_acquire) != NULL) { + struct SwiftNetClientPacketData* const packet_data = request_sent->packet_data; - return packet_data; - } + allocator_free(&requests_sent_memory_allocator, request_sent); - usleep(5000); + return packet_data; } + + usleep(5000); + + goto check_response; } struct SwiftNetServerPacketData* swiftnet_server_make_request(struct SwiftNetServer* const server, struct SwiftNetPacketBuffer* const packet, const struct SwiftNetClientAddrData addr_data, const uint32_t timeout_ms) { - struct RequestSent* const request_sent = construct_request_sent(addr_data.sender_address); + struct RequestSent* request_sent; + uint32_t packet_length; + struct SwiftNetPortInfo port_info; + struct timeval tv; + uint32_t start; + uint32_t end; + + request_sent = construct_request_sent(addr_data.sender_address); - const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; + packet_length = packet->packet_append_pointer - packet->packet_data_start; - const struct SwiftNetPortInfo port_info = { - .destination_port = addr_data.port, - .source_port = server->server_port - }; + port_info = (struct SwiftNetPortInfo){.destination_port = addr_data.port, .source_port = server->server_port}; swiftnet_send_packet(server, addr_data.maximum_transmission_unit, port_info, packet, packet_length, &addr_data.sender_address, &server->packets_sending, &server->packets_sending_memory_allocator, server->pcap, server->eth_header, server->loopback, server->addr_type, server->prepend_size, request_sent, false, 0); - struct timeval tv; gettimeofday(&tv, NULL); - uint32_t start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; - while (1) { - gettimeofday(&tv, NULL); - uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + goto check_response; - if (start + timeout_ms < end) { - delete_request_sent(request_sent); - return NULL; - } +check_response: + gettimeofday(&tv, NULL); + end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; - if (request_sent->packet_data != NULL) { - struct SwiftNetServerPacketData* const packet_data = request_sent->packet_data; + if (start + timeout_ms < end) { + delete_request_sent(request_sent); - allocator_free(&requests_sent_memory_allocator, (void*)request_sent); + return NULL; + } + + if (request_sent->packet_data != NULL) { + struct SwiftNetServerPacketData* const packet_data = request_sent->packet_data; - return packet_data; - } + allocator_free(&requests_sent_memory_allocator, (void*)request_sent); - usleep(5000); + return packet_data; } + + usleep(5000); + + goto check_response; } #endif diff --git a/src/make_response.c b/src/make_response.c index 089dc97..4915a2a 100644 --- a/src/make_response.c +++ b/src/make_response.c @@ -11,11 +11,7 @@ void swiftnet_client_make_response(struct SwiftNetClientConnection* const client void swiftnet_server_make_response(struct SwiftNetServer* const server, struct SwiftNetServerPacketData* const packet_data, struct SwiftNetPacketBuffer* const buffer) { const uint32_t packet_length = buffer->packet_append_pointer - buffer->packet_data_start; - - const struct SwiftNetPortInfo port_info = { - .source_port = server->server_port, - .destination_port = packet_data->metadata.port_info.source_port - }; + const struct SwiftNetPortInfo port_info = {.source_port = server->server_port, .destination_port = packet_data->metadata.port_info.source_port}; swiftnet_send_packet(server, packet_data->metadata.sender.maximum_transmission_unit, port_info, buffer, packet_length, &packet_data->metadata.sender.sender_address, &server->packets_sending, &server->packets_sending_memory_allocator, server->pcap, server->eth_header, server->loopback, server->addr_type, server->prepend_size, NULL, true, packet_data->metadata.packet_id); } diff --git a/src/memory_cleanup_background_service.c b/src/memory_cleanup_background_service.c index 4d73509..d62b483 100644 --- a/src/memory_cleanup_background_service.c +++ b/src/memory_cleanup_background_service.c @@ -43,32 +43,33 @@ static inline void handle_listener(struct Listener* const current_listener) { } void* memory_cleanup_background_service() { - while(atomic_load_explicit(&swiftnet_closing, memory_order_acquire) == false) { - struct timeval start, end; - gettimeofday(&start, NULL); + struct timeval start, end; + int64_t elapsed_us; + uint64_t target_us = (uint64_t)PACKET_HISTORY_STORE_TIME * 1000000ULL; - LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); - struct SwiftNetHashMap* const listeners_map = &listeners; +start_loop: + if(atomic_load_explicit(&swiftnet_closing, memory_order_acquire) == true) return NULL; - LOOP_HASHMAP(listeners_map, - handle_listener(hashmap_data); - ) + gettimeofday(&start, NULL); - UNLOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); + LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); - gettimeofday(&end, NULL); + LOOP_HASHMAP(&listeners, + handle_listener(hashmap_data); + ) - int64_t elapsed_us = (int64_t)(end.tv_sec - start.tv_sec) * 1000000LL + (end.tv_usec - start.tv_usec); + UNLOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); - if (elapsed_us < 0) elapsed_us = 0; + gettimeofday(&end, NULL); - uint64_t target_us = (uint64_t)PACKET_HISTORY_STORE_TIME * 1000000ULL; + elapsed_us = (int64_t)(end.tv_sec - start.tv_sec) * 1000000LL + (end.tv_usec - start.tv_usec); - if ((uint64_t)elapsed_us < target_us) { - usleep(target_us - (uint64_t)elapsed_us); - } + if (elapsed_us < 0) elapsed_us = 0; + + if ((uint64_t)elapsed_us < target_us) { + usleep(target_us - (uint64_t)elapsed_us); } - return NULL; + goto start_loop; } diff --git a/src/packet_buffer.c b/src/packet_buffer.c index d6a9622..92aea2f 100644 --- a/src/packet_buffer.c +++ b/src/packet_buffer.c @@ -5,9 +5,8 @@ #include static inline struct SwiftNetPacketBuffer create_packet_buffer(const uint32_t buffer_size) { - uint8_t* const mem = malloc(buffer_size + PACKET_HEADER_SIZE + sizeof(struct ether_header)); - - uint8_t* const data_pointer = mem + PACKET_HEADER_SIZE + sizeof(struct ether_header); + uint8_t* restrict const mem = malloc(buffer_size + PACKET_HEADER_SIZE + sizeof(struct ether_header)); + uint8_t* restrict const data_pointer = mem + PACKET_HEADER_SIZE + sizeof(struct ether_header); return (struct SwiftNetPacketBuffer){ .packet_buffer_start = mem, @@ -20,29 +19,34 @@ struct SwiftNetPacketBuffer swiftnet_create_packet_buffer(const uint32_t buffer_ return create_packet_buffer(buffer_size); } -void swiftnet_resize_packet_buffer(uint32_t new_buffer_size, struct SwiftNetPacketBuffer* const packet_buffer) { +void swiftnet_resize_packet_buffer(uint32_t new_buffer_size, struct SwiftNetPacketBuffer* restrict const packet_buffer) { + void* new_ptr; + void* data_start; + const uint32_t current_offset = packet_buffer->packet_append_pointer - packet_buffer->packet_data_start; - new_buffer_size += PACKET_HEADER_SIZE + sizeof(struct ether_header); - void* const new_ptr = realloc(packet_buffer->packet_buffer_start, new_buffer_size); + new_buffer_size += PACKET_HEADER_SIZE + sizeof(struct ether_header); + new_ptr = realloc(packet_buffer->packet_buffer_start, new_buffer_size); if (unlikely(new_ptr == NULL)) { PRINT_ERROR("Failed to realloc"); exit(EXIT_FAILURE); } - void* const data_start = new_ptr + PACKET_HEADER_SIZE + sizeof(struct ether_header); + data_start = new_ptr + PACKET_HEADER_SIZE + sizeof(struct ether_header); - packet_buffer->packet_buffer_start = new_ptr; - packet_buffer->packet_data_start = data_start; - packet_buffer->packet_append_pointer = data_start + current_offset; + *packet_buffer = (struct SwiftNetPacketBuffer){ + .packet_buffer_start = new_ptr, + .packet_data_start = data_start, + .packet_append_pointer = data_start + current_offset + }; } -void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* const packet_buffer, void* const data, const uint32_t data_size) { +void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* const packet_buffer, void* restrict const data, const uint32_t data_size) { memcpy(packet_buffer->packet_data_start + byte_offset, data, data_size); } -void swiftnet_destroy_packet_buffer(const struct SwiftNetPacketBuffer* const packet) { +void swiftnet_destroy_packet_buffer(const struct SwiftNetPacketBuffer* restrict const packet) { free(packet->packet_buffer_start); } diff --git a/src/process_packets.c b/src/process_packets.c index 2b7ce8d..46b4664 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -28,62 +28,65 @@ static inline bool is_private_ip(struct in_addr ip) { } // Returns an array of 4 byte uint32_t, that contain indexes of lost chunks -static inline const uint32_t return_lost_chunk_indexes(const uint8_t* const chunks_received, const uint32_t chunk_amount, const uint32_t buffer_size, uint32_t* const buffer) { +static inline const uint32_t return_lost_chunk_indexes(const uint8_t* restrict const chunks_received, const uint32_t chunk_amount, const uint32_t buffer_size, uint32_t* restrict const buffer) { uint32_t byte = 0; - uint32_t offset = 0; - while(1) { - if(byte * 8 + 8 < chunk_amount) { - if(chunks_received[byte] == 0xFF) { - byte++; - continue; - } + goto loop; - for(uint8_t bit = 0; bit < 8; bit++) { - if(offset * 4 + 4 > buffer_size) { - return offset; - } +loop: + if(byte * 8 + 8 < chunk_amount) { + if(chunks_received[byte] == 0xFF) { + byte++; + + goto loop; + } - if((chunks_received[byte] & (1u << bit)) == 0x00) { - buffer[offset] = byte * 8 + bit; - offset++; - } + for(uint8_t bit = 0; bit < 8; bit++) { + if(offset * 4 + 4 > buffer_size) goto exit; + + if((chunks_received[byte] & (1u << bit)) == 0x00) { + buffer[offset] = byte * 8 + bit; + offset++; } - } else { - const uint32_t bits_to_check = chunk_amount - byte * 8; + } + } else { + for(uint32_t bit = 0; bit < chunk_amount - byte * 8; bit++) { + if(offset * 4 + 4 > buffer_size) goto exit; - for(uint32_t bit = 0; bit < bits_to_check; bit++) { - if(offset * 4 + 4 > buffer_size) { - return offset; - } - - if((chunks_received[byte] & (1u << bit)) == 0x00) { - buffer[offset] = byte * 8 + bit; - offset++; - } + if((chunks_received[byte] & (1u << bit)) == 0x00) { + buffer[offset] = byte * 8 + bit; + offset++; } - - return offset; } - - byte++; + + goto exit; } + byte++; + + goto loop; + + +exit: return offset; } -static inline void packet_completed(const uint16_t packet_id, const uint16_t source_port, struct SwiftNetHashMap* const packets_completed_history, struct SwiftNetMemoryAllocator* const packets_completed_history_memory_allocator) { - struct SwiftNetPacketCompleted* const new_packet_completed = allocator_allocate(packets_completed_history_memory_allocator); - new_packet_completed->packet_id = packet_id; - new_packet_completed->marked_cleanup = false; +static inline void packet_completed(const uint16_t packet_id, const uint16_t source_port, struct SwiftNetHashMap* restrict const packets_completed_history, struct SwiftNetMemoryAllocator* restrict const packets_completed_history_memory_allocator) { + struct SwiftNetPacketCompleted* restrict new_packet_completed; + struct PacketCompletedKey* restrict key; + uint16_t* restrict heap_key_data_location; + - uint16_t* heap_key_data_location = allocator_allocate(&uint16_memory_allocator); + new_packet_completed = allocator_allocate(packets_completed_history_memory_allocator); + *new_packet_completed = (struct SwiftNetPacketCompleted){.packet_id = packet_id, .marked_cleanup = false}; + + heap_key_data_location = allocator_allocate(&uint16_memory_allocator); *heap_key_data_location = packet_id; LOCK_ATOMIC_DATA_TYPE(&packets_completed_history->atomic_lock); - struct PacketCompletedKey* const key = allocator_allocate(&packet_completed_key_allocator); + key = allocator_allocate(&packet_completed_key_allocator); *key = (struct PacketCompletedKey){ .source_port = source_port, .packet_id = packet_id @@ -97,35 +100,35 @@ static inline void packet_completed(const uint16_t packet_id, const uint16_t sou } static inline bool check_packet_already_completed(const uint16_t packet_id, const uint16_t source_port, struct SwiftNetHashMap* const packets_completed_history) { - const struct PacketCompletedKey key = { - .packet_id = packet_id, - .source_port = source_port - }; + struct PacketCompletedKey key; + struct SwiftNetPacketCompleted* item; - const struct SwiftNetPacketCompleted* const item = hashmap_get(&key, sizeof(key), packets_completed_history); + + key = (struct PacketCompletedKey){.packet_id = packet_id, .source_port = source_port}; + + item = hashmap_get(&key, sizeof(key), packets_completed_history); return item != NULL; } static inline struct SwiftNetPendingMessage* const get_pending_message(struct SwiftNetHashMap* const pending_messages, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { + struct PendingMessagesKey key; + struct SwiftNetPendingMessage* pending_message; + + LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); - const struct PendingMessagesKey key = { - .source_port = source_port, - .packet_id = packet_id - }; + key = (struct PendingMessagesKey){.source_port = source_port, .packet_id = packet_id}; - struct SwiftNetPendingMessage* const pending_message = hashmap_get(&key, sizeof(key), pending_messages); + pending_message = hashmap_get(&key, sizeof(key), pending_messages); UNLOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); return pending_message; } -static inline void insert_callback_queue_node(struct PacketCallbackQueueNode* const new_node, struct PacketCallbackQueue* const packet_queue) { - if(unlikely(new_node == NULL)) { - return; - } +static inline void insert_callback_queue_node(struct PacketCallbackQueueNode* restrict const new_node, struct PacketCallbackQueue* const packet_queue) { + if(unlikely(new_node == NULL)) return; LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked); @@ -148,12 +151,12 @@ static inline void insert_callback_queue_node(struct PacketCallbackQueueNode* co #ifdef SWIFT_NET_REQUESTS -static inline void handle_request_response(uint16_t packet_id, struct SwiftNetPendingMessage* const pending_message, void* const packet_data, struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, const enum ConnectionType connection_type, const bool loopback, const uint16_t source_port) { - bool is_valid_response = false; +static inline void handle_request_response(uint16_t packet_id, struct SwiftNetPendingMessage* restrict const pending_message, void* restrict const packet_data, struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, const enum ConnectionType connection_type, const bool loopback, const uint16_t source_port) { + struct RequestSent* request_sent; LOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); - struct RequestSent* const request_sent = hashmap_get(&packet_id, sizeof(uint16_t), &requests_sent); + request_sent = hashmap_get(&packet_id, sizeof(uint16_t), &requests_sent); if (request_sent == NULL) { UNLOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); return; @@ -163,36 +166,32 @@ static inline void handle_request_response(uint16_t packet_id, struct SwiftNetPe hashmap_remove(&packet_id, sizeof(uint16_t), &requests_sent); - is_valid_response = true; - UNLOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); - if (is_valid_response == true) { - if (pending_message != NULL) { - LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); + if (pending_message != NULL) { + struct PendingMessagesKey key; - struct PendingMessagesKey key = { - .source_port = source_port, - .packet_id = packet_id - }; - hashmap_remove(&key, sizeof(key), pending_messages); + key = (struct PendingMessagesKey){.source_port = source_port, .packet_id = packet_id}; - UNLOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); - } + LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); + + hashmap_remove(&key, sizeof(key), pending_messages); + + UNLOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); return; - } + } else return; } #endif -static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* const pending_message, const uint16_t packet_id, pthread_mutex_t* const execute_callback_mtx, pthread_cond_t* const execute_callback_cond) { - struct PacketCallbackQueueNode* const node = allocator_allocate(&packet_callback_queue_node_memory_allocator); - node->packet_data = packet_data; - node->next = NULL; - node->pending_message = pending_message; - node->packet_id = packet_id; +static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* restrict const pending_message, const uint16_t packet_id, pthread_mutex_t* const execute_callback_mtx, pthread_cond_t* const execute_callback_cond) { + struct PacketCallbackQueueNode* restrict node; + + + node = allocator_allocate(&packet_callback_queue_node_memory_allocator); + *node = (struct PacketCallbackQueueNode){.packet_data = packet_data, .next = NULL, .pending_message = pending_message, .packet_id = packet_id}; pthread_mutex_lock(execute_callback_mtx); @@ -204,10 +203,7 @@ static inline void pass_callback_execution(void* const packet_data, struct Packe } static inline bool chunk_already_received(uint8_t* const chunks_received, const uint32_t index) { - const uint32_t byte = index / 8; - const uint8_t bit = index % 8; - - return (chunks_received[byte] & (1U << bit)) != 0; + return (chunks_received[index / 8] & (1U << (index % 8))) != 0; } static inline void chunk_received(uint8_t* const chunks_received, const uint32_t index) { @@ -217,30 +213,33 @@ static inline void chunk_received(uint8_t* const chunks_received, const uint32_t chunks_received[byte] |= (uint8_t)(1U << bit); } -static inline struct SwiftNetPendingMessage* const create_new_pending_message(struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, const struct SwiftNetPacketInfo* const packet_info, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { - struct SwiftNetPendingMessage* const new_pending_message = allocator_allocate(pending_messages_memory_allocator); - - uint8_t* const allocated_memory = malloc(packet_info->packet_length); - +static inline struct SwiftNetPendingMessage* const create_new_pending_message(struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, const struct SwiftNetPacketInfo* restrict const packet_info, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { + struct SwiftNetPendingMessage* restrict new_pending_message; + uint8_t* restrict allocated_memory; + struct PendingMessagesKey* key; const uint32_t chunks_received_byte_size = (packet_info->chunk_amount + 7) / 8; - new_pending_message->packet_info = *packet_info; - new_pending_message->packet_data_start = allocated_memory; - new_pending_message->chunks_received_number = 0x00; - new_pending_message->last_index_checked = 0; - new_pending_message->sending_lost_packets = false; - new_pending_message->last_chunks_received_number = 0; + new_pending_message = allocator_allocate(pending_messages_memory_allocator); - new_pending_message->chunks_received_length = chunks_received_byte_size; - new_pending_message->chunks_received = calloc(chunks_received_byte_size, 1); + allocated_memory = malloc(packet_info->packet_length); - new_pending_message->packet_id = packet_id; - new_pending_message->source_port = source_port; + *new_pending_message = (struct SwiftNetPendingMessage){ + .packet_info = *packet_info, + .packet_data_start = allocated_memory, + .chunks_received_number = 0x00, + .last_index_checked = 0, + .sending_lost_packets = false, + .last_chunks_received_number = 0, + .chunks_received_length = chunks_received_byte_size, + .chunks_received = calloc(chunks_received_byte_size, 1), + .packet_id = packet_id, + .source_port = source_port, + }; LOCK_ATOMIC_DATA_TYPE(&pending_messages->atomic_lock); - struct PendingMessagesKey* const key = allocator_allocate(&pending_message_key_allocator); + key = allocator_allocate(&pending_message_key_allocator); *key = (struct PendingMessagesKey){ .source_port = source_port, .packet_id = packet_id @@ -254,9 +253,12 @@ static inline struct SwiftNetPendingMessage* const create_new_pending_message(st } static inline struct SwiftNetPacketSending* const get_packet_sending(struct SwiftNetHashMap* const packet_sending_array, uint16_t target_id) { + struct SwiftNetPacketSending* result; + + LOCK_ATOMIC_DATA_TYPE(&packet_sending_array->atomic_lock); - struct SwiftNetPacketSending* const result = hashmap_get(&target_id, sizeof(target_id), packet_sending_array); + result = hashmap_get(&target_id, sizeof(target_id), packet_sending_array); UNLOCK_ATOMIC_DATA_TYPE(&packet_sending_array->atomic_lock); @@ -264,9 +266,14 @@ static inline struct SwiftNetPacketSending* const get_packet_sending(struct Swif } static inline void signal_delay_change(const enum PacketDelayUpdateStatus status, const struct ip* const ip_header, const uint16_t source_port, const uint16_t destination_port, const uint16_t addr_type, const uint8_t prepend_size, pcap_t* const pcap, const struct ether_header* const eth_hdr) { - const struct ip send_server_info_ip_header = construct_ip_header(ip_header->ip_src, PACKET_HEADER_SIZE, ip_header->ip_id); + struct ip send_server_info_ip_header; + struct SwiftNetPacketInfo packet_info_new; + struct SwiftNetServerInformation server_info; - const struct SwiftNetPacketInfo packet_info_new = construct_packet_info( + + send_server_info_ip_header = construct_ip_header(ip_header->ip_src, PACKET_HEADER_SIZE, ip_header->ip_id); + + packet_info_new = construct_packet_info( sizeof(enum PacketDelayUpdateStatus), PACKET_DELAY_UPDATE, 1, @@ -277,7 +284,7 @@ static inline void signal_delay_change(const enum PacketDelayUpdateStatus status } ); - const struct SwiftNetServerInformation server_info = { + server_info = (struct SwiftNetServerInformation){ .maximum_transmission_unit = maximum_transmission_unit }; @@ -291,6 +298,8 @@ static inline void signal_delay_change(const enum PacketDelayUpdateStatus status } struct PacketQueueNode* const wait_for_next_packet(struct PacketQueue* const packet_queue) { + struct PacketQueueNode* node_to_process; + LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked); if(packet_queue->first_node == NULL) { @@ -298,7 +307,7 @@ struct PacketQueueNode* const wait_for_next_packet(struct PacketQueue* const pac return NULL; } - struct PacketQueueNode* const node_to_process = packet_queue->first_node; + node_to_process = packet_queue->first_node; if(node_to_process->next == NULL) { packet_queue->first_node = NULL; @@ -316,7 +325,7 @@ struct PacketQueueNode* const wait_for_next_packet(struct PacketQueue* const pac return node_to_process; } -static inline bool packet_corrupted(const uint32_t checksum, const uint32_t chunk_size, uint8_t* const buffer) { +static inline bool packet_corrupted(const uint32_t checksum, const uint32_t chunk_size, uint8_t* restrict const buffer) { return crc32(buffer, chunk_size) != checksum; } diff --git a/tests/performance_tests/src/main.c b/tests/performance_tests/src/main.c index 38e85c3..ca54208 100644 --- a/tests/performance_tests/src/main.c +++ b/tests/performance_tests/src/main.c @@ -8,11 +8,11 @@ #include "../../shared.h" -//#define PACKET_SIZE 1000000 // 1 MILLION BYTES -//#define PACKETS_TO_SEND 50 // HOW MANY PACKETS TO SEND +#define PACKET_SIZE 1000000 // 1 MILLION BYTES +#define PACKETS_TO_SEND 50 // HOW MANY PACKETS TO SEND -#define PACKET_SIZE 100000000 // 100 MILLION BYTES -#define PACKETS_TO_SEND 1 // HOW MANY PACKETS TO SEND +//#define PACKET_SIZE 100000000 // 100 MILLION BYTES +//#define PACKETS_TO_SEND 1 // HOW MANY PACKETS TO SEND // ********************** // // SEND 100 MILLION BYTES // From 7f3fc204e77480f592331e072824379d71b3b7d6 Mon Sep 17 00:00:00 2001 From: Morcules Date: Tue, 16 Jun 2026 11:54:18 +0200 Subject: [PATCH 2/2] New structure completed --- src/cleanup_connection.c | 2 +- src/execute_packet_callback.c | 8 +- src/generic_functions.c | 2 +- src/handle_packets.c | 12 +- src/initialize_client_connection.c | 4 +- src/internal/check_existing_listener.c | 45 +- src/internal/datatype_allocator.c | 259 ++++-- src/internal/datatype_hashmap.c | 194 +++-- src/internal/datatype_vector.c | 38 +- src/internal/get_default_interface_and_mac.c | 78 +- src/internal/get_mtu.c | 10 +- src/internal/internal.h | 97 ++- src/internal/pcap_open.c | 23 +- src/internal/pcap_send.c | 11 +- src/make_request.c | 4 +- src/make_response.c | 4 +- src/memory_cleanup_background_service.c | 2 +- src/packet_buffer.c | 2 +- src/process_packets.c | 808 ++++++++++--------- src/send_packet.c | 242 +++--- src/swift_net.h | 30 +- tests/performance_tests/src/main.c | 8 +- 22 files changed, 1127 insertions(+), 756 deletions(-) diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index 7ccf07e..c650ac3 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -32,7 +32,7 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec static inline void remove_listener(const enum ConnectionType connection_type, const char* const restrict interface_name, void* const connection) { uint32_t interface_len; - struct Listener* restrict listener; + struct Listener* listener; interface_len = strlen(interface_name); diff --git a/src/execute_packet_callback.c b/src/execute_packet_callback.c index eef2bc3..dc3f853 100644 --- a/src/execute_packet_callback.c +++ b/src/execute_packet_callback.c @@ -54,10 +54,10 @@ void execute_packet_callback( struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, const _Atomic bool * const closing, void * const connection, - struct SwiftNetHashMap * const pending_messages, - _Atomic(void *) *user_data, - pthread_mutex_t* restrict const execute_callback_mtx, - pthread_cond_t* restrict const execute_callback_cond + struct SwiftNetHashMap* const pending_messages, + _Atomic(void *) * const user_data, + pthread_mutex_t* const execute_callback_mtx, + pthread_cond_t* const execute_callback_cond ) { void (*packet_handler_loaded)(void *const, void *const); diff --git a/src/generic_functions.c b/src/generic_functions.c index e6fdb20..d82e159 100644 --- a/src/generic_functions.c +++ b/src/generic_functions.c @@ -6,7 +6,7 @@ #include // These functions append data to a packet buffer and advance the current pointer by the data size. -static inline void validate_append_to_packet_args(const void* const data, const uint32_t data_size) { +static inline void validate_append_to_packet_args(const void* restrict const data, const uint32_t data_size) { if(unlikely(data == NULL || data_size == 0)) { PRINT_ERROR("Error: Invalid arguments given"); exit(EXIT_FAILURE); diff --git a/src/handle_packets.c b/src/handle_packets.c index c5c21eb..3dfeaca 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -38,7 +38,7 @@ static inline void insert_queue_node( return; } -static inline struct PacketQueueNode* construct_node(const uint32_t data_read, void* const data, const uint32_t sender_address) { +static inline struct PacketQueueNode* construct_node(const uint32_t data_read, void* restrict const data, const uint32_t sender_address) { struct PacketQueueNode* restrict node; @@ -70,11 +70,11 @@ static inline void swiftnet_handle_packets( void* const connection, const enum ConnectionType connection_type, struct PacketQueue* const packet_queue, - const _Atomic bool* closing, + const _Atomic bool* const closing, const bool loopback, const uint16_t addr_type, - const struct pcap_pkthdr* hdr, - const uint8_t* const packet, + const struct pcap_pkthdr* restrict const hdr, + const uint8_t* restrict const packet, pthread_mutex_t* const process_packets_mtx, pthread_cond_t* const process_packets_cond, _Atomic bool *const processing_packets @@ -269,8 +269,8 @@ static void pcap_packet_handle(uint8_t* const user, const struct pcap_pkthdr* re handle_correct_receiver(CONNECTION_TYPE_SERVER, listener, hdr, packet, port_info); } -void* interface_start_listening(void* const listener) { - pcap_loop(((struct Listener*)listener)->pcap, 0, pcap_packet_handle, listener); +void* interface_start_listening(void* const listener_void) { + pcap_loop(((struct Listener*)listener_void)->pcap, 0, pcap_packet_handle, listener_void); return NULL; } diff --git a/src/initialize_client_connection.c b/src/initialize_client_connection.c index bfff0e9..08dc555 100644 --- a/src/initialize_client_connection.c +++ b/src/initialize_client_connection.c @@ -29,7 +29,7 @@ struct RequestServerInformationArgs { struct SwiftNetClientConnection* connection; }; -void* request_server_information(void* restrict const request_server_information_args_void) { +void* request_server_information(void* const request_server_information_args_void) { const struct RequestServerInformationArgs* const request_server_information_args = request_server_information_args_void; struct timeval tv; @@ -131,7 +131,7 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add uint32_t ip; bool loopback; pcap_t* pcap; - struct SwiftNetClientConnection* restrict new_connection; + struct SwiftNetClientConnection* new_connection; struct SwiftNetPacketInfo request_server_information_packet_info; struct ip request_server_info_ip_header; pthread_t send_request_thread; diff --git a/src/internal/check_existing_listener.c b/src/internal/check_existing_listener.c index 656683b..3a16857 100644 --- a/src/internal/check_existing_listener.c +++ b/src/internal/check_existing_listener.c @@ -3,18 +3,25 @@ #include #include -void* check_existing_listener(const char* interface_name, void* const connection, const enum ConnectionType connection_type, const bool loopback) { +void* check_existing_listener(const char* restrict const interface_name, void* const connection, const enum ConnectionType connection_type, const bool loopback) { + uint32_t interface_len; + struct Listener* existing_listener; + struct Listener* new_listener; + uint16_t* key_allocated_mem; + char* listener_key; + + LOCK_ATOMIC_DATA_TYPE(&listeners.atomic_lock); - const uint32_t interface_len = strlen(interface_name); + interface_len = strlen(interface_name); - struct Listener* const existing_listener = hashmap_get(interface_name, interface_len, &listeners); + existing_listener = hashmap_get(interface_name, interface_len, &listeners); - if (existing_listener != NULL) { - if (connection_type == CONNECTION_TYPE_CLIENT) { + if(existing_listener != NULL) { + if(connection_type == CONNECTION_TYPE_CLIENT) { LOCK_ATOMIC_DATA_TYPE(&existing_listener->client_connections.atomic_lock); - uint16_t* const restrict key_allocated_mem = allocator_allocate(&uint16_memory_allocator); + key_allocated_mem = allocator_allocate(&uint16_memory_allocator); *key_allocated_mem = ((struct SwiftNetClientConnection*)connection)->port_info.source_port; hashmap_insert(key_allocated_mem, sizeof(uint16_t), connection, &existing_listener->client_connections); @@ -23,7 +30,7 @@ void* check_existing_listener(const char* interface_name, void* const connection } else { LOCK_ATOMIC_DATA_TYPE(&existing_listener->servers.atomic_lock); - uint16_t* const restrict key_allocated_mem = allocator_allocate(&uint16_memory_allocator); + key_allocated_mem = allocator_allocate(&uint16_memory_allocator); *key_allocated_mem = ((struct SwiftNetServer*)connection)->server_port; hashmap_insert(key_allocated_mem, sizeof(uint16_t), connection, &existing_listener->servers); @@ -36,27 +43,31 @@ void* check_existing_listener(const char* interface_name, void* const connection return existing_listener; } - struct Listener* const new_listener = allocator_allocate(&listener_memory_allocator); - new_listener->servers = hashmap_create(&uint16_memory_allocator); - new_listener->client_connections = hashmap_create(&uint16_memory_allocator); - new_listener->pcap = swiftnet_pcap_open(interface_name); - new_listener->addr_type = pcap_datalink(new_listener->pcap); + new_listener = allocator_allocate(&listener_memory_allocator); + *new_listener = (struct Listener){ + .servers = hashmap_create(&uint16_memory_allocator), + .client_connections = hashmap_create(&uint16_memory_allocator), + .pcap = swiftnet_pcap_open(interface_name), + .loopback = loopback + }; + + new_listener->addr_type = pcap_datalink(new_listener->pcap), + memcpy(new_listener->interface_name, interface_name, interface_len + 1); - new_listener->loopback = loopback; - if (connection_type == CONNECTION_TYPE_CLIENT) { - uint16_t* const restrict key_allocated_mem = allocator_allocate(&uint16_memory_allocator); + if(connection_type == CONNECTION_TYPE_CLIENT) { + key_allocated_mem = allocator_allocate(&uint16_memory_allocator); *key_allocated_mem = ((struct SwiftNetClientConnection*)connection)->port_info.source_port; hashmap_insert(key_allocated_mem, sizeof(uint16_t), connection, &new_listener->client_connections); } else { - uint16_t* const restrict key_allocated_mem = allocator_allocate(&uint16_memory_allocator); + key_allocated_mem = allocator_allocate(&uint16_memory_allocator); *key_allocated_mem = ((struct SwiftNetServer*)connection)->server_port; hashmap_insert(key_allocated_mem, sizeof(uint16_t), connection, &new_listener->servers); } - char* const restrict listener_key = malloc(interface_len); + listener_key = malloc(interface_len); memcpy(listener_key, interface_name, interface_len); diff --git a/src/internal/datatype_allocator.c b/src/internal/datatype_allocator.c index 3ca6727..15b42cf 100644 --- a/src/internal/datatype_allocator.c +++ b/src/internal/datatype_allocator.c @@ -16,43 +16,67 @@ static inline void unlock_ptr_status(struct SwiftNetMemoryAllocatorStack* const } static inline void lock_ptr_status(struct SwiftNetMemoryAllocatorStack* const stack) { - bool target = false; + bool target; - while(!atomic_compare_exchange_strong_explicit( + + target = false; + + goto acquire_lock; + + +acquire_lock: + if(atomic_compare_exchange_strong_explicit( &stack->accessing_ptr_status, &target, true, memory_order_acquire, memory_order_relaxed )) { - target = false; + return; } + + target = false; + + goto acquire_lock; } static inline void set_memory_status(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location, const uint8_t status) { - const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + uint16_t stacks_allocated; + uint16_t i; + + + stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); - for (uint16_t i = 0; i < stacks_allocated; i++) { - struct SwiftNetMemoryAllocatorStack* const stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + for(i = 0; i < stacks_allocated; i++) { + struct SwiftNetMemoryAllocatorStack* stack; + uint8_t* casted_data; + uint8_t* casted_memory_loc; + uint32_t offset; + uint32_t index; + uint32_t byte; + uint8_t bit; - const uint8_t* const casted_data = stack->data; - const uint8_t* const casted_memory_loc = memory_location; - if ( + stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + + casted_data = stack->data; + casted_memory_loc = memory_location; + + if( casted_memory_loc >= casted_data && casted_memory_loc < casted_data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) ) { - const uint32_t offset = casted_memory_loc - casted_data; - const uint32_t index = offset / memory_allocator->item_size; + offset = casted_memory_loc - casted_data; + index = offset / memory_allocator->item_size; - const uint32_t byte = index / 8; - const uint8_t bit = index % 8; + byte = index / 8; + bit = index % 8; lock_ptr_status(stack); - if (status) { - *(stack->ptr_status + byte) |= (1u << bit); + if(status) { + *(stack->ptr_status + byte) |= (1u << bit); } else { *(stack->ptr_status + byte) &= ~(1u << bit); } @@ -65,24 +89,37 @@ static inline void set_memory_status(struct SwiftNetMemoryAllocator* const memor } static inline bool is_already_free(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location) { - const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + uint16_t stacks_allocated; + uint16_t i; + - for (uint16_t i = 0; i < stacks_allocated; i++) { - struct SwiftNetMemoryAllocatorStack* const stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); - const uint8_t* const casted_data = stack->data; - const uint8_t* const casted_memory_loc = memory_location; + for(i = 0; i < stacks_allocated; i++) { + struct SwiftNetMemoryAllocatorStack* stack; + uint8_t* casted_data; + uint8_t* casted_memory_loc; + uint32_t offset; + uint32_t index; + uint32_t byte; + uint8_t bit; - if ( - casted_memory_loc >= casted_data + + stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + + casted_data = stack->data; + casted_memory_loc = memory_location; + + if( + casted_memory_loc >= casted_data && casted_memory_loc < casted_data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) ) { - const uint32_t offset = casted_memory_loc - casted_data; - const uint32_t index = offset / memory_allocator->item_size; + offset = casted_memory_loc - casted_data; + index = offset / memory_allocator->item_size; - const uint32_t byte = index / 8; - const uint8_t bit = index % 8; + byte = index / 8; + bit = index % 8; lock_ptr_status(stack); @@ -104,25 +141,25 @@ static inline bool is_already_free(struct SwiftNetMemoryAllocator* const memory_ // Type is either 0/1 - 1 = allocation - 0 = freeing struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(struct SwiftNetMemoryAllocator* const allocator, const uint8_t type) { - const uint16_t stacks_allocated = atomic_load_explicit(&allocator->stacks_allocated, memory_order_acquire); - + uint16_t stacks_allocated; uint64_t bitmap; uint16_t first_free; - - uint64_t invalid_bitmap = 0x00; - + uint64_t invalid_bitmap; uint64_t new_bitmap; - uint32_t stack_size; - bool valid_size; + struct SwiftNetMemoryAllocatorStack* stack; + + + stacks_allocated = atomic_load_explicit(&allocator->stacks_allocated, memory_order_acquire); - struct SwiftNetMemoryAllocatorStack* stack = NULL; + invalid_bitmap = 0x00; bitmap = atomic_load_explicit(&allocator->occupied, memory_order_acquire); goto find_free_stack; + find_free_stack: if((bitmap | invalid_bitmap) == UINT64_MAX) { return NULL; @@ -130,13 +167,13 @@ struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(struct SwiftN first_free = __builtin_ctzll(~(bitmap | invalid_bitmap)); } - if (first_free >= stacks_allocated) { + if(first_free >= stacks_allocated) { return NULL; } new_bitmap = bitmap | (1ULL << first_free); - if (!atomic_compare_exchange_strong_explicit(&allocator->occupied, &bitmap, new_bitmap, memory_order_release, memory_order_acquire)) { + if(!atomic_compare_exchange_strong_explicit(&allocator->occupied, &bitmap, new_bitmap, memory_order_release, memory_order_acquire)) { goto find_free_stack; } @@ -144,12 +181,13 @@ struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(struct SwiftN goto process_stack; + process_stack: stack_size = atomic_load_explicit(&stack->size, memory_order_acquire); valid_size = type == 0 ? (stack_size < allocator->chunk_item_amount && stack_size >= 0) : (stack_size <= allocator->chunk_item_amount && stack_size > 0); - if (valid_size) { + if(valid_size) { return stack; } else { free_stack_lock(stack, allocator); @@ -161,16 +199,23 @@ struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(struct SwiftN } struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const uint32_t chunk_item_amount) { - void* const allocated_memory = malloc(item_size * chunk_item_amount); - void* const pointers_memory = malloc(chunk_item_amount * sizeof(void*)); + void* allocated_memory; + void* pointers_memory; + struct SwiftNetMemoryAllocatorStack* first_stack; + struct SwiftNetMemoryAllocator new_allocator; + uint32_t i; + - if (unlikely(allocated_memory == NULL || pointers_memory == NULL)) { + allocated_memory = malloc(item_size * chunk_item_amount); + pointers_memory = malloc(chunk_item_amount * sizeof(void*)); + + if(unlikely(allocated_memory == NULL || pointers_memory == NULL)) { PRINT_ERROR("Failed to allocate memory"); exit(EXIT_FAILURE); } - struct SwiftNetMemoryAllocatorStack* const first_stack = malloc(sizeof(struct SwiftNetMemoryAllocatorStack)); - if (unlikely(first_stack == NULL)) { + first_stack = malloc(sizeof(struct SwiftNetMemoryAllocatorStack)); + if(unlikely(first_stack == NULL)) { PRINT_ERROR("Failed to allocate memory"); exit(EXIT_FAILURE); } @@ -180,7 +225,7 @@ struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const first_stack->size = chunk_item_amount; first_stack->index = 0; - struct SwiftNetMemoryAllocator new_allocator = (struct SwiftNetMemoryAllocator){ + new_allocator = (struct SwiftNetMemoryAllocator){ .item_size = item_size, .chunk_item_amount = chunk_item_amount, .stacks_allocated = 1 @@ -192,7 +237,7 @@ struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const atomic_store_explicit(&new_allocator.occupied, 0x00, memory_order_release); - for (uint32_t i = 0; i < chunk_item_amount; i++) { + for(i = 0; i < chunk_item_amount; i++) { (*((void **)pointers_memory + i) = (uint8_t*)allocated_memory + (i * item_size)); } @@ -207,40 +252,58 @@ struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const } static void create_new_stack(struct SwiftNetMemoryAllocator* const memory_allocator) { - uint8_t creating_unlocked = STACK_CREATING_UNLOCKED; + uint8_t creating_unlocked; + uint32_t chunk_item_amount; + uint32_t item_size; + void* allocated_memory; + void* allocated_memory_pointers; + struct SwiftNetMemoryAllocatorStack* stack; + uint16_t stacks_allocated; + uint32_t i; + + + creating_unlocked = STACK_CREATING_UNLOCKED; - while (!atomic_compare_exchange_strong_explicit(&memory_allocator->creating_stack, &creating_unlocked, STACK_CREATING_LOCKED, memory_order_release, memory_order_relaxed)) { - creating_unlocked = STACK_CREATING_UNLOCKED; + goto acquire_creating_lock; - usleep(100); - continue; +acquire_creating_lock: + if(atomic_compare_exchange_strong_explicit(&memory_allocator->creating_stack, &creating_unlocked, STACK_CREATING_LOCKED, memory_order_release, memory_order_relaxed)) { + goto allocate_stack; } - const uint32_t chunk_item_amount = memory_allocator->chunk_item_amount; - const uint32_t item_size = memory_allocator->item_size; + creating_unlocked = STACK_CREATING_UNLOCKED; - void* const allocated_memory = malloc(memory_allocator->item_size * chunk_item_amount); - void* const allocated_memory_pointers = malloc(chunk_item_amount * sizeof(void*)); - if (unlikely(allocated_memory == NULL || allocated_memory_pointers == NULL)) { + usleep(100); + + goto acquire_creating_lock; + + +allocate_stack: + chunk_item_amount = memory_allocator->chunk_item_amount; + item_size = memory_allocator->item_size; + + allocated_memory = malloc(memory_allocator->item_size * chunk_item_amount); + allocated_memory_pointers = malloc(chunk_item_amount * sizeof(void*)); + if(unlikely(allocated_memory == NULL || allocated_memory_pointers == NULL)) { PRINT_ERROR("Failed to allocate memory"); exit(EXIT_FAILURE); } - struct SwiftNetMemoryAllocatorStack* const stack = malloc(sizeof(struct SwiftNetMemoryAllocatorStack)); - if (unlikely(stack == NULL)) { + stack = malloc(sizeof(struct SwiftNetMemoryAllocatorStack)); + if(unlikely(stack == NULL)) { PRINT_ERROR("Failed to allocate memory"); exit(EXIT_FAILURE); } - const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); stack->pointers = allocated_memory_pointers; stack->data = allocated_memory; stack->size = chunk_item_amount; stack->index = stacks_allocated; - for (uint32_t i = 0; i < chunk_item_amount; i++) { + for(i = 0; i < chunk_item_amount; i++) { ((void **)allocated_memory_pointers)[i] = (uint8_t*)allocated_memory + (i * item_size); } @@ -257,21 +320,28 @@ static void create_new_stack(struct SwiftNetMemoryAllocator* const memory_alloca } void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator) { - struct SwiftNetMemoryAllocatorStack* const valid_stack = find_free_pointer_stack(memory_allocator, 1); + struct SwiftNetMemoryAllocatorStack* valid_stack; + uint32_t size; + void** ptr_to_data; + void* item_ptr; + void* res; + + + valid_stack = find_free_pointer_stack(memory_allocator, 1); - if (valid_stack == NULL) { + if(valid_stack == NULL) { create_new_stack(memory_allocator); - void* const res = allocator_allocate(memory_allocator); + res = allocator_allocate(memory_allocator); return res; } - const uint32_t size = atomic_fetch_sub(&valid_stack->size, 1);; + size = atomic_fetch_sub(&valid_stack->size, 1); - void** const ptr_to_data = ((void**)valid_stack->pointers) + size - 1; + ptr_to_data = ((void**)valid_stack->pointers) + size - 1; - void* item_ptr = *ptr_to_data; + item_ptr = *ptr_to_data; #ifdef SWIFT_NET_INTERNAL_TESTING set_memory_status(memory_allocator, item_ptr, 1); @@ -283,17 +353,22 @@ void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator) } void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location) { + struct SwiftNetMemoryAllocatorStack* free_stack; + uint32_t size; + bool already_free; + + #ifdef SWIFT_NET_INTERNAL_TESTING - const bool already_free = is_already_free(memory_allocator, memory_location); + already_free = is_already_free(memory_allocator, memory_location); - if (already_free == true) { + if(already_free == true) { PRINT_ERROR("Pointer %p has already been freed", memory_location); exit(EXIT_FAILURE); } #endif - struct SwiftNetMemoryAllocatorStack* const free_stack = find_free_pointer_stack(memory_allocator, 0); - if (free_stack == NULL) { + free_stack = find_free_pointer_stack(memory_allocator, 0); + if(free_stack == NULL) { create_new_stack(memory_allocator); allocator_free(memory_allocator, memory_location); @@ -301,7 +376,7 @@ void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void return; } - const uint32_t size = atomic_fetch_add(&free_stack->size, 1); + size = atomic_fetch_add(&free_stack->size, 1); ((void**)free_stack->pointers)[size] = memory_location; @@ -317,35 +392,53 @@ void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator , const bool disable_internal_check #endif ) { - const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + uint16_t stacks_allocated; + uint16_t stack_index; + + + stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + + for(stack_index = 0; stack_index < stacks_allocated; stack_index++) { + struct SwiftNetMemoryAllocatorStack* current_stack; - for (uint16_t stack_index = 0; stack_index < stacks_allocated; stack_index++) { - struct SwiftNetMemoryAllocatorStack* const current_stack = atomic_load_explicit(&memory_allocator->stacks[stack_index], memory_order_acquire); + + current_stack = atomic_load_explicit(&memory_allocator->stacks[stack_index], memory_order_acquire); free(current_stack->data); free(current_stack->pointers); #ifdef SWIFT_NET_INTERNAL_TESTING if(!disable_internal_check) { + uint32_t total_items; + uint32_t bytes; + uint32_t byte; + uint8_t bit; + uint32_t idx; + bool allocated; + uint8_t mask; + + lock_ptr_status(current_stack); - const uint32_t total_items = memory_allocator->chunk_item_amount; - const uint32_t bytes = (total_items / 8) + 1; + total_items = memory_allocator->chunk_item_amount; + bytes = (total_items / 8) + 1; - for (uint32_t byte = 0; byte < bytes; byte++) { - uint8_t mask = current_stack->ptr_status[byte]; + for(byte = 0; byte < bytes; byte++) { + mask = current_stack->ptr_status[byte]; - if (mask == 0x00) { + if(mask == 0x00) { continue; } - for (uint8_t bit = 0; bit < 8; bit++) { - uint32_t idx = byte * 8 + bit; - if (idx >= total_items) break; + for(bit = 0; bit < 8; bit++) { + idx = byte * 8 + bit; + if(idx >= total_items) { + break; + } - bool allocated = (mask & (1u << bit)) != 0; + allocated = (mask & (1u << bit)) != 0; - if (allocated) { + if(allocated) { items_leaked++; bytes_leaked += memory_allocator->item_size; } @@ -360,4 +453,4 @@ void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator free(current_stack); } -} +} \ No newline at end of file diff --git a/src/internal/datatype_hashmap.c b/src/internal/datatype_hashmap.c index ab391b2..db54969 100644 --- a/src/internal/datatype_hashmap.c +++ b/src/internal/datatype_hashmap.c @@ -12,10 +12,13 @@ uint64_t seed; // This hashing function is not really as random as I would want it to be, but it's performant. // Can cause some collisions. static inline uint64_t hash64(const uint8_t* const data, const uint32_t data_size) { - // Manual SIMD optimization would be preffered in the future. - uint64_t res = 0; + uint64_t res; + uint32_t i; - for (uint32_t i = 0; i < data_size; i++) { + + res = 0; + + for(i = 0; i < data_size; i++) { res = (res ^ *(data + i)) * seed; } @@ -30,11 +33,15 @@ static inline uint32_t get_key(const void* const key_data, const uint32_t data_s // Must rehash every key. Takes many cpu cycles. static inline void hashmap_resize(struct SwiftNetHashMap* const hashmap) { - // Multiply value should be changed by -D flag in the future. - // For now just literal - const uint32_t old_capacity = hashmap->capacity; - const uint32_t new_capacity = hashmap->capacity * 4; - struct SwiftNetHashMapItem* const old_data_location = hashmap->items; + uint32_t old_capacity; + uint32_t new_capacity; + struct SwiftNetHashMapItem* old_data_location; + uint32_t i; + + + old_capacity = hashmap->capacity; + new_capacity = hashmap->capacity * 4; + old_data_location = hashmap->items; hashmap->capacity = new_capacity; @@ -45,32 +52,42 @@ static inline void hashmap_resize(struct SwiftNetHashMap* const hashmap) { hashmap->item_occupation = calloc(sizeof(uint32_t), (new_capacity + 31) / 32); - for (uint32_t i = 0; i < old_capacity; i++) { - struct SwiftNetHashMapItem* const current_hashmap_item = old_data_location + i; - if (current_hashmap_item->value == NULL) { + for(i = 0; i < old_capacity; i++) { + struct SwiftNetHashMapItem* current_hashmap_item; + struct SwiftNetHashMapItem* current_linked_item; + void* key_original_data; + uint32_t key_original_data_size; + uint64_t new_key; + struct SwiftNetHashMapItem* new_mem_hashmap_item; + uint32_t byte; + uint8_t bit; + struct SwiftNetHashMapItem* hashmap_item_new_allocation; + + + current_hashmap_item = old_data_location + i; + if(current_hashmap_item->value == NULL) { continue; } - for (struct SwiftNetHashMapItem* current_linked_item = current_hashmap_item; current_linked_item != NULL; current_linked_item = current_linked_item->next) { - void* const key_original_data = current_linked_item->key_original_data; - const uint32_t key_original_data_size = current_linked_item->key_original_data_size; + for(current_linked_item = current_hashmap_item; current_linked_item != NULL; current_linked_item = current_linked_item->next) { + key_original_data = current_linked_item->key_original_data; + key_original_data_size = current_linked_item->key_original_data_size; - const uint64_t new_key = get_key(key_original_data, key_original_data_size, hashmap); + new_key = get_key(key_original_data, key_original_data_size, hashmap); - struct SwiftNetHashMapItem* new_mem_hashmap_item = hashmap->items + new_key; + new_mem_hashmap_item = hashmap->items + new_key; - const uint32_t byte = new_key / 32; - const uint8_t bit = new_key % 32; + byte = new_key / 32; + bit = new_key % 32; *(hashmap->item_occupation + byte) |= 1 << bit; - if (new_mem_hashmap_item->value != NULL) { - // Get last item - while (new_mem_hashmap_item->next != NULL) { + if(new_mem_hashmap_item->value != NULL) { + while(new_mem_hashmap_item->next != NULL) { new_mem_hashmap_item = new_mem_hashmap_item->next; } - struct SwiftNetHashMapItem* const hashmap_item_new_allocation = allocator_allocate(&hashmap_item_memory_allocator); + hashmap_item_new_allocation = allocator_allocate(&hashmap_item_memory_allocator); *hashmap_item_new_allocation = (struct SwiftNetHashMapItem){ .key_original_data = key_original_data, .key_original_data_size = key_original_data_size, @@ -93,7 +110,7 @@ static inline void hashmap_resize(struct SwiftNetHashMap* const hashmap) { free(old_data_location); } -struct SwiftNetHashMap hashmap_create(struct SwiftNetMemoryAllocator* key_memory_allocator) { +struct SwiftNetHashMap hashmap_create(struct SwiftNetMemoryAllocator* const key_memory_allocator) { return (struct SwiftNetHashMap){ .capacity = 0x40 * SWIFT_NET_MEMORY_USAGE, .items = calloc(sizeof(struct SwiftNetHashMapItem), 0x40 * SWIFT_NET_MEMORY_USAGE), @@ -104,31 +121,49 @@ struct SwiftNetHashMap hashmap_create(struct SwiftNetMemoryAllocator* key_memory } void* hashmap_get(const void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* const hashmap) { - const uint64_t key = get_key(key_data, data_size, hashmap); + uint64_t key; + struct SwiftNetHashMapItem* current_item; - struct SwiftNetHashMapItem* current_item = hashmap->items + key; - while (current_item != NULL) { - if (data_size == current_item->key_original_data_size && memcmp(current_item->key_original_data, key_data, data_size) == 0) { - return current_item->value; - } + key = get_key(key_data, data_size, hashmap); - current_item = current_item->next; + current_item = hashmap->items + key; - continue; + goto loop; + +loop: + if(current_item == NULL) { + goto exit; } + if(data_size == current_item->key_original_data_size && memcmp(current_item->key_original_data, key_data, data_size) == 0) { + return current_item->value; + } + + current_item = current_item->next; + + goto loop; + + +exit: return NULL; } void hashmap_insert(void* const key_data, const uint32_t data_size, void* const value, struct SwiftNetHashMap* const hashmap) { - const uint64_t key = get_key(key_data, data_size, hashmap); + uint64_t key; + struct SwiftNetHashMapItem* current_target_item; + struct SwiftNetHashMapItem* new_item; + uint32_t byte; + uint8_t bit; - struct SwiftNetHashMapItem* current_target_item = hashmap->items + key; - while (current_target_item->value != NULL) { - if (current_target_item->next == NULL) { - struct SwiftNetHashMapItem* const new_item = allocator_allocate(&hashmap_item_memory_allocator); + key = get_key(key_data, data_size, hashmap); + + current_target_item = hashmap->items + key; + + while(current_target_item->value != NULL) { + if(current_target_item->next == NULL) { + new_item = allocator_allocate(&hashmap_item_memory_allocator); current_target_item->next = new_item; @@ -149,54 +184,70 @@ void hashmap_insert(void* const key_data, const uint32_t data_size, void* const hashmap->size++; - const uint32_t byte = key / 32; - const uint8_t bit = key % 32; + byte = key / 32; + bit = key % 32; *(hashmap->item_occupation + byte) |= 0 << bit; - if (hashmap->size >= hashmap->capacity) { + if(hashmap->size >= hashmap->capacity) { hashmap_resize(hashmap); } } -void free_hashmap_item_key(struct SwiftNetHashMap* const restrict hashmap, struct SwiftNetHashMapItem* const restrict hashmap_item) { - if (hashmap->key_memory_allocator == NULL) { +void free_hashmap_item_key(struct SwiftNetHashMap* const hashmap, struct SwiftNetHashMapItem* const hashmap_item) { + if(hashmap->key_memory_allocator == NULL) { free(hashmap_item->key_original_data); } else { allocator_free(hashmap->key_memory_allocator, hashmap_item->key_original_data); } } -void hashmap_remove(void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* const restrict hashmap) { - const uint64_t key = get_key(key_data, data_size, hashmap); +void hashmap_remove(void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* const hashmap) { + uint64_t key; + struct SwiftNetHashMapItem* previous_target_item; + struct SwiftNetHashMapItem* current_target_item; + uint32_t byte; + uint8_t bit; + struct SwiftNetHashMapItem* next; + + + key = get_key(key_data, data_size, hashmap); - struct SwiftNetHashMapItem* previous_target_item = hashmap->items + key; - struct SwiftNetHashMapItem* current_target_item = hashmap->items + key; + previous_target_item = hashmap->items + key; + current_target_item = hashmap->items + key; - if (current_target_item->next == NULL) { - const uint32_t byte = key / 32; - const uint8_t bit = key % 32; + if(current_target_item->next == NULL) { + byte = key / 32; + bit = key % 32; *(hashmap->item_occupation + byte) &= ~(0 << bit); } - while (current_target_item != NULL) { - if (data_size == current_target_item->key_original_data_size && memcmp(current_target_item->key_original_data, key_data, data_size) == 0) { - break; - } + goto find_item; - previous_target_item = current_target_item; - current_target_item = current_target_item->next; - continue; +find_item: + if(current_target_item == NULL) { + goto exit; + } + + if(data_size == current_target_item->key_original_data_size && memcmp(current_target_item->key_original_data, key_data, data_size) == 0) { + goto remove_item; } - if (current_target_item == previous_target_item) { + previous_target_item = current_target_item; + current_target_item = current_target_item->next; + + goto find_item; + + +remove_item: + if(current_target_item == previous_target_item) { current_target_item->value = NULL; - struct SwiftNetHashMapItem* const next = current_target_item->next; + next = current_target_item->next; - if (next != NULL) { + if(next != NULL) { free_hashmap_item_key(hashmap, current_target_item); memcpy(current_target_item, next, sizeof(struct SwiftNetHashMapItem)); @@ -218,28 +269,37 @@ void hashmap_remove(void* const key_data, const uint32_t data_size, struct Swift } hashmap->size--; + + +exit: + return; } void hashmap_destroy(struct SwiftNetHashMap* const hashmap) { - for (uint32_t i = 0; i < hashmap->capacity; i++) { - struct SwiftNetHashMapItem* const current_item = hashmap->items + i; - if (current_item->value == NULL) { + uint32_t i; + + + for(i = 0; i < hashmap->capacity; i++) { + struct SwiftNetHashMapItem* current_item; + struct SwiftNetHashMapItem* current_linked_item; + struct SwiftNetHashMapItem* next_item; + + + current_item = hashmap->items + i; + if(current_item->value == NULL) { continue; } - // Dealloc all ->next - for (struct SwiftNetHashMapItem* current_linked_item = current_item->next; current_linked_item != NULL;) { - struct SwiftNetHashMapItem* const next_item = current_linked_item->next; + for(current_linked_item = current_item->next; current_linked_item != NULL;) { + next_item = current_linked_item->next; free_hashmap_item_key(hashmap, current_linked_item); allocator_free(&hashmap_item_memory_allocator, current_linked_item); current_linked_item = next_item; - - continue; } } free(hashmap->items); -} +} \ No newline at end of file diff --git a/src/internal/datatype_vector.c b/src/internal/datatype_vector.c index dc0da36..e9d70a6 100644 --- a/src/internal/datatype_vector.c +++ b/src/internal/datatype_vector.c @@ -3,20 +3,21 @@ #include struct SwiftNetVector vector_create(const uint32_t starting_amount) { - void* const data_ptr = malloc(sizeof(void*) * starting_amount); - if (unlikely(data_ptr == NULL)) { + void* data_ptr; + + + data_ptr = malloc(sizeof(void*) * starting_amount); + if(unlikely(data_ptr == NULL)) { PRINT_ERROR("Failed to malloc"); exit(EXIT_FAILURE); } - const struct SwiftNetVector new_vector = { + return (struct SwiftNetVector){ .size = 0, .capacity = starting_amount, .data = data_ptr, .locked = 0 }; - - return new_vector; } void vector_destroy(struct SwiftNetVector* const vector) { @@ -24,16 +25,22 @@ void vector_destroy(struct SwiftNetVector* const vector) { } void vector_push(struct SwiftNetVector* const vector, void* const data) { - const uint32_t size = vector->size; - const uint32_t capacity = vector->capacity; + uint32_t size; + uint32_t capacity; + uint32_t new_capacity; + void** new_data_ptr; + - if (size == capacity) { - const uint32_t new_capacity = capacity * 2; + size = vector->size; + capacity = vector->capacity; + + if(size == capacity) { + new_capacity = capacity * 2; vector->capacity = new_capacity; - void** const new_data_ptr = realloc(vector->data, sizeof(void*) * new_capacity); - if (unlikely(new_data_ptr == NULL)) { + new_data_ptr = realloc(vector->data, sizeof(void*) * new_capacity); + if(unlikely(new_data_ptr == NULL)) { PRINT_ERROR("Failed to malloc"); exit(EXIT_FAILURE); } @@ -47,7 +54,7 @@ void vector_push(struct SwiftNetVector* const vector, void* const data) { } void vector_remove(struct SwiftNetVector* const vector, const uint32_t index) { - if (index < vector->size - 1) { + if(index < vector->size - 1) { memcpy(vector->data + index, vector->data + vector->size - 1, sizeof(void*)); } @@ -55,7 +62,10 @@ void vector_remove(struct SwiftNetVector* const vector, const uint32_t index) { } void* vector_get(struct SwiftNetVector* const vector, const uint32_t index) { - void** const data_ptr = ((void**)vector->data) + index; + void** data_ptr; + + + data_ptr = ((void**)vector->data) + index; return *data_ptr; -} +} \ No newline at end of file diff --git a/src/internal/get_default_interface_and_mac.c b/src/internal/get_default_interface_and_mac.c index c5690af..086fcbf 100644 --- a/src/internal/get_default_interface_and_mac.c +++ b/src/internal/get_default_interface_and_mac.c @@ -17,47 +17,58 @@ #include #endif -int get_default_interface_and_mac(char* restrict interface_name, uint32_t interface_name_length, uint8_t mac_out[6], int sockfd) { +int get_default_interface_and_mac(char* restrict interface_name, const uint32_t interface_name_length, uint8_t* restrict mac_out, const int sockfd) { struct sockaddr_in local_addr; - socklen_t addr_len = sizeof(local_addr); + socklen_t addr_len; + char local_ip[INET_ADDRSTRLEN]; + struct ifaddrs* ifaddr; + struct ifaddrs* ifa; + struct ifaddrs* match; + int mac_found; + - if (getsockname(sockfd, (struct sockaddr *)&local_addr, &addr_len) < 0) { + addr_len = sizeof(local_addr); + + if(getsockname(sockfd, (struct sockaddr *)&local_addr, &addr_len) < 0) { perror("getsockname"); return -1; } - char local_ip[INET_ADDRSTRLEN]; - if (!inet_ntop(AF_INET, &local_addr.sin_addr, local_ip, sizeof(local_ip))) { + if(!inet_ntop(AF_INET, &local_addr.sin_addr, local_ip, sizeof(local_ip))) { perror("inet_ntop"); return -1; } - struct ifaddrs *ifaddr, *ifa; - if (getifaddrs(&ifaddr) == -1) { + if(getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); return -1; } - struct ifaddrs *match = NULL; + match = NULL; - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) continue; + for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + char iface_ip[INET_ADDRSTRLEN]; + struct sockaddr_in* sin; - if (ifa->ifa_addr->sa_family == AF_INET) { - char iface_ip[INET_ADDRSTRLEN]; - struct sockaddr_in *sin = (struct sockaddr_in *)ifa->ifa_addr; + if(!ifa->ifa_addr) { + continue; + } + + if(ifa->ifa_addr->sa_family == AF_INET) { + sin = (struct sockaddr_in *)ifa->ifa_addr; - if (!inet_ntop(AF_INET, &sin->sin_addr, iface_ip, sizeof(iface_ip))) + if(!inet_ntop(AF_INET, &sin->sin_addr, iface_ip, sizeof(iface_ip))) { continue; + } - if (strcmp(local_ip, iface_ip) == 0) { + if(strcmp(local_ip, iface_ip) == 0) { match = ifa; break; } } } - if (!match) { + if(!match) { PRINT_ERROR("No matching interface found for IP %s", local_ip); freeifaddrs(ifaddr); return -1; @@ -66,25 +77,36 @@ int get_default_interface_and_mac(char* restrict interface_name, uint32_t interf strncpy(interface_name, match->ifa_name, interface_name_length - 1); interface_name[interface_name_length - 1] = '\0'; - int mac_found = 0; + mac_found = 0; - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { - if (!ifa->ifa_addr) continue; - if (strcmp(ifa->ifa_name, interface_name) != 0) continue; + for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if(!ifa->ifa_addr) { + continue; + } + + if(strcmp(ifa->ifa_name, interface_name) != 0) { + continue; + } #ifdef __linux__ - if (ifa->ifa_addr->sa_family == AF_PACKET) { - struct sockaddr_ll *s = (struct sockaddr_ll *)ifa->ifa_addr; - if (s->sll_halen == 6) { + if(ifa->ifa_addr->sa_family == AF_PACKET) { + struct sockaddr_ll* s; + + + s = (struct sockaddr_ll *)ifa->ifa_addr; + if(s->sll_halen == 6) { memcpy(mac_out, s->sll_addr, 6); mac_found = 1; break; } } #elif defined(__APPLE__) - if (ifa->ifa_addr->sa_family == AF_LINK) { - struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; - if (sdl->sdl_alen == 6) { + if(ifa->ifa_addr->sa_family == AF_LINK) { + struct sockaddr_dl* sdl; + + + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + if(sdl->sdl_alen == 6) { memcpy(mac_out, LLADDR(sdl), 6); mac_found = 1; break; @@ -95,10 +117,10 @@ int get_default_interface_and_mac(char* restrict interface_name, uint32_t interf freeifaddrs(ifaddr); - if (!mac_found) { + if(!mac_found) { PRINT_ERROR("No MAC address found for interface %s", interface_name); return -1; } return 0; -} +} \ No newline at end of file diff --git a/src/internal/get_mtu.c b/src/internal/get_mtu.c index 2883521..5198bba 100644 --- a/src/internal/get_mtu.c +++ b/src/internal/get_mtu.c @@ -9,17 +9,17 @@ #include #include -const uint32_t get_mtu(const char* const restrict interface, const int sockfd) { +const uint32_t get_mtu(const char* restrict const interface, const int sockfd) { struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, interface, IFNAMSIZ - 1); - if (ioctl(sockfd, SIOCGIFMTU, &ifr) < 0) { + if(ioctl(sockfd, SIOCGIFMTU, &ifr) < 0) { PRINT_ERROR("ioctl failed"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return ifr.ifr_mtu; -} - +} \ No newline at end of file diff --git a/src/internal/internal.h b/src/internal/internal.h index f22b35d..f135bab 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -113,19 +113,36 @@ enum RequestLostPacketsReturnType { #define MIN(one, two) (one > two ? two : one) -static inline uint32_t crc32(uint8_t* data, uint32_t length) { +static inline void* swiftnet_allocate_memory(const uint32_t size) { + // Future + return NULL; +} + +static inline void swiftnet_free_memory(const uint32_t size, const void* restrict const ptr) { + // Future + return; +} + +static inline void swiftnet_reallocate_memory(const uint32_t new_size, const void* restrict const ptr) { + // Future + return; +} + +static inline uint32_t crc32(const uint8_t* const data, const uint32_t length) { + const uint8_t* ptr = data; + uint32_t remaining = length; uint32_t crc = 0xFFFFFFFF; - while (length >= 8) { - crc = __crc32d(crc, *(const uint64_t*)data); - data += 8; - length -= 8; + while (remaining >= 8) { + crc = __crc32d(crc, *(const uint64_t*)ptr); + ptr += 8; + remaining -= 8; } - while (length > 0) { - crc = __crc32b(crc, *data); - data++; - length--; + while (remaining > 0) { + crc = __crc32b(crc, *ptr); + ptr++; + remaining--; } return ~crc; @@ -173,7 +190,7 @@ extern _Atomic bool swiftnet_closing; extern void* memory_cleanup_background_service(); -extern int get_default_interface_and_mac(char *restrict interface_name, uint32_t interface_name_length, uint8_t mac_out[6], int sockfd); +extern int get_default_interface_and_mac(char* restrict interface_name, const uint32_t interface_name_length, uint8_t* restrict mac_out, const int sockfd); extern const uint32_t get_mtu(const char* restrict const interface, const int sockfd); extern int get_bpf_device(); extern int bind_bpf_to_interface(const int bpf, const bool loopback); @@ -188,10 +205,10 @@ extern void* execute_packet_callback_server(void* const void_server); extern struct in_addr private_ip_address; extern uint8_t mac_address[6]; extern char default_network_interface[SIZEOF_FIELD(struct ifreq, ifr_name)]; -extern pcap_t* swiftnet_pcap_open(const char* interface); -extern int swiftnet_pcap_send(pcap_t *pcap, const uint8_t *data, int len); +extern pcap_t* swiftnet_pcap_open(const char* restrict const interface); +extern int swiftnet_pcap_send(pcap_t* const pcap, const uint8_t* restrict const data, const int len); -extern void* check_existing_listener(const char* interface_name, void* const connection, const enum ConnectionType connection_type, const bool loopback); +extern void* check_existing_listener(const char* restrict const interface_name, void* const connection, const enum ConnectionType connection_type, const bool loopback); #ifdef SWIFT_NET_INTERNAL_TESTING extern uint32_t bytes_leaked; @@ -205,14 +222,19 @@ static inline bool check_debug_flag(const SwiftNetDebugFlags flag) { return (debugger.flags & flag) != 0; } -static inline void send_debug_message(const char* message, ...) { +static inline void send_debug_message(const char* restrict const message, ...) { va_list args; + char* prefix; + uint32_t prefix_length; + uint32_t message_length; + + va_start(args, message); - char* prefix = "[DEBUG] "; + prefix = "[DEBUG] "; - const uint32_t prefix_length = strlen(prefix); - const uint32_t message_length = strlen(message); + prefix_length = strlen(prefix); + message_length = strlen(message); char full_message[prefix_length + message_length + 1]; @@ -255,7 +277,7 @@ extern struct SwiftNetMemoryAllocator client_connection_memory_allocator; extern struct SwiftNetMemoryAllocator listener_memory_allocator; extern struct SwiftNetMemoryAllocator hashmap_item_memory_allocator; -extern void* interface_start_listening(void* listener_void); +extern void* interface_start_listening(void* const listener_void); extern void* vector_get(struct SwiftNetVector* const vector, const uint32_t index); extern void vector_remove(struct SwiftNetVector* const vector, const uint32_t index); @@ -263,14 +285,14 @@ extern void vector_push(struct SwiftNetVector* const vector, void* const data); extern void vector_destroy(struct SwiftNetVector* const vector); extern struct SwiftNetVector vector_create(const uint32_t starting_amount); -extern struct SwiftNetHashMap hashmap_create(struct SwiftNetMemoryAllocator* key_memory_allocator); -extern void hashmap_insert(void* const key_data, const uint32_t data_size, void* const value, struct SwiftNetHashMap* restrict const hashmap); +extern struct SwiftNetHashMap hashmap_create(struct SwiftNetMemoryAllocator* const key_memory_allocator); +extern void hashmap_insert(void* const key_data, const uint32_t data_size, void* const value, struct SwiftNetHashMap* const hashmap); extern void hashmap_remove(void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* const hashmap); extern void hashmap_destroy(struct SwiftNetHashMap* const hashmap); -extern void* hashmap_get(const void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* restrict const hashmap); +extern void* hashmap_get(const void* const key_data, const uint32_t data_size, struct SwiftNetHashMap* const hashmap); -extern void* server_start_pcap(void* server_void); -extern void* client_start_pcap(void* client_void); +extern void* server_start_pcap(void* const server_void); +extern void* client_start_pcap(void* const client_void); #ifdef SWIFT_NET_REQUESTS struct RequestSent { @@ -316,19 +338,22 @@ static inline struct SwiftNetPacketInfo construct_packet_info(const uint32_t pac }; } -static struct ip construct_ip_header(struct in_addr destination_addr, const uint32_t packet_size, const uint16_t packet_id) { - struct ip ip_header = { - .ip_v = 4, // Version (ipv4) - .ip_hl = 5, // Header length - .ip_tos = 0, // Type of service - .ip_p = PROT_NUMBER, // Protocol - .ip_len = htons(packet_size), // Chunk size - .ip_id = htons(packet_id), // Packet id - .ip_off = htons(0), // Not used - .ip_ttl = 64,// Time to live - .ip_sum = htons(0), // not used!! - .ip_src = private_ip_address, // Source ip - .ip_dst = destination_addr // Destination ip +static struct ip construct_ip_header(const struct in_addr destination_addr, const uint32_t packet_size, const uint16_t packet_id) { + struct ip ip_header; + + + ip_header = (struct ip){ + .ip_v = 4, + .ip_hl = 5, + .ip_tos = 0, + .ip_p = PROT_NUMBER, + .ip_len = htons(packet_size), + .ip_id = htons(packet_id), + .ip_off = htons(0), + .ip_ttl = 64, + .ip_sum = htons(0), + .ip_src = private_ip_address, + .ip_dst = destination_addr }; return ip_header; diff --git a/src/internal/pcap_open.c b/src/internal/pcap_open.c index bde41e3..af61122 100644 --- a/src/internal/pcap_open.c +++ b/src/internal/pcap_open.c @@ -1,10 +1,17 @@ #include "internal.h" #include -pcap_t* swiftnet_pcap_open(const char* interface) { +pcap_t* swiftnet_pcap_open(const char* restrict const interface) { char errbuf[PCAP_ERRBUF_SIZE]; + pcap_t* p; + struct bpf_program fp; + char filter_exp[] = "ip proto 253"; + bpf_u_int32 net; + + + net = 0; - pcap_t *p = pcap_open_live( + p = pcap_open_live( interface, 65535, 0, @@ -12,23 +19,19 @@ pcap_t* swiftnet_pcap_open(const char* interface) { errbuf ); - if (!p) { + if(!p) { PRINT_ERROR("pcap_open_live failed: %s", errbuf); return NULL; } - struct bpf_program fp; - char filter_exp[] = "ip proto 253"; - bpf_u_int32 net = 0; - - if (pcap_compile(p, &fp, filter_exp, 0, net) == -1) { + if(pcap_compile(p, &fp, filter_exp, 0, net) == -1) { PRINT_ERROR("Couldn't parse filter %s: %s", filter_exp, pcap_geterr(p)); exit(EXIT_FAILURE); } - if (pcap_setfilter(p, &fp) != 0) { + if(pcap_setfilter(p, &fp) != 0) { PRINT_ERROR("Unable to set filter: %s", pcap_geterr(p)); } return p; -} +} \ No newline at end of file diff --git a/src/internal/pcap_send.c b/src/internal/pcap_send.c index 4525fa3..831c281 100644 --- a/src/internal/pcap_send.c +++ b/src/internal/pcap_send.c @@ -2,11 +2,14 @@ #include #include -int swiftnet_pcap_send(pcap_t *pcap, const u_char *data, int len) { - int ret = pcap_inject(pcap, data, len); +int swiftnet_pcap_send(pcap_t* const pcap, const uint8_t* restrict const data, const int len) { + int ret; - if (ret == -1) { - if (errno == ENOBUFS) { + + ret = pcap_inject(pcap, data, len); + + if(ret == -1) { + if(errno == ENOBUFS) { return -2; } diff --git a/src/make_request.c b/src/make_request.c index 336b49a..ea57759 100644 --- a/src/make_request.c +++ b/src/make_request.c @@ -8,7 +8,7 @@ #ifdef SWIFT_NET_REQUESTS -static inline void delete_request_sent(struct RequestSent* request_sent) { +static inline void delete_request_sent(struct RequestSent* restrict const request_sent) { LOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock) hashmap_remove(&request_sent->packet_id, sizeof(uint16_t), &requests_sent); @@ -69,7 +69,7 @@ struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetCli goto check_response; } -struct SwiftNetServerPacketData* swiftnet_server_make_request(struct SwiftNetServer* const server, struct SwiftNetPacketBuffer* const packet, const struct SwiftNetClientAddrData addr_data, const uint32_t timeout_ms) { +struct SwiftNetServerPacketData* swiftnet_server_make_request(struct SwiftNetServer* const server, struct SwiftNetPacketBuffer* restrict const packet, const struct SwiftNetClientAddrData addr_data, const uint32_t timeout_ms) { struct RequestSent* request_sent; uint32_t packet_length; struct SwiftNetPortInfo port_info; diff --git a/src/make_response.c b/src/make_response.c index 4915a2a..cc903be 100644 --- a/src/make_response.c +++ b/src/make_response.c @@ -3,13 +3,13 @@ #ifdef SWIFT_NET_REQUESTS -void swiftnet_client_make_response(struct SwiftNetClientConnection* const client, struct SwiftNetClientPacketData* const packet_data, struct SwiftNetPacketBuffer* const buffer) { +void swiftnet_client_make_response(struct SwiftNetClientConnection* const client, struct SwiftNetClientPacketData* const packet_data, struct SwiftNetPacketBuffer* restrict const buffer) { const uint32_t packet_length = buffer->packet_append_pointer - buffer->packet_data_start; swiftnet_send_packet(client, client->maximum_transmission_unit, client->port_info, buffer, packet_length, &client->server_addr, &client->packets_sending, &client->packets_sending_memory_allocator, client->pcap, client->eth_header, client->loopback, client->addr_type, client->prepend_size, NULL, true, packet_data->metadata.packet_id); } -void swiftnet_server_make_response(struct SwiftNetServer* const server, struct SwiftNetServerPacketData* const packet_data, struct SwiftNetPacketBuffer* const buffer) { +void swiftnet_server_make_response(struct SwiftNetServer* const server, struct SwiftNetServerPacketData* const packet_data, struct SwiftNetPacketBuffer* restrict const buffer) { const uint32_t packet_length = buffer->packet_append_pointer - buffer->packet_data_start; const struct SwiftNetPortInfo port_info = {.source_port = server->server_port, .destination_port = packet_data->metadata.port_info.source_port}; diff --git a/src/memory_cleanup_background_service.c b/src/memory_cleanup_background_service.c index d62b483..ca4a2e2 100644 --- a/src/memory_cleanup_background_service.c +++ b/src/memory_cleanup_background_service.c @@ -5,7 +5,7 @@ #include #include -static inline void cleanup_packets_completed(struct SwiftNetHashMap* packets_completed, struct SwiftNetMemoryAllocator* const packets_completed_allocator) { +static inline void cleanup_packets_completed(struct SwiftNetHashMap* const packets_completed, struct SwiftNetMemoryAllocator* const packets_completed_allocator) { LOCK_ATOMIC_DATA_TYPE(&packets_completed->atomic_lock); LOOP_HASHMAP(packets_completed, diff --git a/src/packet_buffer.c b/src/packet_buffer.c index 92aea2f..7984e1e 100644 --- a/src/packet_buffer.c +++ b/src/packet_buffer.c @@ -43,7 +43,7 @@ void swiftnet_resize_packet_buffer(uint32_t new_buffer_size, struct SwiftNetPack }; } -void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* const packet_buffer, void* restrict const data, const uint32_t data_size) { +void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* restrict const packet_buffer, void* restrict const data, const uint32_t data_size) { memcpy(packet_buffer->packet_data_start + byte_offset, data, data_size); } diff --git a/src/process_packets.c b/src/process_packets.c index 46b4664..7f04e7d 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -17,7 +17,7 @@ #include #include -static inline bool is_private_ip(struct in_addr ip) { +static inline bool is_private_ip(const struct in_addr ip) { in_addr_t addr = htonl(ip.s_addr); uint8_t octet1 = (addr >> 24) & 0xFF; uint8_t octet2 = (addr >> 16) & 0xFF; @@ -28,7 +28,7 @@ static inline bool is_private_ip(struct in_addr ip) { } // Returns an array of 4 byte uint32_t, that contain indexes of lost chunks -static inline const uint32_t return_lost_chunk_indexes(const uint8_t* restrict const chunks_received, const uint32_t chunk_amount, const uint32_t buffer_size, uint32_t* restrict const buffer) { +static inline uint32_t return_lost_chunk_indexes(const uint8_t* restrict const chunks_received, const uint32_t chunk_amount, const uint32_t buffer_size, uint32_t* restrict const buffer) { uint32_t byte = 0; uint32_t offset = 0; @@ -72,10 +72,10 @@ static inline const uint32_t return_lost_chunk_indexes(const uint8_t* restrict c return offset; } -static inline void packet_completed(const uint16_t packet_id, const uint16_t source_port, struct SwiftNetHashMap* restrict const packets_completed_history, struct SwiftNetMemoryAllocator* restrict const packets_completed_history_memory_allocator) { - struct SwiftNetPacketCompleted* restrict new_packet_completed; - struct PacketCompletedKey* restrict key; - uint16_t* restrict heap_key_data_location; +static inline void packet_completed(const uint16_t packet_id, const uint16_t source_port, struct SwiftNetHashMap* const packets_completed_history, struct SwiftNetMemoryAllocator* const packets_completed_history_memory_allocator) { + struct SwiftNetPacketCompleted* new_packet_completed; + struct PacketCompletedKey* key; + uint16_t* heap_key_data_location; new_packet_completed = allocator_allocate(packets_completed_history_memory_allocator); @@ -111,7 +111,7 @@ static inline bool check_packet_already_completed(const uint16_t packet_id, cons return item != NULL; } -static inline struct SwiftNetPendingMessage* const get_pending_message(struct SwiftNetHashMap* const pending_messages, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { +static inline struct SwiftNetPendingMessage* get_pending_message(struct SwiftNetHashMap* const pending_messages, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { struct PendingMessagesKey key; struct SwiftNetPendingMessage* pending_message; @@ -151,7 +151,7 @@ static inline void insert_callback_queue_node(struct PacketCallbackQueueNode* re #ifdef SWIFT_NET_REQUESTS -static inline void handle_request_response(uint16_t packet_id, struct SwiftNetPendingMessage* restrict const pending_message, void* restrict const packet_data, struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, const enum ConnectionType connection_type, const bool loopback, const uint16_t source_port) { +static inline void handle_request_response(uint16_t packet_id, const struct SwiftNetPendingMessage* restrict const pending_message, void* restrict const packet_data, struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, const enum ConnectionType connection_type, const bool loopback, const uint16_t source_port) { struct RequestSent* request_sent; LOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); @@ -187,7 +187,7 @@ static inline void handle_request_response(uint16_t packet_id, struct SwiftNetPe #endif static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* restrict const pending_message, const uint16_t packet_id, pthread_mutex_t* const execute_callback_mtx, pthread_cond_t* const execute_callback_cond) { - struct PacketCallbackQueueNode* restrict node; + struct PacketCallbackQueueNode* node; node = allocator_allocate(&packet_callback_queue_node_memory_allocator); @@ -202,23 +202,28 @@ static inline void pass_callback_execution(void* const packet_data, struct Packe pthread_mutex_unlock(execute_callback_mtx); } -static inline bool chunk_already_received(uint8_t* const chunks_received, const uint32_t index) { +static inline bool chunk_already_received(const uint8_t* restrict const chunks_received, const uint32_t index) { return (chunks_received[index / 8] & (1U << (index % 8))) != 0; } -static inline void chunk_received(uint8_t* const chunks_received, const uint32_t index) { - const uint32_t byte = index / 8; - const uint8_t bit = index % 8; +static inline void chunk_received(uint8_t* restrict const chunks_received, const uint32_t index) { + uint32_t byte; + uint8_t bit; + + byte = index / 8; + bit = index % 8; chunks_received[byte] |= (uint8_t)(1U << bit); } -static inline struct SwiftNetPendingMessage* const create_new_pending_message(struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, const struct SwiftNetPacketInfo* restrict const packet_info, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { - struct SwiftNetPendingMessage* restrict new_pending_message; - uint8_t* restrict allocated_memory; +static inline struct SwiftNetPendingMessage* create_new_pending_message(struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, const struct SwiftNetPacketInfo* restrict const packet_info, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { + struct SwiftNetPendingMessage* new_pending_message; + uint8_t* allocated_memory; struct PendingMessagesKey* key; - const uint32_t chunks_received_byte_size = (packet_info->chunk_amount + 7) / 8; + uint32_t chunks_received_byte_size; + + chunks_received_byte_size = (packet_info->chunk_amount + 7) / 8; new_pending_message = allocator_allocate(pending_messages_memory_allocator); @@ -252,20 +257,20 @@ static inline struct SwiftNetPendingMessage* const create_new_pending_message(st return new_pending_message; } -static inline struct SwiftNetPacketSending* const get_packet_sending(struct SwiftNetHashMap* const packet_sending_array, uint16_t target_id) { +static inline struct SwiftNetPacketSending* get_packet_sending(struct SwiftNetHashMap* const packet_sending_array, const uint16_t target_id) { struct SwiftNetPacketSending* result; LOCK_ATOMIC_DATA_TYPE(&packet_sending_array->atomic_lock); - result = hashmap_get(&target_id, sizeof(target_id), packet_sending_array); + result = hashmap_get(&target_id, sizeof(target_id), packet_sending_array); UNLOCK_ATOMIC_DATA_TYPE(&packet_sending_array->atomic_lock); return result; } -static inline void signal_delay_change(const enum PacketDelayUpdateStatus status, const struct ip* const ip_header, const uint16_t source_port, const uint16_t destination_port, const uint16_t addr_type, const uint8_t prepend_size, pcap_t* const pcap, const struct ether_header* const eth_hdr) { +static inline void signal_delay_change(const enum PacketDelayUpdateStatus status, const struct ip* restrict const ip_header, const uint16_t source_port, const uint16_t destination_port, const uint16_t addr_type, const uint8_t prepend_size, pcap_t* const pcap, const struct ether_header* restrict const eth_hdr) { struct ip send_server_info_ip_header; struct SwiftNetPacketInfo packet_info_new; struct SwiftNetServerInformation server_info; @@ -288,7 +293,7 @@ static inline void signal_delay_change(const enum PacketDelayUpdateStatus status .maximum_transmission_unit = maximum_transmission_unit }; - HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) + HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, eth_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); @@ -297,9 +302,10 @@ static inline void signal_delay_change(const enum PacketDelayUpdateStatus status SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); } -struct PacketQueueNode* const wait_for_next_packet(struct PacketQueue* const packet_queue) { +struct PacketQueueNode* wait_for_next_packet(struct PacketQueue* const packet_queue) { struct PacketQueueNode* node_to_process; + LOCK_ATOMIC_DATA_TYPE(&packet_queue->locked); if(packet_queue->first_node == NULL) { @@ -330,7 +336,7 @@ static inline bool packet_corrupted(const uint32_t checksum, const uint32_t chun } static inline void swiftnet_process_packets( - void* _Atomic * packet_handler, + void* _Atomic * const packet_handler, pcap_t* const pcap, const struct ether_header eth_hdr, const uint16_t source_port, @@ -342,493 +348,566 @@ static inline void swiftnet_process_packets( struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, struct SwiftNetHashMap* const packets_completed_history, struct SwiftNetMemoryAllocator* const packets_completed_history_memory_allocator, - enum ConnectionType connection_type, + const enum ConnectionType connection_type, struct PacketQueue* const packet_queue, struct PacketCallbackQueue* const packet_callback_queue, void* const connection, - _Atomic bool* closing, + const _Atomic bool* const closing, const uint8_t prepend_size, pthread_mutex_t* const process_packets_mtx, pthread_cond_t* const process_packets_cond, pthread_mutex_t* const execute_callback_mtx, pthread_cond_t* const execute_callback_cond, - _Atomic bool *const processing_packets + _Atomic bool* const processing_packets ) { - uint8_t idle_stage = 0; // 0-3 + uint8_t idle_stage; + struct PacketQueueNode* node; + uint8_t* packet_buffer; + uint8_t* packet_data; + struct ip ip_header; + struct SwiftNetPacketInfo packet_info; + uint32_t checksum_received; + struct SwiftNetClientAddrData sender; + uint32_t mtu; + uint32_t chunk_data_size; + struct SwiftNetPendingMessage* pending_message; - while(1) { - if (atomic_load(closing) == true) { - break; - } - struct PacketQueueNode* const node = wait_for_next_packet(packet_queue); - if(node == NULL) { - switch (idle_stage) { - case 0: usleep(1000); break; - case 1: usleep(2000); break; - case 2: usleep(5000); break; - case 3: { - atomic_store_explicit(processing_packets, false, memory_order_release); + idle_stage = 0; - pthread_mutex_lock(process_packets_mtx); +process_packet: + if (atomic_load(closing) == true) { + goto exit; + } - pthread_cond_wait(process_packets_cond, process_packets_mtx); + node = wait_for_next_packet(packet_queue); + if(node == NULL) { + switch (idle_stage) { + case 0: usleep(1000); break; + case 1: usleep(2000); break; + case 2: usleep(5000); break; + case 3: { + atomic_store_explicit(processing_packets, false, memory_order_release); - pthread_mutex_unlock(process_packets_mtx); + pthread_mutex_lock(process_packets_mtx); - atomic_store_explicit(processing_packets, true, memory_order_release); + pthread_cond_wait(process_packets_cond, process_packets_mtx); - idle_stage = 0; + pthread_mutex_unlock(process_packets_mtx); - continue; - } - } + atomic_store_explicit(processing_packets, true, memory_order_release); - idle_stage++; + idle_stage = 0; - continue; + goto process_packet; + } } - idle_stage = 0; + idle_stage++; - uint8_t* const packet_buffer = node->data; - if(packet_buffer == NULL) { - goto next_packet; - } + goto process_packet; + } - uint8_t* const packet_data = &packet_buffer[prepend_size + PACKET_HEADER_SIZE]; + idle_stage = 0; - struct ip ip_header; - memcpy(&ip_header, packet_buffer + prepend_size, sizeof(ip_header)); + packet_buffer = node->data; + if(unlikely(packet_buffer == NULL)) { + goto next_packet; + } - struct SwiftNetPacketInfo packet_info; - memcpy(&packet_info, packet_buffer + prepend_size + sizeof(ip_header), sizeof(packet_info)); + packet_data = &packet_buffer[prepend_size + PACKET_HEADER_SIZE]; - // Check if the packet is meant to be for this server - if(packet_info.port_info.destination_port != source_port) { - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + memcpy(&ip_header, packet_buffer + prepend_size, sizeof(ip_header)); - goto next_packet; - } + memcpy(&packet_info, packet_buffer + prepend_size + sizeof(ip_header), sizeof(packet_info)); - const uint32_t checksum_received = packet_info.checksum; + // Check if the packet is meant to be for this server + if(packet_info.port_info.destination_port != source_port) { + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - memset(packet_buffer + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, checksum), 0x00, SIZEOF_FIELD(struct SwiftNetPacketInfo, checksum)); + goto next_packet; + } - memcpy(packet_buffer + prepend_size + offsetof(struct ip, ip_len), (void*)&node->data_read, SIZEOF_FIELD(struct ip, ip_len)); + checksum_received = packet_info.checksum; - if(memcmp(&ip_header.ip_src, &ip_header.ip_dst, sizeof(struct in_addr)) != 0 && is_private_ip(ip_header.ip_src) == false && is_private_ip(ip_header.ip_dst)) { - if(ip_header.ip_sum != 0 && packet_corrupted(checksum_received, node->data_read, packet_buffer) == true) { - #ifdef SWIFT_NET_DEBUG - if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_RECEIVING)) { - send_debug_message("Received corrupted packet: {\"source_ip_address\": \"%s\", \"source_port\": %d, \"packet_id\": %d, \"received_checsum\": %d, \"real_checksum\": %d}\n", inet_ntoa(ip_header.ip_src), packet_info.port_info.source_port, ip_header.ip_id, checksum_received, crc32(packet_buffer, node->data_read)); - } - #endif + memset(packet_buffer + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, checksum), 0x00, SIZEOF_FIELD(struct SwiftNetPacketInfo, checksum)); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + memcpy(packet_buffer + prepend_size + offsetof(struct ip, ip_len), (void*)&node->data_read, SIZEOF_FIELD(struct ip, ip_len)); - goto next_packet; - } + if(memcmp(&ip_header.ip_src, &ip_header.ip_dst, sizeof(struct in_addr)) != 0 && is_private_ip(ip_header.ip_src) == false && is_private_ip(ip_header.ip_dst)) { + if(ip_header.ip_sum != 0 && packet_corrupted(checksum_received, node->data_read, packet_buffer) == true) { + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_RECEIVING)) { + send_debug_message("Received corrupted packet: {\"source_ip_address\": \"%s\", \"source_port\": %d, \"packet_id\": %d, \"received_checsum\": %d, \"real_checksum\": %d}\n", inet_ntoa(ip_header.ip_src), packet_info.port_info.source_port, ip_header.ip_id, checksum_received, crc32(packet_buffer, node->data_read)); + } + #endif + + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; } + } - #ifdef SWIFT_NET_DEBUG - if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_RECEIVING)) { - send_debug_message("Received packet: {\"source_ip_address\": \"%s\", \"source_port\": %d, \"packet_id\": %d, \"packet_type\": %d, \"packet_length\": %d, \"chunk_index\": %d, \"connection_type\": %d, \"checksum_received\": %d, \"real_checksum\": %d}\n", inet_ntoa(ip_header.ip_src), packet_info.port_info.source_port, ip_header.ip_id, packet_info.packet_type, packet_info.packet_length, packet_info.chunk_index, connection_type, checksum_received, crc32(node->data, node->data_read)); - } - #endif + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_RECEIVING)) { + send_debug_message("Received packet: {\"source_ip_address\": \"%s\", \"source_port\": %d, \"packet_id\": %d, \"packet_type\": %d, \"packet_length\": %d, \"chunk_index\": %d, \"connection_type\": %d, \"checksum_received\": %d, \"real_checksum\": %d}\n", inet_ntoa(ip_header.ip_src), packet_info.port_info.source_port, ip_header.ip_id, packet_info.packet_type, packet_info.packet_length, packet_info.chunk_index, connection_type, checksum_received, crc32(node->data, node->data_read)); + } + #endif + + switch(packet_info.packet_type) { + case REQUEST_INFORMATION: + { + struct ip send_server_info_ip_header; + struct SwiftNetPacketInfo packet_info_new; + struct SwiftNetServerInformation server_info; + + + send_server_info_ip_header = construct_ip_header(ip_header.ip_src, PACKET_HEADER_SIZE, rand()); + + packet_info_new = construct_packet_info( + sizeof(struct SwiftNetServerInformation), + REQUEST_INFORMATION, + 1, + 0, + (struct SwiftNetPortInfo){ + .source_port = source_port, + .destination_port = packet_info.port_info.source_port + } + ); - switch(packet_info.packet_type) { - case REQUEST_INFORMATION: - { - const struct ip send_server_info_ip_header = construct_ip_header(ip_header.ip_src, PACKET_HEADER_SIZE, rand()); - - const struct SwiftNetPacketInfo packet_info_new = construct_packet_info( - sizeof(struct SwiftNetServerInformation), - REQUEST_INFORMATION, - 1, - 0, - (struct SwiftNetPortInfo){ - .source_port = source_port, - .destination_port = packet_info.port_info.source_port - } - ); + server_info = (struct SwiftNetServerInformation){ + .maximum_transmission_unit = maximum_transmission_unit + }; - const struct SwiftNetServerInformation server_info = { - .maximum_transmission_unit = maximum_transmission_unit - }; + HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) - HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) + memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); - memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); + HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + + SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) - - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); - - goto next_packet; - } - case SEND_LOST_PACKETS_REQUEST: - { - const uint32_t mtu = MIN(packet_info.maximum_transmission_unit, maximum_transmission_unit); + goto next_packet; + } + case SEND_LOST_PACKETS_REQUEST: + { + uint32_t case_mtu; + struct SwiftNetPendingMessage* case_pending_message; + bool packet_already_completed; + struct ip send_packet_ip_header; + struct SwiftNetPacketInfo send_packet_info; + struct ip send_lost_packets_ip_header; + struct SwiftNetPacketInfo packet_info_new; + uint16_t header_size; + uint32_t lost_chunk_indexes; + uint32_t lost_indexes_size; + uint32_t packet_length; + uint16_t packet_length_net_order; + + + case_mtu = MIN(packet_info.maximum_transmission_unit, maximum_transmission_unit); + + case_pending_message = get_pending_message(pending_messages, connection_type, ip_header.ip_id, packet_info.port_info.source_port); + if(case_pending_message == NULL) { + packet_already_completed = check_packet_already_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history); + if(likely(packet_already_completed == true)) { + send_packet_ip_header = construct_ip_header(ip_header.ip_src, PACKET_HEADER_SIZE, ip_header.ip_id); + + send_packet_info = construct_packet_info( + 0x00, + SUCCESSFULLY_RECEIVED_PACKET, + 1, + 0, + (struct SwiftNetPortInfo){ + .destination_port = packet_info.port_info.source_port, + .source_port = packet_info.port_info.destination_port + } + ); - struct SwiftNetPendingMessage* const pending_message = get_pending_message(pending_messages, connection_type, ip_header.ip_id, packet_info.port_info.source_port); - if(pending_message == NULL) { - const bool packet_already_completed = check_packet_already_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history); - if(likely(packet_already_completed == true)) { - const struct ip send_packet_ip_header = construct_ip_header(ip_header.ip_src, PACKET_HEADER_SIZE, ip_header.ip_id); + HANDLE_PACKET_CONSTRUCTION(&send_packet_ip_header, &send_packet_info, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE, buffer) - struct SwiftNetPacketInfo send_packet_info = construct_packet_info( - 0x00, - SUCCESSFULLY_RECEIVED_PACKET, - 1, - 0, - (struct SwiftNetPortInfo){ - .destination_port = packet_info.port_info.source_port, - .source_port = packet_info.port_info.destination_port - } - ); + HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) - HANDLE_PACKET_CONSTRUCTION(&send_packet_ip_header, &send_packet_info, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE, buffer) + SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); + goto next_packet; + } - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - goto next_packet; - } + goto next_packet; + } - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + case_pending_message->sending_lost_packets = true; - goto next_packet; + send_lost_packets_ip_header = construct_ip_header(ip_header.ip_src, 0, ip_header.ip_id); + + packet_info_new = construct_packet_info( + 0, + SEND_LOST_PACKETS_RESPONSE, + 1, + 0, + (struct SwiftNetPortInfo){ + .destination_port = packet_info.port_info.source_port, + .source_port = packet_info.port_info.destination_port } + ); - pending_message->sending_lost_packets = true; + header_size = PACKET_HEADER_SIZE + prepend_size; - struct ip send_lost_packets_ip_header = construct_ip_header(ip_header.ip_src, 0, ip_header.ip_id); + HANDLE_PACKET_CONSTRUCTION(&send_lost_packets_ip_header, &packet_info_new, addr_type, ð_hdr, case_mtu + prepend_size, buffer) - struct SwiftNetPacketInfo packet_info_new = construct_packet_info( - 0, - SEND_LOST_PACKETS_RESPONSE, - 1, - 0, - (struct SwiftNetPortInfo){ - .destination_port = packet_info.port_info.source_port, - .source_port = packet_info.port_info.destination_port - } - ); + lost_chunk_indexes = return_lost_chunk_indexes(case_pending_message->chunks_received, case_pending_message->packet_info.chunk_amount, case_mtu - PACKET_HEADER_SIZE, (uint32_t*)(buffer + header_size)); - const uint16_t header_size = PACKET_HEADER_SIZE + prepend_size; + lost_indexes_size = lost_chunk_indexes * sizeof(uint32_t); + packet_length = PACKET_HEADER_SIZE + (lost_chunk_indexes * sizeof(uint32_t)); - HANDLE_PACKET_CONSTRUCTION(&send_lost_packets_ip_header, &packet_info_new, addr_type, ð_hdr, mtu + prepend_size, buffer) + packet_length_net_order = htons((uint16_t)packet_length); - const uint32_t lost_chunk_indexes = return_lost_chunk_indexes(pending_message->chunks_received, pending_message->packet_info.chunk_amount, mtu - PACKET_HEADER_SIZE, (uint32_t*)(buffer + header_size)); + memcpy(buffer + prepend_size + offsetof(struct ip, ip_len), &packet_length_net_order, SIZEOF_FIELD(struct ip, ip_len)); + memcpy(buffer + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, packet_length), &lost_indexes_size, sizeof(lost_indexes_size)); - const uint32_t lost_indexes_size = lost_chunk_indexes * sizeof(uint32_t); - const uint32_t packet_length = PACKET_HEADER_SIZE + (lost_chunk_indexes * sizeof(uint32_t)); + HANDLE_CHECKSUM(buffer, packet_length + prepend_size, prepend_size); - const uint16_t packet_length_net_order = htons((uint16_t)packet_length); + SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, packet_length + prepend_size); - memcpy(buffer + prepend_size + offsetof(struct ip, ip_len), &packet_length_net_order, SIZEOF_FIELD(struct ip, ip_len)); - memcpy(buffer + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, packet_length), &lost_indexes_size, sizeof(lost_indexes_size)); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; + } + case SEND_LOST_PACKETS_RESPONSE: + { + struct SwiftNetPacketSending* target_packet_sending; + uint32_t packets_lost; - HANDLE_CHECKSUM(buffer, packet_length + prepend_size, prepend_size); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, packet_length + prepend_size); + target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); + if(unlikely(target_packet_sending == NULL)) { allocator_free(&packet_buffer_memory_allocator, packet_buffer); goto next_packet; } - case SEND_LOST_PACKETS_RESPONSE: - { - struct SwiftNetPacketSending* const target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); - - if(unlikely(target_packet_sending == NULL)) { - allocator_free(&packet_buffer_memory_allocator, packet_buffer); - - goto next_packet; - } - - LOCK_ATOMIC_DATA_TYPE(&target_packet_sending->locked); - if(target_packet_sending->lost_chunks == NULL) { - target_packet_sending->lost_chunks = malloc(maximum_transmission_unit - PACKET_HEADER_SIZE); - } + LOCK_ATOMIC_DATA_TYPE(&target_packet_sending->locked); - const uint32_t packets_lost = (packet_info.packet_length) / sizeof(uint32_t); + if(target_packet_sending->lost_chunks == NULL) { + target_packet_sending->lost_chunks = malloc(maximum_transmission_unit - PACKET_HEADER_SIZE); + } - memcpy((void*)target_packet_sending->lost_chunks, packet_data, packet_info.packet_length); + packets_lost = (packet_info.packet_length) / sizeof(uint32_t); - target_packet_sending->lost_chunks_size = packet_info.packet_length / 4; + memcpy((void*)target_packet_sending->lost_chunks, packet_data, packet_info.packet_length); - atomic_store_explicit(&target_packet_sending->updated, UPDATED_LOST_CHUNKS, memory_order_release); + target_packet_sending->lost_chunks_size = packet_info.packet_length / 4; - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + atomic_store_explicit(&target_packet_sending->updated, UPDATED_LOST_CHUNKS, memory_order_release); - UNLOCK_ATOMIC_DATA_TYPE(&target_packet_sending->locked); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - goto next_packet; - } - case SUCCESSFULLY_RECEIVED_PACKET: - { - struct SwiftNetPacketSending* const target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); + UNLOCK_ATOMIC_DATA_TYPE(&target_packet_sending->locked); - if(unlikely(target_packet_sending == NULL)) { - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + goto next_packet; + } + case SUCCESSFULLY_RECEIVED_PACKET: + { + struct SwiftNetPacketSending* target_packet_sending; - goto next_packet; - } - atomic_store_explicit(&target_packet_sending->updated, SUCCESSFULLY_RECEIVED, memory_order_release); + target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); + if(unlikely(target_packet_sending == NULL)) { allocator_free(&packet_buffer_memory_allocator, packet_buffer); goto next_packet; } - case PACKET_DELAY_UPDATE: - { - const enum PacketDelayUpdateStatus* const status = (enum PacketDelayUpdateStatus*)packet_data; - struct SwiftNetPacketSending* const target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); + atomic_store_explicit(&target_packet_sending->updated, SUCCESSFULLY_RECEIVED, memory_order_release); - uint32_t current_delay = atomic_load_explicit(&target_packet_sending->current_send_delay, memory_order_acquire); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - if (*status == INCREASE_DELAY) { - current_delay = (current_delay / 6) * 7; - } else { - current_delay = (current_delay / 6) * 5; - } + goto next_packet; + } + case PACKET_DELAY_UPDATE: + { + enum PacketDelayUpdateStatus* status; + struct SwiftNetPacketSending* target_packet_sending; + uint32_t current_delay; - atomic_store_explicit(&target_packet_sending->current_send_delay, current_delay, memory_order_release); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + status = (enum PacketDelayUpdateStatus*)packet_data; - goto next_packet; + target_packet_sending = get_packet_sending(packets_sending, ip_header.ip_id); + + current_delay = atomic_load_explicit(&target_packet_sending->current_send_delay, memory_order_acquire); + + if (*status == INCREASE_DELAY) { + current_delay = (current_delay / 6) * 7; + } else { + current_delay = (current_delay / 6) * 5; } - default: - break; - } - if (check_packet_already_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history)) { + atomic_store_explicit(&target_packet_sending->current_send_delay, current_delay, memory_order_release); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + goto next_packet; } + default: + break; + } - struct SwiftNetClientAddrData sender = { - .maximum_transmission_unit = packet_info.maximum_transmission_unit, - .port = packet_info.port_info.source_port, - }; + if (check_packet_already_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history)) { + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + goto next_packet; + } - if (addr_type == DLT_EN10MB) { - memcpy(&sender.mac_address, eth_hdr.ether_shost, sizeof(sender.mac_address)); - } + sender = (struct SwiftNetClientAddrData){ + .maximum_transmission_unit = packet_info.maximum_transmission_unit, + .port = packet_info.port_info.source_port, + }; - const uint32_t mtu = MIN(packet_info.maximum_transmission_unit, maximum_transmission_unit); - const uint32_t chunk_data_size = mtu - PACKET_HEADER_SIZE; + if (addr_type == DLT_EN10MB) { + memcpy(&sender.mac_address, eth_hdr.ether_shost, sizeof(sender.mac_address)); + } - struct SwiftNetPendingMessage* const pending_message = get_pending_message(pending_messages, connection_type, ip_header.ip_id, packet_info.port_info.source_port); + mtu = MIN(packet_info.maximum_transmission_unit, maximum_transmission_unit); + chunk_data_size = mtu - PACKET_HEADER_SIZE; - if(pending_message == NULL) { - if(packet_info.packet_length > chunk_data_size) { - // Split packet into chunks - struct SwiftNetPendingMessage* const new_pending_message = create_new_pending_message(pending_messages, pending_messages_memory_allocator, &packet_info, connection_type, ip_header.ip_id, packet_info.port_info.source_port); + pending_message = get_pending_message(pending_messages, connection_type, ip_header.ip_id, packet_info.port_info.source_port); - new_pending_message->chunks_received_number = 1; + if(pending_message == NULL) { + if(packet_info.packet_length > chunk_data_size) { + struct SwiftNetPendingMessage* new_pending_message; - chunk_received(new_pending_message->chunks_received, packet_info.chunk_index); - - memcpy(new_pending_message->packet_data_start, packet_data, chunk_data_size); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + new_pending_message = create_new_pending_message(pending_messages, pending_messages_memory_allocator, &packet_info, connection_type, ip_header.ip_id, packet_info.port_info.source_port); - goto next_packet; - } else { - packet_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history, packets_completed_history_memory_allocator); - - if(connection_type == CONNECTION_TYPE_SERVER) { - struct SwiftNetServerPacketData* const new_packet_data = allocator_allocate(&server_packet_data_memory_allocator) ; - new_packet_data->data = packet_data; - new_packet_data->current_pointer = packet_data; - new_packet_data->internal_pending_message = NULL; - new_packet_data->metadata = (struct SwiftNetPacketServerMetadata){ - .port_info = packet_info.port_info, - .sender = sender, - .data_length = packet_info.packet_length, - .packet_id = ip_header.ip_id - #ifdef SWIFT_NET_REQUESTS - , .expecting_response = packet_info.packet_type == REQUEST - #endif - }; + new_pending_message->chunks_received_number = 1; + + chunk_received(new_pending_message->chunks_received, packet_info.chunk_index); + + memcpy(new_pending_message->packet_data_start, packet_data, chunk_data_size); + + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; + } else { + packet_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history, packets_completed_history_memory_allocator); + if(connection_type == CONNECTION_TYPE_SERVER) { + struct SwiftNetServerPacketData* new_packet_data; + + + new_packet_data = allocator_allocate(&server_packet_data_memory_allocator); + new_packet_data->data = packet_data; + new_packet_data->current_pointer = packet_data; + new_packet_data->internal_pending_message = NULL; + new_packet_data->metadata = (struct SwiftNetPacketServerMetadata){ + .port_info = packet_info.port_info, + .sender = sender, + .data_length = packet_info.packet_length, + .packet_id = ip_header.ip_id #ifdef SWIFT_NET_REQUESTS - if (packet_info.packet_type == RESPONSE) { - handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); - } else { - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); - } - #else - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + , .expecting_response = packet_info.packet_type == REQUEST #endif + }; + + #ifdef SWIFT_NET_REQUESTS + if (packet_info.packet_type == RESPONSE) { + handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); } else { - struct SwiftNetClientPacketData* const new_packet_data = allocator_allocate(&client_packet_data_memory_allocator) ; - new_packet_data->data = packet_data; - new_packet_data->current_pointer = packet_data; - new_packet_data->internal_pending_message = NULL; - new_packet_data->metadata = (struct SwiftNetPacketClientMetadata){ - .port_info = packet_info.port_info, - .data_length = packet_info.packet_length, - .packet_id = ip_header.ip_id - #ifdef SWIFT_NET_REQUESTS - , .expecting_response = packet_info.packet_type == REQUEST - #endif - }; + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + } + #else + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + #endif + } else { + struct SwiftNetClientPacketData* new_packet_data; + + new_packet_data = allocator_allocate(&client_packet_data_memory_allocator); + new_packet_data->data = packet_data; + new_packet_data->current_pointer = packet_data; + new_packet_data->internal_pending_message = NULL; + new_packet_data->metadata = (struct SwiftNetPacketClientMetadata){ + .port_info = packet_info.port_info, + .data_length = packet_info.packet_length, + .packet_id = ip_header.ip_id #ifdef SWIFT_NET_REQUESTS - if (packet_info.packet_type == RESPONSE) { - handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); - } else { - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); - } - #else - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + , .expecting_response = packet_info.packet_type == REQUEST #endif - } + }; - goto next_packet; + #ifdef SWIFT_NET_REQUESTS + if (packet_info.packet_type == RESPONSE) { + handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); + } else { + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + } + #else + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + #endif } - } else { - if (chunk_already_received(pending_message->chunks_received, packet_info.chunk_index)) { - allocator_free(&packet_buffer_memory_allocator, packet_buffer); - goto next_packet; - } + goto next_packet; + } + } else { + uint32_t bytes_to_write; + + if (chunk_already_received(pending_message->chunks_received, packet_info.chunk_index)) { + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; + } - const uint32_t bytes_to_write = (packet_info.chunk_index + 1) >= packet_info.chunk_amount ? packet_info.packet_length % chunk_data_size : chunk_data_size; + bytes_to_write = (packet_info.chunk_index + 1) >= packet_info.chunk_amount ? packet_info.packet_length % chunk_data_size : chunk_data_size; - if(pending_message->chunks_received_number + 1 == packet_info.chunk_amount) { + if(pending_message->chunks_received_number + 1 == packet_info.chunk_amount) { - pending_message->chunks_received_number++; + pending_message->chunks_received_number++; - // Completed the packet - memcpy(pending_message->packet_data_start + (chunk_data_size * packet_info.chunk_index), packet_data, bytes_to_write); + // Completed the packet + memcpy(pending_message->packet_data_start + (chunk_data_size * packet_info.chunk_index), packet_data, bytes_to_write); - chunk_received(pending_message->chunks_received, packet_info.chunk_index); + chunk_received(pending_message->chunks_received, packet_info.chunk_index); - #ifdef SWIFT_NET_DEBUG - uint32_t lost_chunks_buffer[chunk_data_size]; + #ifdef SWIFT_NET_DEBUG + { + uint32_t lost_chunks_buffer[chunk_data_size]; + uint32_t lost_chunks_num; - const uint32_t lost_chunks_num = return_lost_chunk_indexes(pending_message->chunks_received, packet_info.chunk_amount, chunk_data_size, (uint32_t*)lost_chunks_buffer); - if (lost_chunks_num != 0) { - PRINT_ERROR("Packet marked as completed, but %d chunks are missing", lost_chunks_num); + lost_chunks_num = return_lost_chunk_indexes(pending_message->chunks_received, packet_info.chunk_amount, chunk_data_size, (uint32_t*)lost_chunks_buffer); - for (uint32_t i = 0; i < lost_chunks_num; i++) { - printf("chunk index missing: %d\n", *(lost_chunks_buffer + i)); - } + if (lost_chunks_num != 0) { + PRINT_ERROR("Packet marked as completed, but %d chunks are missing", lost_chunks_num); + + for (uint32_t i = 0; i < lost_chunks_num; i++) { + printf("chunk index missing: %d\n", *(lost_chunks_buffer + i)); } - #endif + } + } + #endif + + packet_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history, packets_completed_history_memory_allocator); + + if(connection_type == CONNECTION_TYPE_SERVER) { + uint8_t* ptr; + struct SwiftNetServerPacketData* server_packet_data; - packet_completed(ip_header.ip_id, packet_info.port_info.source_port, packets_completed_history, packets_completed_history_memory_allocator); - - if(connection_type == CONNECTION_TYPE_SERVER) { - uint8_t* const ptr = pending_message->packet_data_start; - - struct SwiftNetServerPacketData* const packet_data = allocator_allocate(&server_packet_data_memory_allocator); - packet_data->data = ptr; - packet_data->current_pointer = ptr; - packet_data->internal_pending_message = pending_message; - packet_data->metadata = (struct SwiftNetPacketServerMetadata){ - .port_info = packet_info.port_info, - .sender = sender, - .data_length = packet_info.packet_length, - .packet_id = ip_header.ip_id - #ifdef SWIFT_NET_REQUESTS - , .expecting_response = packet_info.packet_type == REQUEST - #endif - }; + ptr = pending_message->packet_data_start; + + server_packet_data = allocator_allocate(&server_packet_data_memory_allocator); + server_packet_data->data = ptr; + server_packet_data->current_pointer = ptr; + server_packet_data->internal_pending_message = pending_message; + server_packet_data->metadata = (struct SwiftNetPacketServerMetadata){ + .port_info = packet_info.port_info, + .sender = sender, + .data_length = packet_info.packet_length, + .packet_id = ip_header.ip_id #ifdef SWIFT_NET_REQUESTS - if (packet_info.packet_type == RESPONSE) { - handle_request_response(ip_header.ip_id, pending_message, packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); - } else { - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); - } - #else - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + , .expecting_response = packet_info.packet_type == REQUEST #endif + }; + + #ifdef SWIFT_NET_REQUESTS + if (packet_info.packet_type == RESPONSE) { + handle_request_response(ip_header.ip_id, pending_message, server_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); } else { - uint8_t* const ptr = pending_message->packet_data_start; - - struct SwiftNetClientPacketData* const packet_data = allocator_allocate(&client_packet_data_memory_allocator) ; - packet_data->data = ptr; - packet_data->current_pointer = ptr; - packet_data->internal_pending_message = pending_message; - packet_data->metadata = (struct SwiftNetPacketClientMetadata){ - .port_info = packet_info.port_info, - .data_length = packet_info.packet_length, - .packet_id = ip_header.ip_id - #ifdef SWIFT_NET_REQUESTS - , .expecting_response = packet_info.packet_type == REQUEST - #endif - }; + pass_callback_execution(server_packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + } + #else + pass_callback_execution(server_packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + #endif + } else { + uint8_t* ptr; + struct SwiftNetClientPacketData* client_packet_data; + + + ptr = pending_message->packet_data_start; + client_packet_data = allocator_allocate(&client_packet_data_memory_allocator); + client_packet_data->data = ptr; + client_packet_data->current_pointer = ptr; + client_packet_data->internal_pending_message = pending_message; + client_packet_data->metadata = (struct SwiftNetPacketClientMetadata){ + .port_info = packet_info.port_info, + .data_length = packet_info.packet_length, + .packet_id = ip_header.ip_id #ifdef SWIFT_NET_REQUESTS - if (packet_info.packet_type == RESPONSE) { - handle_request_response(ip_header.ip_id, pending_message, packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); - } else { - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); - } - #else - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + , .expecting_response = packet_info.packet_type == REQUEST #endif + }; + + #ifdef SWIFT_NET_REQUESTS + if (packet_info.packet_type == RESPONSE) { + handle_request_response(ip_header.ip_id, pending_message, client_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback, packet_info.port_info.source_port); + } else { + pass_callback_execution(client_packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); } + #else + pass_callback_execution(client_packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); + #endif + } - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + allocator_free(&packet_buffer_memory_allocator, packet_buffer); - goto next_packet; - } else { - const uint32_t new_packets = packet_info.chunk_index - pending_message->last_index_checked; - const uint32_t new_packets_validated = pending_message->chunks_received_number - pending_message->last_chunks_received_number; - - if (new_packets > 50) { - float ratio = (float)new_packets_validated / (float)new_packets; - if (ratio > 0.95) { - signal_delay_change(LOWER_DELAY, &ip_header, source_port, packet_info.port_info.source_port, addr_type, prepend_size, pcap, ð_hdr); - } else { - signal_delay_change(INCREASE_DELAY, &ip_header, source_port, packet_info.port_info.source_port, addr_type, prepend_size, pcap, ð_hdr); - } + goto next_packet; + } else { + uint32_t new_packets; + uint32_t new_packets_validated; + float ratio; + + + new_packets = packet_info.chunk_index - pending_message->last_index_checked; + new_packets_validated = pending_message->chunks_received_number - pending_message->last_chunks_received_number; - pending_message->last_chunks_received_number = pending_message->chunks_received_number; - pending_message->last_index_checked = packet_info.chunk_index; + if (new_packets > 50) { + ratio = (float)new_packets_validated / (float)new_packets; + if (ratio > 0.95) { + signal_delay_change(LOWER_DELAY, &ip_header, source_port, packet_info.port_info.source_port, addr_type, prepend_size, pcap, ð_hdr); + } else { + signal_delay_change(INCREASE_DELAY, &ip_header, source_port, packet_info.port_info.source_port, addr_type, prepend_size, pcap, ð_hdr); } - memcpy(pending_message->packet_data_start + (chunk_data_size * packet_info.chunk_index), packet_data, bytes_to_write); + pending_message->last_chunks_received_number = pending_message->chunks_received_number; + pending_message->last_index_checked = packet_info.chunk_index; + } - chunk_received(pending_message->chunks_received, packet_info.chunk_index); + memcpy(pending_message->packet_data_start + (chunk_data_size * packet_info.chunk_index), packet_data, bytes_to_write); - pending_message->chunks_received_number++; + chunk_received(pending_message->chunks_received, packet_info.chunk_index); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); + pending_message->chunks_received_number++; - goto next_packet; - } + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; } + } - goto next_packet; + goto next_packet; - next_packet: - allocator_free(&packet_queue_node_memory_allocator, (void*)node); +next_packet: + allocator_free(&packet_queue_node_memory_allocator, (void*)node); - continue; - } + goto process_packet; +exit: + return; } void* swiftnet_server_process_packets(void* const void_server) { - struct SwiftNetServer* const server = (struct SwiftNetServer*)void_server; + struct SwiftNetServer* server; + + + server = void_server; swiftnet_process_packets((void*)&server->packet_handler, server->pcap, server->eth_header, server->server_port, server->loopback, server->addr_type, &server->packets_sending, &server->packets_sending_memory_allocator, &server->pending_messages, &server->pending_messages_memory_allocator, &server->packets_completed, &server->packets_completed_memory_allocator, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->packet_callback_queue, server, &server->closing, server->prepend_size, &server->process_packets_mtx, &server->process_packets_cond, &server->execute_callback_mtx, &server->execute_callback_cond, &server->processing_packets); @@ -836,7 +915,10 @@ void* swiftnet_server_process_packets(void* const void_server) { } void* swiftnet_client_process_packets(void* const void_client) { - struct SwiftNetClientConnection* const client = (struct SwiftNetClientConnection*)void_client; + struct SwiftNetClientConnection* client; + + + client = (struct SwiftNetClientConnection*)void_client; swiftnet_process_packets((void*)&client->packet_handler, client->pcap, client->eth_header, client->port_info.source_port, client->loopback, client->addr_type, &client->packets_sending, &client->packets_sending_memory_allocator, &client->pending_messages, &client->pending_messages_memory_allocator, &client->packets_completed, &client->packets_completed_memory_allocator, CONNECTION_TYPE_CLIENT, &client->packet_queue, &client->packet_callback_queue, client, &client->closing, client->prepend_size, &client->process_packets_mtx, &client->process_packets_cond, &client->execute_callback_mtx, &client->execute_callback_cond, &client->processing_packets); diff --git a/src/send_packet.c b/src/send_packet.c index 898cef7..8f19b83 100644 --- a/src/send_packet.c +++ b/src/send_packet.c @@ -16,38 +16,43 @@ #include "internal/internal.h" #include -static inline enum RequestLostPacketsReturnType request_lost_packets_bitarray(const uint8_t* const raw_data, const uint32_t data_size, const struct sockaddr* const destination, pcap_t* const pcap, struct SwiftNetPacketSending* const packet_sending) { - while(1) { - if(check_debug_flag(SWIFTNET_DEBUG_LOST_PACKETS)) { - send_debug_message("Requested list of lost packets: {\"packet_id\": %d}\n", htons(packet_sending->packet_id)); - } +static inline enum RequestLostPacketsReturnType request_lost_packets_bitarray(const uint8_t* const raw_data, const uint32_t data_size, pcap_t* const pcap, struct SwiftNetPacketSending* const packet_sending) { + uint8_t times_checked; + enum PacketSendingUpdated status; + - SWIFTNET_PCAP_SEND_SAFE(pcap, raw_data, data_size); +request_lost_packets: + if(check_debug_flag(SWIFTNET_DEBUG_LOST_PACKETS)) { + send_debug_message("Requested list of lost packets: {\"packet_id\": %d}\n", htons(packet_sending->packet_id)); + } - for(uint8_t times_checked = 0; times_checked < 0xFF; times_checked++) { - const enum PacketSendingUpdated status = atomic_load_explicit(&packet_sending->updated, memory_order_acquire); + SWIFTNET_PCAP_SEND_SAFE(pcap, raw_data, data_size); - switch (status) { - case NO_UPDATE: - break; - case UPDATED_LOST_CHUNKS: - atomic_store_explicit(&packet_sending->updated, NO_UPDATE, memory_order_release); - return REQUEST_LOST_PACKETS_RETURN_UPDATED_BIT_ARRAY; - case SUCCESSFULLY_RECEIVED: - atomic_store_explicit(&packet_sending->updated, NO_UPDATE, memory_order_release); + for(times_checked = 0; times_checked < 0xFF; times_checked++) { + status = atomic_load_explicit(&packet_sending->updated, memory_order_acquire); - return REQUEST_LOST_PACKETS_RETURN_COMPLETED_PACKET; - } + switch (status) { + case NO_UPDATE: + break; + case UPDATED_LOST_CHUNKS: + atomic_store_explicit(&packet_sending->updated, NO_UPDATE, memory_order_release); + return REQUEST_LOST_PACKETS_RETURN_UPDATED_BIT_ARRAY; + case SUCCESSFULLY_RECEIVED: + atomic_store_explicit(&packet_sending->updated, NO_UPDATE, memory_order_release); - usleep(1000); + return REQUEST_LOST_PACKETS_RETURN_COMPLETED_PACKET; } + + usleep(1000); } + + goto request_lost_packets; } static inline void handle_lost_packets( struct SwiftNetPacketSending* const packet_sending, const uint32_t mtu, - const struct SwiftNetPacketBuffer* const packet, + const struct SwiftNetPacketBuffer* const packet, pcap_t* const pcap, const struct ether_header eth_hdr, const struct in_addr* const destination_address, @@ -63,14 +68,26 @@ static inline void handle_lost_packets( , const uint8_t packet_type #endif ) { - const struct SwiftNetPortInfo port_info = { + struct SwiftNetPortInfo port_info; + struct ip request_lost_packets_ip_header; + struct SwiftNetPacketInfo request_lost_packets_bit_array; + uint32_t packet_length; + uint32_t chunk_amount; + struct SwiftNetPacketInfo resend_chunk_packet_info; + struct ip resend_chunk_ip_header; + uint8_t temp_data_buffer[prepend_size + PACKET_HEADER_SIZE]; + uint8_t prepend_buffer[prepend_size + PACKET_HEADER_SIZE]; + enum RequestLostPacketsReturnType request_lost_packets_bitarray_response; + + + port_info = (struct SwiftNetPortInfo){ .source_port = source_port, .destination_port = destination_port }; - const struct ip request_lost_packets_ip_header = construct_ip_header(*destination_address, PACKET_HEADER_SIZE, packet_sending->packet_id); + request_lost_packets_ip_header = construct_ip_header(*destination_address, PACKET_HEADER_SIZE, packet_sending->packet_id); - struct SwiftNetPacketInfo request_lost_packets_bit_array = construct_packet_info( + request_lost_packets_bit_array = construct_packet_info( 0x00, SEND_LOST_PACKETS_REQUEST, 1, @@ -82,10 +99,10 @@ static inline void handle_lost_packets( HANDLE_CHECKSUM(request_lost_packets_buffer, sizeof(request_lost_packets_buffer), prepend_size) - const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; - const uint32_t chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); + packet_length = packet->packet_append_pointer - packet->packet_data_start; + chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); - const struct SwiftNetPacketInfo resend_chunk_packet_info = construct_packet_info( + resend_chunk_packet_info = construct_packet_info( packet_length, #ifdef SWIFT_NET_REQUESTS packet_type, @@ -97,26 +114,31 @@ static inline void handle_lost_packets( port_info ); - const struct ip resend_chunk_ip_header = construct_ip_header(*destination_address, mtu, packet_sending->packet_id); + resend_chunk_ip_header = construct_ip_header(*destination_address, mtu, packet_sending->packet_id); - uint8_t temp_data_buffer[prepend_size + PACKET_HEADER_SIZE]; + if (addr_type == DLT_NULL) { + uint32_t family; - uint8_t prepend_buffer[prepend_size + PACKET_HEADER_SIZE]; - if (addr_type == DLT_NULL) { - // Loopback interface - const uint32_t family = PF_INET; \ - memcpy(prepend_buffer, &family, sizeof(family)); \ - memcpy(prepend_buffer+ sizeof(family), &resend_chunk_ip_header, sizeof(resend_chunk_ip_header)); \ - memcpy(prepend_buffer + sizeof(family) + sizeof(resend_chunk_ip_header), &resend_chunk_packet_info, sizeof(resend_chunk_packet_info)); \ + family = PF_INET; + + memcpy(prepend_buffer, &family, sizeof(family)); + memcpy(prepend_buffer + sizeof(family), &resend_chunk_ip_header, sizeof(resend_chunk_ip_header)); + memcpy(prepend_buffer + sizeof(family) + sizeof(resend_chunk_ip_header), &resend_chunk_packet_info, sizeof(resend_chunk_packet_info)); } else if (addr_type == DLT_EN10MB) { - memcpy(prepend_buffer, ð_hdr, sizeof(eth_hdr)); \ - memcpy(prepend_buffer+ sizeof(eth_hdr), &resend_chunk_ip_header, sizeof(resend_chunk_ip_header)); \ - memcpy(prepend_buffer + sizeof(eth_hdr) + sizeof(resend_chunk_ip_header), &resend_chunk_packet_info, sizeof(resend_chunk_packet_info)); \ + memcpy(prepend_buffer, ð_hdr, sizeof(eth_hdr)); + memcpy(prepend_buffer + sizeof(eth_hdr), &resend_chunk_ip_header, sizeof(resend_chunk_ip_header)); + memcpy(prepend_buffer + sizeof(eth_hdr) + sizeof(resend_chunk_ip_header), &resend_chunk_packet_info, sizeof(resend_chunk_packet_info)); } while(1) { - const enum RequestLostPacketsReturnType request_lost_packets_bitarray_response = request_lost_packets_bitarray(request_lost_packets_buffer, PACKET_HEADER_SIZE + prepend_size, (const struct sockaddr*)destination_address, pcap, packet_sending); + uint32_t i; + uint32_t lost_chunk_index; + uint32_t current_offset; + uint8_t* current_buffer_header_ptr; + + + request_lost_packets_bitarray_response = request_lost_packets_bitarray(request_lost_packets_buffer, PACKET_HEADER_SIZE + prepend_size, pcap, packet_sending); LOCK_ATOMIC_DATA_TYPE(&packets_sending->atomic_lock); @@ -135,12 +157,12 @@ static inline void handle_lost_packets( return; } - for(uint32_t i = 0; i < packet_sending->lost_chunks_size; i++) { - const uint32_t lost_chunk_index = packet_sending->lost_chunks[i]; + for(i = 0; i < packet_sending->lost_chunks_size; i++) { + lost_chunk_index = packet_sending->lost_chunks[i]; - const uint32_t current_offset = lost_chunk_index * (mtu - PACKET_HEADER_SIZE); + current_offset = lost_chunk_index * (mtu - PACKET_HEADER_SIZE); - uint8_t* const current_buffer_header_ptr = packet->packet_data_start + current_offset - prepend_size - PACKET_HEADER_SIZE; + current_buffer_header_ptr = packet->packet_data_start + current_offset - prepend_size - PACKET_HEADER_SIZE; memcpy(temp_data_buffer, current_buffer_header_ptr, prepend_size + PACKET_HEADER_SIZE); @@ -155,9 +177,13 @@ static inline void handle_lost_packets( memset(current_buffer_header_ptr + prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, checksum), 0x00, SIZEOF_FIELD(struct SwiftNetPacketInfo, checksum)); if(current_offset + mtu - PACKET_HEADER_SIZE >= packet_length) { - const uint32_t bytes_to_complete = packet_length - current_offset; + uint32_t bytes_to_complete; + uint16_t new_ip_len; + - const uint16_t new_ip_len = htons(bytes_to_complete + PACKET_HEADER_SIZE); + bytes_to_complete = packet_length - current_offset; + + new_ip_len = htons(bytes_to_complete + PACKET_HEADER_SIZE); memcpy(current_buffer_header_ptr + offsetof(struct ip, ip_len), &new_ip_len, SIZEOF_FIELD(struct ip, ip_len)); HANDLE_CHECKSUM(current_buffer_header_ptr, prepend_size + PACKET_HEADER_SIZE + bytes_to_complete, prepend_size) @@ -196,7 +222,15 @@ inline void swiftnet_send_packet( , const uint16_t request_packet_id #endif ) { - const uint32_t mtu = MIN(target_maximum_transmission_unit, maximum_transmission_unit); + uint32_t mtu; + uint32_t chunk_amount; + uint16_t packet_id; + #ifdef SWIFT_NET_REQUESTS + uint8_t packet_type; + #endif + + + mtu = MIN(target_maximum_transmission_unit, maximum_transmission_unit); #ifdef SWIFT_NET_DEBUG if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_SENDING)) { @@ -205,7 +239,6 @@ inline void swiftnet_send_packet( #endif #ifdef SWIFT_NET_REQUESTS - uint16_t packet_id; if (response == true) { packet_id = request_packet_id; } else { @@ -213,11 +246,14 @@ inline void swiftnet_send_packet( } if (request_sent != NULL) { + uint16_t* hashmap_key_mem; + + request_sent->packet_id = packet_id; LOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); - uint16_t* const restrict hashmap_key_mem = allocator_allocate(&uint16_memory_allocator); + hashmap_key_mem = allocator_allocate(&uint16_memory_allocator); *hashmap_key_mem = packet_id; hashmap_insert(hashmap_key_mem, sizeof(uint16_t), request_sent, &requests_sent); @@ -225,17 +261,31 @@ inline void swiftnet_send_packet( UNLOCK_ATOMIC_DATA_TYPE(&requests_sent.atomic_lock); } #else - const uint16_t packet_id = rand(); + packet_id = rand(); #endif #ifdef SWIFT_NET_REQUESTS - const uint8_t packet_type = response ? RESPONSE : request_sent == NULL ? MESSAGE : REQUEST; + packet_type = response ? RESPONSE : request_sent == NULL ? MESSAGE : REQUEST; #endif - const uint32_t chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); + chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); if(packet_length > mtu) { - struct SwiftNetPacketInfo packet_info = construct_packet_info( + struct SwiftNetPacketInfo packet_info; + struct ip ip_header; + uint16_t net_order_len; + struct SwiftNetPacketSending* new_packet_sending; + uint16_t* key_data_mem; + uint8_t temp_data_buffer[prepend_size + PACKET_HEADER_SIZE]; + uint8_t prepend_buffer[prepend_size + PACKET_HEADER_SIZE]; + uint32_t i; + uint32_t current_offset; + uint8_t* buffer_header_location; + uint16_t bytes_to_send; + uint16_t bytes_to_send_net_order; + + + packet_info = construct_packet_info( packet_length, #ifdef SWIFT_NET_REQUESTS packet_type, @@ -247,12 +297,12 @@ inline void swiftnet_send_packet( port_info ); - struct ip ip_header = construct_ip_header(*target_addr, mtu, packet_id); + ip_header = construct_ip_header(*target_addr, mtu, packet_id); - const uint16_t net_order_len = htons(mtu + prepend_size); + net_order_len = htons(mtu + prepend_size); ip_header.ip_len = net_order_len; - struct SwiftNetPacketSending* const new_packet_sending = allocator_allocate(packets_sending_memory_allocator); + new_packet_sending = allocator_allocate(packets_sending_memory_allocator); if(unlikely(new_packet_sending == NULL)) { PRINT_ERROR("Failed to send a packet: exceeded maximum amount of sending packets at the same time"); return; @@ -260,14 +310,15 @@ inline void swiftnet_send_packet( LOCK_ATOMIC_DATA_TYPE(&packets_sending->atomic_lock); - uint16_t* const key_data_mem = allocator_allocate(&uint16_memory_allocator); + key_data_mem = allocator_allocate(&uint16_memory_allocator); *key_data_mem = packet_id; - new_packet_sending->lost_chunks = NULL; - new_packet_sending->locked = false; - new_packet_sending->lost_chunks = NULL; - new_packet_sending->lost_chunks_size = 0; - new_packet_sending->packet_id = packet_id; + *new_packet_sending = (struct SwiftNetPacketSending){ + .locked = false, + .lost_chunks = NULL, + .lost_chunks_size = 0, + .packet_id = packet_id, + }; atomic_store_explicit(&new_packet_sending->current_send_delay, 50, memory_order_release); atomic_store_explicit(&new_packet_sending->updated, NO_UPDATE, memory_order_release); @@ -276,24 +327,22 @@ inline void swiftnet_send_packet( UNLOCK_ATOMIC_DATA_TYPE(&packets_sending->atomic_lock); - uint8_t temp_data_buffer[prepend_size + PACKET_HEADER_SIZE]; + if (addr_type == DLT_NULL) { + uint32_t family; - uint8_t prepend_buffer[prepend_size + PACKET_HEADER_SIZE]; - if (addr_type == DLT_NULL) { - // Loopback interface - const uint32_t family = PF_INET; \ - memcpy(prepend_buffer, &family, sizeof(family)); \ - memcpy(prepend_buffer+ sizeof(family), &ip_header, sizeof(ip_header)); \ - memcpy(prepend_buffer + sizeof(family) + sizeof(ip_header), &packet_info, sizeof(packet_info)); \ + family = PF_INET; + memcpy(prepend_buffer, &family, sizeof(family)); + memcpy(prepend_buffer + sizeof(family), &ip_header, sizeof(ip_header)); + memcpy(prepend_buffer + sizeof(family) + sizeof(ip_header), &packet_info, sizeof(packet_info)); } else if (addr_type == DLT_EN10MB) { - memcpy(prepend_buffer, ð_hdr, sizeof(eth_hdr)); \ - memcpy(prepend_buffer+ sizeof(eth_hdr), &ip_header, sizeof(ip_header)); \ - memcpy(prepend_buffer + sizeof(eth_hdr) + sizeof(ip_header), &packet_info, sizeof(packet_info)); \ + memcpy(prepend_buffer, ð_hdr, sizeof(eth_hdr)); + memcpy(prepend_buffer + sizeof(eth_hdr), &ip_header, sizeof(ip_header)); + memcpy(prepend_buffer + sizeof(eth_hdr) + sizeof(ip_header), &packet_info, sizeof(packet_info)); } - for(uint32_t i = 0; ; i++) { - const uint32_t current_offset = i * (mtu - PACKET_HEADER_SIZE); + for(i = 0; ; i++) { + current_offset = i * (mtu - PACKET_HEADER_SIZE); #ifdef SWIFT_NET_DEBUG if (check_debug_flag(SWIFTNET_DEBUG_PACKETS_SENDING)) { @@ -301,9 +350,8 @@ inline void swiftnet_send_packet( } #endif - uint8_t* const buffer_header_location = packet->packet_data_start + current_offset - prepend_size - PACKET_HEADER_SIZE; + buffer_header_location = packet->packet_data_start + current_offset - prepend_size - PACKET_HEADER_SIZE; - // Copy data into temp storage memcpy(temp_data_buffer, buffer_header_location, prepend_size + PACKET_HEADER_SIZE); memcpy(buffer_header_location, prepend_buffer, prepend_size + PACKET_HEADER_SIZE); @@ -313,10 +361,9 @@ inline void swiftnet_send_packet( memset(buffer_header_location + sizeof(struct ip) + prepend_size + offsetof(struct SwiftNetPacketInfo, checksum), 0x00, SIZEOF_FIELD(struct SwiftNetPacketInfo, checksum)); if(current_offset + (mtu - PACKET_HEADER_SIZE) >= packet_info.packet_length) { - const uint16_t bytes_to_send = (uint16_t)(packet_length - current_offset + PACKET_HEADER_SIZE + prepend_size); + bytes_to_send = (uint16_t)(packet_length - current_offset + PACKET_HEADER_SIZE + prepend_size); - // Last chunk - const uint16_t bytes_to_send_net_order = htons(bytes_to_send - prepend_size); + bytes_to_send_net_order = htons(bytes_to_send - prepend_size); memcpy(buffer_header_location + prepend_size + offsetof(struct ip, ip_len), &bytes_to_send_net_order, SIZEOF_FIELD(struct ip, ip_len)); @@ -335,7 +382,7 @@ inline void swiftnet_send_packet( break; } else { - const uint16_t bytes_to_send = prepend_size + mtu; + bytes_to_send = prepend_size + mtu; HANDLE_CHECKSUM(buffer_header_location, bytes_to_send, prepend_size) @@ -347,9 +394,14 @@ inline void swiftnet_send_packet( } } } else { - const uint32_t final_packet_size = prepend_size + PACKET_HEADER_SIZE + packet_length; + uint32_t final_packet_size; + struct SwiftNetPacketInfo packet_info; + struct ip ip_header; + + + final_packet_size = prepend_size + PACKET_HEADER_SIZE + packet_length; - const struct SwiftNetPacketInfo packet_info = construct_packet_info( + packet_info = construct_packet_info( packet_length, #ifdef SWIFT_NET_REQUESTS packet_type, @@ -361,10 +413,13 @@ inline void swiftnet_send_packet( port_info ); - const struct ip ip_header = construct_ip_header(*target_addr, final_packet_size - prepend_size, packet_id); + ip_header = construct_ip_header(*target_addr, final_packet_size - prepend_size, packet_id); if(addr_type == DLT_NULL) { - uint32_t family = PF_INET; + uint32_t family; + + + family = PF_INET; memcpy(packet->packet_buffer_start + sizeof(struct ether_header) - sizeof(family), &family, sizeof(family)); memcpy(packet->packet_buffer_start + sizeof(struct ether_header), &ip_header, sizeof(ip_header)); memcpy(packet->packet_buffer_start + sizeof(struct ether_header) + sizeof(struct ip), &packet_info, sizeof(packet_info)); @@ -388,8 +443,11 @@ inline void swiftnet_send_packet( } } -void swiftnet_client_send_packet(struct SwiftNetClientConnection* const client, struct SwiftNetPacketBuffer* const packet) { - const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; +void swiftnet_client_send_packet(struct SwiftNetClientConnection* const client, struct SwiftNetPacketBuffer* restrict const packet) { + uint32_t packet_length; + + + packet_length = packet->packet_append_pointer - packet->packet_data_start; swiftnet_send_packet(client, client->maximum_transmission_unit, client->port_info, packet, packet_length, &client->server_addr, &client->packets_sending, &client->packets_sending_memory_allocator, client->pcap, client->eth_header, client->loopback, client->addr_type, client->prepend_size #ifdef SWIFT_NET_REQUESTS @@ -398,15 +456,19 @@ void swiftnet_client_send_packet(struct SwiftNetClientConnection* const client, ); } -void swiftnet_server_send_packet(struct SwiftNetServer* const server, struct SwiftNetPacketBuffer* const packet, const struct SwiftNetClientAddrData target) { - const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; +void swiftnet_server_send_packet(struct SwiftNetServer* const server, struct SwiftNetPacketBuffer* restrict const packet, const struct SwiftNetClientAddrData target) { + uint32_t packet_length; + struct SwiftNetPortInfo port_info; + struct ether_header eth_hdr; + - const struct SwiftNetPortInfo port_info = { + packet_length = packet->packet_append_pointer - packet->packet_data_start; + + port_info = (struct SwiftNetPortInfo){ .destination_port = target.port, .source_port = server->server_port }; - struct ether_header eth_hdr; memcpy(ð_hdr, &server->eth_header, sizeof(eth_hdr)); memcpy(ð_hdr.ether_dhost, &target.mac_address, sizeof(eth_hdr.ether_dhost)); diff --git a/src/swift_net.h b/src/swift_net.h index c4c1cdb..738a27a 100644 --- a/src/swift_net.h +++ b/src/swift_net.h @@ -328,9 +328,9 @@ extern void swiftnet_client_set_message_handler( ); // Append data to a packet buffer. extern void swiftnet_append_to_buffer( - const void* const data, + const void* restrict const data, const uint32_t data_size, - struct SwiftNetPacketBuffer* const buffer + struct SwiftNetPacketBuffer* restrict const buffer ); // Clean up and free resources for a client connection. @@ -345,13 +345,13 @@ extern void swiftnet_initialize(); // Send a packet from the client to its connected server. extern void swiftnet_client_send_packet( struct SwiftNetClientConnection* const client, - struct SwiftNetPacketBuffer* const packet + struct SwiftNetPacketBuffer* restrict const packet ); // Send a packet from the server to a specified client. extern void swiftnet_server_send_packet( struct SwiftNetServer* const server, - struct SwiftNetPacketBuffer* const packet, + struct SwiftNetPacketBuffer* restrict const packet, const struct SwiftNetClientAddrData target ); @@ -360,13 +360,13 @@ extern void swiftnet_server_send_packet( extern struct SwiftNetPacketBuffer swiftnet_create_packet_buffer(const uint32_t buffer_size); // Resizes packet buffer. -extern void swiftnet_resize_packet_buffer(const uint32_t new_buffer_size, struct SwiftNetPacketBuffer* const); +extern void swiftnet_resize_packet_buffer(uint32_t new_buffer_size, struct SwiftNetPacketBuffer* restrict const); // Writes to packet buffer at specific offset -extern void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* const, void* const data, const uint32_t data_size); +extern void swiftnet_write_packet_buffer(const uint32_t byte_offset, struct SwiftNetPacketBuffer* restrict const, void* restrict const data, const uint32_t data_size); // Destroy a packet buffer and free resources. -extern void swiftnet_destroy_packet_buffer(const struct SwiftNetPacketBuffer* const packet); +extern void swiftnet_destroy_packet_buffer(const struct SwiftNetPacketBuffer* restrict const packet); // Create and initialize a server. extern struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool loopback); @@ -379,20 +379,20 @@ extern struct SwiftNetClientConnection* swiftnet_create_client( ); // Read data from a client packet. -extern void* swiftnet_client_read_packet(struct SwiftNetClientPacketData* const packet_data, const uint32_t data_size); +extern void* swiftnet_client_read_packet(struct SwiftNetClientPacketData* restrict const packet_data, const uint32_t data_size); // Read data from a server packet. -extern void* swiftnet_server_read_packet(struct SwiftNetServerPacketData* const packet_data, const uint32_t data_size); +extern void* swiftnet_server_read_packet(struct SwiftNetServerPacketData* restrict const packet_data, const uint32_t data_size); // Destroy client packet data and release memory. extern void swiftnet_client_destroy_packet_data( - struct SwiftNetClientPacketData* const packet_data, + struct SwiftNetClientPacketData* restrict const packet_data, struct SwiftNetClientConnection* const client_conn ); // Destroy server packet data and release memory. extern void swiftnet_server_destroy_packet_data( - struct SwiftNetServerPacketData* const packet_data, + struct SwiftNetServerPacketData* restrict const packet_data, struct SwiftNetServer* const server ); @@ -404,14 +404,14 @@ extern void swiftnet_cleanup(); // Make a request from a client and wait for a response. extern struct SwiftNetClientPacketData* swiftnet_client_make_request( struct SwiftNetClientConnection* const client, - struct SwiftNetPacketBuffer* const packet, + struct SwiftNetPacketBuffer* restrict const packet, const uint32_t timeout_ms ); // Make a request from the server to a specific client and wait for response. extern struct SwiftNetServerPacketData* swiftnet_server_make_request( struct SwiftNetServer* const server, - struct SwiftNetPacketBuffer* const packet, + struct SwiftNetPacketBuffer* restrict const packet, const struct SwiftNetClientAddrData addr_data, const uint32_t timeout_ms ); @@ -420,14 +420,14 @@ extern struct SwiftNetServerPacketData* swiftnet_server_make_request( extern void swiftnet_client_make_response( struct SwiftNetClientConnection* const client, struct SwiftNetClientPacketData* const packet_data, - struct SwiftNetPacketBuffer* const buffer + struct SwiftNetPacketBuffer* restrict const buffer ); // Send a response from the server. extern void swiftnet_server_make_response( struct SwiftNetServer* const server, struct SwiftNetServerPacketData* const packet_data, - struct SwiftNetPacketBuffer* const buffer + struct SwiftNetPacketBuffer* restrict const buffer ); #endif diff --git a/tests/performance_tests/src/main.c b/tests/performance_tests/src/main.c index ca54208..38e85c3 100644 --- a/tests/performance_tests/src/main.c +++ b/tests/performance_tests/src/main.c @@ -8,11 +8,11 @@ #include "../../shared.h" -#define PACKET_SIZE 1000000 // 1 MILLION BYTES -#define PACKETS_TO_SEND 50 // HOW MANY PACKETS TO SEND +//#define PACKET_SIZE 1000000 // 1 MILLION BYTES +//#define PACKETS_TO_SEND 50 // HOW MANY PACKETS TO SEND -//#define PACKET_SIZE 100000000 // 100 MILLION BYTES -//#define PACKETS_TO_SEND 1 // HOW MANY PACKETS TO SEND +#define PACKET_SIZE 100000000 // 100 MILLION BYTES +#define PACKETS_TO_SEND 1 // HOW MANY PACKETS TO SEND // ********************** // // SEND 100 MILLION BYTES //