diff --git a/src/cleanup.c b/src/cleanup.c index ad0bb4f..c3cb606 100644 --- a/src/cleanup.c +++ b/src/cleanup.c @@ -3,19 +3,7 @@ #include #include -void swiftnet_cleanup() { - allocator_destroy(&packet_queue_node_memory_allocator); - allocator_destroy(&packet_callback_queue_node_memory_allocator); - allocator_destroy(&server_packet_data_memory_allocator); - allocator_destroy(&client_packet_data_memory_allocator); - allocator_destroy(&packet_buffer_memory_allocator); - - #ifdef SWIFT_NET_REQUESTS - allocator_destroy(&requests_sent_memory_allocator); - - vector_destroy(&requests_sent); - #endif - +static inline void close_listeners() { vector_lock(&listeners); for (uint16_t i = 0; i < listeners.size; i++) { @@ -32,7 +20,23 @@ void swiftnet_cleanup() { } vector_destroy(&listeners); +} + +void swiftnet_cleanup() { + allocator_destroy(&packet_queue_node_memory_allocator); + allocator_destroy(&packet_callback_queue_node_memory_allocator); + allocator_destroy(&server_packet_data_memory_allocator); + allocator_destroy(&client_packet_data_memory_allocator); + allocator_destroy(&packet_buffer_memory_allocator); + + #ifdef SWIFT_NET_REQUESTS + allocator_destroy(&requests_sent_memory_allocator); + + vector_destroy(&requests_sent); + #endif + close_listeners(); + allocator_destroy(&server_memory_allocator); allocator_destroy(&client_connection_memory_allocator); diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index bd876ff..fc52b3d 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -4,94 +4,119 @@ #include #include -void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) { - allocator_destroy(&client->packets_sending_memory_allocator); - allocator_destroy(&client->pending_messages_memory_allocator); - allocator_destroy(&client->packets_completed_memory_allocator); - - vector_destroy(&client->packets_sending); - vector_destroy(&client->pending_messages); - vector_destroy(&client->packets_completed); - - const char* interface_name = client->loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface; +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; + + allocator_destroy(&client->packets_sending_memory_allocator); + allocator_destroy(&client->pending_messages_memory_allocator); + allocator_destroy(&client->packets_completed_memory_allocator); + + vector_destroy(&client->packets_sending); + vector_destroy(&client->pending_messages); + vector_destroy(&client->packets_completed); + } else { + struct SwiftNetServer* const server = (struct SwiftNetServer*)connection; + + allocator_destroy(&server->packets_sending_memory_allocator); + allocator_destroy(&server->pending_messages_memory_allocator); + allocator_destroy(&server->packets_completed_memory_allocator); + + vector_destroy(&server->packets_sending); + vector_destroy(&server->pending_messages); + vector_destroy(&server->packets_completed); + } +} +static inline void remove_listener(const enum ConnectionType connection_type, const char* interface_name, void* const connection) { vector_lock(&listeners); for (uint16_t i = 0; i < listeners.size; i++) { struct Listener* const current_listener = vector_get(&listeners, i); if (strcmp(interface_name, current_listener->interface_name) == 0) { - vector_lock(¤t_listener->client_connections); + if (connection_type == CONNECTION_TYPE_CLIENT) { + vector_lock(¤t_listener->client_connections); - for (uint16_t inx = 0; inx < current_listener->client_connections.size; inx++) { - struct SwiftNetClientConnection* const current_client_conn = vector_get(¤t_listener->client_connections, i); - if (current_client_conn != client) { - continue; + for (uint16_t inx = 0; inx < current_listener->client_connections.size; inx++) { + struct SwiftNetClientConnection* const current_connection = vector_get(¤t_listener->client_connections, i); + if (current_connection != connection) { + continue; + } + + vector_remove(¤t_listener->client_connections, inx); + + break; } - vector_remove(¤t_listener->client_connections, inx); + vector_unlock(¤t_listener->client_connections); + } else { + vector_lock(¤t_listener->servers); - break; - } + for (uint16_t inx = 0; inx < current_listener->servers.size; inx++) { + struct SwiftNetClientConnection* const current_connection = vector_get(¤t_listener->servers, i); + if (current_connection != connection) { + continue; + } + + vector_remove(¤t_listener->servers, inx); - vector_unlock(¤t_listener->client_connections); + break; + } + + vector_unlock(¤t_listener->servers); + } break; } } vector_unlock(&listeners); +} - atomic_store_explicit(&client->closing, true, memory_order_release); - - pthread_join(client->process_packets_thread, NULL); - pthread_join(client->execute_callback_thread, NULL); - - pcap_close(client->pcap); - - allocator_free(&client_connection_memory_allocator, client); +static inline const char* get_interface_name(const bool loopback) { + return loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface; } -void swiftnet_server_cleanup(struct SwiftNetServer* const server) { - allocator_destroy(&server->packets_sending_memory_allocator); - allocator_destroy(&server->pending_messages_memory_allocator); - allocator_destroy(&server->packets_completed_memory_allocator); +static inline void close_threads(const enum ConnectionType connection_type, void* const connection) { + if (connection_type == CONNECTION_TYPE_CLIENT) { + struct SwiftNetClientConnection* const client = connection; - vector_destroy(&server->packets_sending); - vector_destroy(&server->pending_messages); - vector_destroy(&server->packets_completed); + atomic_store_explicit(&client->closing, true, memory_order_release); - const char* interface_name = server->loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface; + pthread_join(client->process_packets_thread, NULL); + pthread_join(client->execute_callback_thread, NULL); + } else { + struct SwiftNetServer* const server = connection; - vector_lock(&listeners); + atomic_store_explicit(&server->closing, true, memory_order_release); - for (uint16_t i = 0; i < listeners.size; i++) { - struct Listener* const current_listener = vector_get(&listeners, i); - if (strcmp(interface_name, current_listener->interface_name) == 0) { - vector_lock(¤t_listener->servers); + pthread_join(server->process_packets_thread, NULL); + pthread_join(server->execute_callback_thread, NULL); + } +} - for (uint16_t inx = 0; inx < current_listener->servers.size; inx++) { - struct SwiftNetServer* const current_server = vector_get(¤t_listener->servers, i); - if (current_server != server) { - continue; - } +void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) { + cleanup_connection_resources(CONNECTION_TYPE_CLIENT, client); + + const char* interface_name = get_interface_name(client->loopback); - vector_remove(¤t_listener->servers, inx); + remove_listener(CONNECTION_TYPE_CLIENT, interface_name, client); - break; - } + close_threads(CONNECTION_TYPE_CLIENT, client); - vector_unlock(¤t_listener->servers); + pcap_close(client->pcap); - break; - } - } + allocator_free(&client_connection_memory_allocator, client); +} - vector_unlock(&listeners); +void swiftnet_server_cleanup(struct SwiftNetServer* const server) { + cleanup_connection_resources(CONNECTION_TYPE_SERVER, server); + + const char* interface_name = get_interface_name(server->loopback); - atomic_store_explicit(&server->closing, true, memory_order_release); + remove_listener(CONNECTION_TYPE_SERVER, interface_name, server); - pthread_join(server->process_packets_thread, NULL); - pthread_join(server->execute_callback_thread, NULL); + close_threads(CONNECTION_TYPE_SERVER, server); pcap_close(server->pcap); diff --git a/src/execute_packet_callback.c b/src/execute_packet_callback.c index 0019b6a..f5ea3b1 100644 --- a/src/execute_packet_callback.c +++ b/src/execute_packet_callback.c @@ -7,11 +7,15 @@ #include #include -static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) { +static inline void lock_packet_queue(struct PacketCallbackQueue* const packet_queue) { uint32_t owner_none = PACKET_CALLBACK_QUEUE_OWNER_NONE; while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, PACKET_CALLBACK_QUEUE_OWNER_EXECUTE_PACKET_CALLBACK, memory_order_acquire, memory_order_relaxed)) { owner_none = PACKET_CALLBACK_QUEUE_OWNER_NONE; } +} + +static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struct PacketCallbackQueue* const packet_queue) { + lock_packet_queue(packet_queue); if(packet_queue->first_node == NULL) { atomic_store_explicit(&packet_queue->owner, PACKET_CALLBACK_QUEUE_OWNER_NONE, memory_order_release); @@ -36,6 +40,19 @@ static struct PacketCallbackQueueNode* const wait_for_next_packet_callback(struc return node_to_process; } +static inline void remove_pending_message_from_vector(struct SwiftNetVector* const pending_messages, struct SwiftNetPendingMessage* const pending_message) { + vector_lock(pending_messages); + + for (uint32_t i = 0; i < pending_messages->size; i++) { + const struct SwiftNetPendingMessage* const current_pending_message = vector_get(pending_messages, i); + if (current_pending_message == pending_message) { + vector_remove(pending_messages, i); + } + } + + vector_unlock(pending_messages); +} + 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 SwiftNetVector* const pending_messages, _Atomic(void*)* user_data) { while (1) { if (atomic_load_explicit(closing, memory_order_acquire) == true) { @@ -55,16 +72,7 @@ void execute_packet_callback(struct PacketCallbackQueue* const queue, void (* co } if(node->pending_message != NULL) { - vector_lock(pending_messages); - - for (uint32_t i = 0; i < pending_messages->size; i++) { - const struct SwiftNetPendingMessage* const pending_message = vector_get(pending_messages, i); - if (pending_message == node->pending_message) { - vector_remove(pending_messages, i); - } - } - - vector_unlock(pending_messages); + remove_pending_message_from_vector(pending_messages, node->pending_message); } void (*const packet_handler_loaded)(void* const, void* const) = atomic_load(packet_handler); diff --git a/src/handle_packets.c b/src/handle_packets.c index 5b96ffc..d91317f 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -10,15 +10,23 @@ #include "internal/internal.h" #include +static inline void lock_packet_queue(struct PacketQueue* const packet_queue) { + uint32_t owner_none = PACKET_QUEUE_OWNER_NONE; + while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, PACKET_QUEUE_OWNER_HANDLE_PACKETS, memory_order_acquire, memory_order_relaxed)) { + owner_none = PACKET_QUEUE_OWNER_NONE; + } +} + +static inline void unlock_packet_queue(struct PacketQueue* const packet_queue) { + atomic_store_explicit(&packet_queue->owner, PACKET_QUEUE_OWNER_NONE, memory_order_release); +} + static inline void insert_queue_node(struct PacketQueueNode* const new_node, struct PacketQueue* const packet_queue, const enum ConnectionType contype) { if(new_node == NULL) { return; } - uint32_t owner_none = PACKET_QUEUE_OWNER_NONE; - while(!atomic_compare_exchange_strong_explicit(&packet_queue->owner, &owner_none, PACKET_QUEUE_OWNER_HANDLE_PACKETS, memory_order_acquire, memory_order_relaxed)) { - owner_none = PACKET_QUEUE_OWNER_NONE; - } + lock_packet_queue(packet_queue); if(packet_queue->last_node == NULL) { packet_queue->last_node = new_node; @@ -32,53 +40,55 @@ static inline void insert_queue_node(struct PacketQueueNode* const new_node, str packet_queue->first_node = new_node; } - atomic_store_explicit(&packet_queue->owner, PACKET_QUEUE_OWNER_NONE, memory_order_release); + unlock_packet_queue(packet_queue); return; } -static inline void swiftnet_handle_packets(const uint16_t source_port, pthread_t* const process_packets_thread, void* 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) { - struct PacketQueueNode *node = allocator_allocate(&packet_queue_node_memory_allocator); +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); if (unlikely(node == NULL)) { - return; + return NULL; } - uint8_t *packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); + node->data = data; + node->data_read = data_read; + node->sender_address.s_addr = sender_address; + node->next = NULL; + + return node; +} + +static inline void swiftnet_handle_packets(const uint16_t source_port, pthread_t* const process_packets_thread, void* 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) { + uint8_t* const packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); if (unlikely(packet_buffer == NULL)) { - allocator_free(&packet_queue_node_memory_allocator, node); return; } - uint32_t len = hdr->caplen; + const uint32_t len = hdr->caplen; memcpy(packet_buffer, packet, len); - if (len == 0) { - allocator_free(&packet_queue_node_memory_allocator, node); + if (unlikely(len == 0)) { allocator_free(&packet_buffer_memory_allocator, packet_buffer); return; } + uint32_t sender_address = 0; + if (addr_type == DLT_EN10MB) { - struct ether_header *eth = (struct ether_header *)packet_buffer; + 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)); - node->sender_address = ip_header->ip_src; + sender_address = ip_header->ip_src.s_addr; } else { - allocator_free(&packet_queue_node_memory_allocator, node); allocator_free(&packet_buffer_memory_allocator, packet_buffer); return; } - } else { - node->sender_address.s_addr = 0; } - node->data_read = len; - node->data = packet_buffer; - node->next = NULL; - - node->server_address_length = sizeof(node->sender_address); + struct PacketQueueNode* const node = construct_node(len, packet_buffer, sender_address); atomic_thread_fence(memory_order_release); @@ -104,9 +114,9 @@ static void handle_client_init(struct SwiftNetClientConnection* user, const stru return; } - struct ip* ip_header = (struct ip*)(buffer + client_connection->prepend_size); - struct SwiftNetPacketInfo* packet_info = (struct SwiftNetPacketInfo*)(buffer + client_connection->prepend_size + sizeof(struct ip)); - struct SwiftNetServerInformation* server_information = (struct SwiftNetServerInformation*)(buffer + client_connection->prepend_size + sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo)); + struct ip* const ip_header = (struct ip*)(buffer + client_connection->prepend_size); + 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)); 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 @@ -132,44 +142,53 @@ static void handle_client_init(struct SwiftNetClientConnection* user, const stru atomic_store_explicit(&client_connection->initialized, true, memory_order_release); } -static void pcap_packet_handle(uint8_t* user, const struct pcap_pkthdr* hdr, const uint8_t* packet) { - struct Listener* const listener = (struct Listener*)user; +static inline void handle_correct_receiver(const enum ConnectionType connection_type, struct Listener* const listener, const struct pcap_pkthdr* const hdr, const uint8_t* const packet, const struct SwiftNetPortInfo* const port_info) { + if (connection_type == CONNECTION_TYPE_CLIENT) { + vector_lock(&listener->client_connections); - struct SwiftNetPortInfo* const port_info = (struct SwiftNetPortInfo*)(packet + PACKET_PREPEND_SIZE(listener->addr_type) + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, port_info)); + for (uint16_t i = 0; i < listener->client_connections.size; i++) { + struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i); + if (client_connection->port_info.source_port == port_info->destination_port) { + vector_unlock(&listener->client_connections); - vector_lock(&listener->servers); + if (client_connection->initialized == false) { + handle_client_init(client_connection, hdr, packet); + } else { + swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet); + } - for (uint16_t i = 0; i < listener->servers.size; i++) { - struct SwiftNetServer* const server = vector_get(&listener->servers, i); - if (server->server_port == port_info->destination_port) { - vector_unlock(&listener->servers); - - swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet); - - return; + return; + } } - } - vector_unlock(&listener->servers); + vector_unlock(&listener->client_connections); + } else { + vector_lock(&listener->servers); - vector_lock(&listener->client_connections); + for (uint16_t i = 0; i < listener->servers.size; i++) { + struct SwiftNetServer* const server = vector_get(&listener->servers, i); + if (server->server_port == port_info->destination_port) { + vector_unlock(&listener->servers); - for (uint16_t i = 0; i < listener->client_connections.size; i++) { - struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i); - if (client_connection->port_info.source_port == port_info->destination_port) { - vector_unlock(&listener->client_connections); + swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet); - if (client_connection->initialized == false) { - handle_client_init(client_connection, hdr, packet); - } else { - swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet); + return; } - - return; } + + vector_unlock(&listener->servers); } +} + +static void pcap_packet_handle(uint8_t* const user, const struct pcap_pkthdr* const hdr, const uint8_t* const packet) { + printf("Received packet\n"); + + struct Listener* const listener = (struct Listener*)user; + + struct SwiftNetPortInfo* const port_info = (struct SwiftNetPortInfo*)(packet + PACKET_PREPEND_SIZE(listener->addr_type) + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, port_info)); - vector_unlock(&listener->client_connections); + 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) { diff --git a/src/initialize_client_socket.c b/src/initialize_client_socket.c index 99bf673..1315feb 100644 --- a/src/initialize_client_socket.c +++ b/src/initialize_client_socket.c @@ -64,49 +64,74 @@ void* request_server_information(void* const request_server_information_args_voi return NULL; } - - -struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_address, const uint16_t port, const uint32_t timeout_ms) { +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 in_addr addr; - inet_aton(ip_address, &addr); - const uint32_t ip = ntohl(addr.s_addr); - const bool loopback = (ip >> 24) == 127; - - new_connection->loopback = loopback; - - new_connection->pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); - if (new_connection->pcap == NULL) { - PRINT_ERROR("Failed to open bpf"); - exit(EXIT_FAILURE); - } - - new_connection->addr_type = pcap_datalink(new_connection->pcap); - - const uint16_t clientPort = rand(); + struct ether_header eth_header = { + .ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, + .ether_type = htons(0x0800) + }; - const uint8_t prepend_size = PACKET_PREPEND_SIZE(new_connection->addr_type); + memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); - new_connection->prepend_size = prepend_size; + 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->pending_messages = vector_create(100); + new_connection->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100); + new_connection->packets_sending = vector_create(100); + new_connection->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); + new_connection->packets_completed = vector_create(100); + new_connection->packet_queue = (struct PacketQueue){ .first_node = NULL, .last_node = NULL }; - atomic_store(&new_connection->packet_queue.owner, PACKET_QUEUE_OWNER_NONE); + atomic_store_explicit(&new_connection->packet_queue.owner, PACKET_QUEUE_OWNER_NONE, 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)); + atomic_store_explicit(&new_connection->packet_callback_queue.owner, PACKET_CALLBACK_QUEUE_OWNER_NONE, memory_order_release); - new_connection->server_addr_len = sizeof(new_connection->server_addr); + return new_connection; +} - new_connection->port_info.destination_port = port; - new_connection->port_info.source_port = clientPort; +static inline void remove_con_from_listener(const struct SwiftNetClientConnection* const con, struct Listener* const listener) { + vector_lock(&listener->client_connections); - new_connection->packet_handler = NULL; + for (uint16_t i = 0; i < listener->client_connections.size; i++) { + struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i); + if (client_connection == con) { + vector_remove(&listener->client_connections, i); + } + } + + vector_unlock(&listener->client_connections); +} - new_connection->server_addr.s_addr = inet_addr(ip_address); +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; - atomic_store_explicit(&new_connection->packet_handler_user_arg, NULL, memory_order_release); + pcap_t* const pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + if (unlikely(pcap == NULL)) { + PRINT_ERROR("Failed to open bpf"); + exit(EXIT_FAILURE); + } + + 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( @@ -117,39 +142,23 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add new_connection->port_info ); - 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; - 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_PACKET_CONSTRUCTION(&request_server_info_ip_header, &request_server_information_packet_info, new_connection->addr_type, ð_header, PACKET_HEADER_SIZE + prepend_size, request_server_info_buffer) - - HANDLE_CHECKSUM(request_server_info_buffer, sizeof(request_server_info_buffer), prepend_size) - - memset(&new_connection->packet_callback_queue, 0x00, sizeof(struct PacketCallbackQueue)); - atomic_store(&new_connection->packet_callback_queue.owner, PACKET_CALLBACK_QUEUE_OWNER_NONE); + 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 = new_connection->pcap, + .pcap = pcap, .data = request_server_info_buffer, .size = sizeof(request_server_info_buffer), - .server_addr = new_connection->server_addr, + .server_addr = addr, .timeout_ms = timeout_ms, .connection = new_connection }; - atomic_store_explicit(&new_connection->closing, false, memory_order_release); - - atomic_store_explicit(&new_connection->initialized, false, memory_order_release); - 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); @@ -159,31 +168,15 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add if (atomic_load_explicit(&new_connection->initialized, memory_order_acquire) == false) { atomic_store_explicit(&new_connection->closing, true, memory_order_release); - vector_lock(&listener->client_connections); - pcap_close(new_connection->pcap); allocator_free(&client_connection_memory_allocator, new_connection); - for (uint16_t i = 0; i < listener->client_connections.size; i++) { - struct SwiftNetClientConnection* const client_connection = vector_get(&listener->client_connections, i); - if (client_connection == new_connection) { - vector_remove(&listener->client_connections, i); - } - } - - vector_unlock(&listener->client_connections); - + remove_con_from_listener(new_connection, listener); + return NULL; } - new_connection->pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 100); - new_connection->pending_messages = vector_create(100); - new_connection->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100); - new_connection->packets_sending = vector_create(100); - new_connection->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); - new_connection->packets_completed = vector_create(100); - 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); diff --git a/src/initialize_server_socket.c b/src/initialize_server_socket.c index ff943e0..a74bead 100644 --- a/src/initialize_server_socket.c +++ b/src/initialize_server_socket.c @@ -13,30 +13,9 @@ #include "internal/internal.h" #include "swift_net.h" -struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool loopback) { +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); - #ifdef SWIFT_NET_ERROR - if(unlikely(new_server == NULL)) { - PRINT_ERROR("Failed to get an empty server"); - exit(EXIT_FAILURE); - } - #endif - - new_server->server_port = port; - new_server->loopback = loopback; - - // Init pcap device - new_server->pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); - if (new_server->pcap == NULL) { - PRINT_ERROR("Failed to open bpf"); - exit(EXIT_FAILURE); - } - - new_server->addr_type = pcap_datalink(new_server->pcap); - - new_server->prepend_size = PACKET_PREPEND_SIZE(new_server->addr_type); - struct ether_header eth_header = { .ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, .ether_type = htons(0x0800) @@ -45,19 +24,23 @@ struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool lo memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); new_server->eth_header = eth_header; - + new_server->server_port = server_port; + new_server->loopback = loopback; + new_server->pcap = pcap; + new_server->addr_type = pcap_datalink(pcap); + new_server->prepend_size = PACKET_PREPEND_SIZE(new_server->addr_type); new_server->packet_queue = (struct PacketQueue){ .first_node = NULL, .last_node = NULL }; - atomic_store(&new_server->packet_queue.owner, PACKET_QUEUE_OWNER_NONE); - memset(&new_server->packet_callback_queue, 0x00, sizeof(struct PacketCallbackQueue)); - atomic_store_explicit(&new_server->packet_callback_queue.owner, PACKET_CALLBACK_QUEUE_OWNER_NONE, memory_order_release); + atomic_store_explicit(&new_server->packet_queue.owner, PACKET_QUEUE_OWNER_NONE, memory_order_release); + atomic_store_explicit(&new_server->packet_callback_queue.owner, PACKET_CALLBACK_QUEUE_OWNER_NONE, memory_order_release); atomic_store_explicit(&new_server->packet_handler, NULL, memory_order_release); atomic_store_explicit(&new_server->packet_handler_user_arg, NULL, memory_order_release); + atomic_store_explicit(&new_server->closing, false, memory_order_release); new_server->pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 100); new_server->pending_messages = vector_create(100); @@ -66,10 +49,22 @@ struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool lo new_server->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); new_server->packets_completed = vector_create(100); - atomic_store_explicit(&new_server->closing, false, memory_order_release); + return new_server; +} + +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); + if (unlikely(pcap == NULL)) { + PRINT_ERROR("Failed to open bpf"); + exit(EXIT_FAILURE); + } + + struct SwiftNetServer* const 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); + pthread_create(&new_server->process_packets_thread, NULL, swiftnet_server_process_packets, new_server); pthread_create(&new_server->execute_callback_thread, NULL, execute_packet_callback_server, new_server); diff --git a/src/initialize_swift_net.c b/src/initialize_swift_net.c index 61a8ae1..7fe8fef 100644 --- a/src/initialize_swift_net.c +++ b/src/initialize_swift_net.c @@ -39,6 +39,17 @@ struct SwiftNetMemoryAllocator listener_memory_allocator; struct SwiftNetVector listeners; +static inline void initialize_allocators() { + packet_queue_node_memory_allocator = allocator_create(sizeof(struct PacketQueueNode), 100); + packet_callback_queue_node_memory_allocator = allocator_create(sizeof(struct PacketCallbackQueueNode), 100); + server_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetServerPacketData), 100); + client_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetClientPacketData), 100); + packet_buffer_memory_allocator = allocator_create(maximum_transmission_unit + sizeof(struct ether_header), 100); + server_memory_allocator = allocator_create(sizeof(struct SwiftNetServer), 10); + client_connection_memory_allocator = allocator_create(sizeof(struct SwiftNetClientConnection), 10); + listener_memory_allocator = allocator_create(sizeof(struct Listener), 100); +} + void swiftnet_initialize() { const int temp_socket = socket(AF_INET, SOCK_DGRAM, 0); if (temp_socket < 0) { @@ -84,14 +95,7 @@ void swiftnet_initialize() { close(temp_socket); - packet_queue_node_memory_allocator = allocator_create(sizeof(struct PacketQueueNode), 100); - packet_callback_queue_node_memory_allocator = allocator_create(sizeof(struct PacketCallbackQueueNode), 100); - server_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetServerPacketData), 100); - client_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetClientPacketData), 100); - packet_buffer_memory_allocator = allocator_create(maximum_transmission_unit + sizeof(struct ether_header), 100); - server_memory_allocator = allocator_create(sizeof(struct SwiftNetServer), 10); - client_connection_memory_allocator = allocator_create(sizeof(struct SwiftNetClientConnection), 10); - listener_memory_allocator = allocator_create(sizeof(struct Listener), 100); + initialize_allocators(); #ifdef SWIFT_NET_REQUESTS requests_sent_memory_allocator = allocator_create(sizeof(struct RequestSent), 100); diff --git a/src/make_request.c b/src/make_request.c index 2f099a4..b56223a 100644 --- a/src/make_request.c +++ b/src/make_request.c @@ -7,10 +7,30 @@ #ifdef SWIFT_NET_REQUESTS -struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetClientConnection* const client, struct SwiftNetPacketBuffer* const packet, const uint32_t timeout_ms) { +static inline void delete_request_sent(struct RequestSent* request_sent) { + vector_lock(&requests_sent); + + for (uint32_t i = 0; i < requests_sent.size; i++) { + if (vector_get(&requests_sent, i) == request_sent) { + vector_remove(&requests_sent, i); + } + } + + vector_unlock(&requests_sent); + + allocator_free(&requests_sent_memory_allocator, 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 = client->server_addr; + request_sent->address = address; + + 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); const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; @@ -21,22 +41,11 @@ struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetCli uint32_t start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; while (1) { - struct timeval tv; gettimeofday(&tv, NULL); uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; if (start + timeout_ms < end) { - vector_lock(&requests_sent); - - for (uint32_t i = 0; i < requests_sent.size; i++) { - if (vector_get(&requests_sent, i) == request_sent) { - vector_remove(&requests_sent, i); - } - } - - vector_unlock(&requests_sent); - - allocator_free(&requests_sent_memory_allocator, request_sent); + delete_request_sent(request_sent); return NULL; } @@ -54,9 +63,7 @@ struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetCli } 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 = allocator_allocate(&requests_sent_memory_allocator); - request_sent->packet_data = NULL; - request_sent->address = addr_data.sender_address; + struct RequestSent* const request_sent = construct_request_sent(addr_data.sender_address); const uint32_t packet_length = packet->packet_append_pointer - packet->packet_data_start; @@ -67,7 +74,20 @@ struct SwiftNetServerPacketData* swiftnet_server_make_request(struct SwiftNetSer 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; + while (1) { + gettimeofday(&tv, NULL); + uint32_t end = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + if (start + timeout_ms < end) { + delete_request_sent(request_sent); + + return NULL; + } + if (request_sent->packet_data != NULL) { struct SwiftNetServerPacketData* const packet_data = request_sent->packet_data; diff --git a/src/process_packets.c b/src/process_packets.c index 0921c6b..526a962 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -210,8 +210,7 @@ static inline void handle_request_response(const uint16_t packet_id, const struc #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 -) { +static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* const pending_message, const uint16_t packet_id) { struct PacketCallbackQueueNode* const node = allocator_allocate(&packet_callback_queue_node_memory_allocator); node->packet_data = packet_data; node->next = NULL; @@ -312,10 +311,6 @@ static inline bool packet_corrupted(const uint16_t checksum, const uint32_t chun return crc16(buffer, chunk_size) != checksum; } -static inline void handle_ip_header_ordering(struct ip* ip_hdr) { - -} - static inline void swiftnet_process_packets( void* _Atomic * packet_handler, pcap_t* const pcap, @@ -397,34 +392,34 @@ static inline void swiftnet_process_packets( switch(packet_info.packet_type) { case PACKET_TYPE_REQUEST_INFORMATION: { - const struct ip send_server_info_ip_header = construct_ip_header(node->sender_address, PACKET_HEADER_SIZE, rand()); - - const struct SwiftNetPacketInfo packet_info_new = construct_packet_info( - sizeof(struct SwiftNetServerInformation), - PACKET_TYPE_REQUEST_INFORMATION, - 1, - 0, - (struct SwiftNetPortInfo){ - .source_port = source_port, - .destination_port = packet_info.port_info.source_port - } - ); + const struct ip send_server_info_ip_header = construct_ip_header(node->sender_address, PACKET_HEADER_SIZE, rand()); - const struct SwiftNetServerInformation server_info = { - .maximum_transmission_unit = maximum_transmission_unit - }; + const struct SwiftNetPacketInfo packet_info_new = construct_packet_info( + sizeof(struct SwiftNetServerInformation), + PACKET_TYPE_REQUEST_INFORMATION, + 1, + 0, + (struct SwiftNetPortInfo){ + .source_port = source_port, + .destination_port = packet_info.port_info.source_port + } + ); - HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) + const struct SwiftNetServerInformation server_info = { + .maximum_transmission_unit = maximum_transmission_unit + }; - memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); + HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) - - swiftnet_pcap_send(pcap, buffer, sizeof(buffer)); + memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); - allocator_free(&packet_buffer_memory_allocator, packet_buffer); - - goto next_packet; + HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + + swiftnet_pcap_send(pcap, buffer, sizeof(buffer)); + + allocator_free(&packet_buffer_memory_allocator, packet_buffer); + + goto next_packet; } case PACKET_TYPE_SEND_LOST_PACKETS_REQUEST: { diff --git a/src/swift_net.h b/src/swift_net.h index 0cac264..9f87acf 100644 --- a/src/swift_net.h +++ b/src/swift_net.h @@ -141,7 +141,6 @@ struct PacketQueueNode { uint8_t* data; uint32_t data_read; struct in_addr sender_address; - socklen_t server_address_length; }; struct PacketQueue { @@ -220,7 +219,6 @@ struct SwiftNetClientConnection { struct ether_header eth_header; struct SwiftNetPortInfo port_info; struct in_addr server_addr; - socklen_t server_addr_len; _Atomic(void (*)(struct SwiftNetClientPacketData* const, void* const user)) packet_handler; _Atomic(void*) packet_handler_user_arg; _Atomic bool closing;