diff --git a/.github/workflows/run_all_tests.yml b/.github/workflows/run_all_tests.yml index 7cea027..5c38915 100644 --- a/.github/workflows/run_all_tests.yml +++ b/.github/workflows/run_all_tests.yml @@ -22,7 +22,8 @@ jobs: - uses: actions/checkout@v4 - name: build run: | - ./build_for_testing.sh + cp profile_template.cmake profile.cmake + ./build.sh working-directory: build - name: build_integration_tests run: | diff --git a/.gitignore b/.gitignore index b553309..2f88ba2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,14 @@ *.DS_Store +profile.cmake CMakeCache.txt CMakeFiles/ cmake_install.cmake install_manifest.txt Makefile *.cmake +*.cache +!/build/profile_template.cmake !/build/cmake diff --git a/build/build_for_release.sh b/build/build.sh similarity index 63% rename from build/build_for_release.sh rename to build/build.sh index 3049029..8f4fef5 100755 --- a/build/build_for_release.sh +++ b/build/build.sh @@ -4,5 +4,5 @@ rm -rf cmake rm -f Makefile rm -f cmake_install.cmake -cmake ../src -DCMAKE_BUILD_TYPE=Release -DSANITIZER=none -B . +cmake ../src -B . make -B -j8 diff --git a/build/build_for_testing.sh b/build/build_for_testing.sh deleted file mode 100755 index 50bc816..0000000 --- a/build/build_for_testing.sh +++ /dev/null @@ -1,8 +0,0 @@ -rm -f CMakeCache.txt -rm -rf CMakeFiles -rm -rf cmake -rm -f Makefile -rm -f cmake_install.cmake - -cmake ../src -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread -DSWIFT_NET_INTERNAL_TESTING=ON -B . -make -B -j8 diff --git a/build/build_instructions.md b/build/build_instructions.md new file mode 100644 index 0000000..12df4c0 --- /dev/null +++ b/build/build_instructions.md @@ -0,0 +1,4 @@ +## Create profile +- Copy the profile_template.cmake file and name it profile.cmake +- Configure the profile correctly +- Run build.sh diff --git a/build/profile_template.cmake b/build/profile_template.cmake new file mode 100644 index 0000000..eb4513a --- /dev/null +++ b/build/profile_template.cmake @@ -0,0 +1,10 @@ +set(CMAKE_BUILD_TYPE Debug) + +add_compile_definitions( + # SWIFT_NET_DISABLE_REQUESTS # Compile source without request features (make_request, make_response) + SWIFT_NET_MEMORY_USAGE=5 # Multiplier of memory preallocated +) + +set(SWIFT_NET_INTERNAL_TESTING ON) # Only used when debugging the library itself +set(SANITIZER "none") # (thread, address, undefined, none (no sanitizer)) +set(BACKEND "pcap") # (pcap, dpdk) diff --git a/src/.clangd b/src/.clangd deleted file mode 100644 index b721dff..0000000 --- a/src/.clangd +++ /dev/null @@ -1,4 +0,0 @@ -CompileFlags: - Add: - - "-xc" - - "-std=c99" diff --git a/src/; b/src/; deleted file mode 100644 index d28a196..0000000 --- a/src/; +++ /dev/null @@ -1,192 +0,0 @@ -#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 75993fe..8bb81f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.10) project(swiftnet C CXX) include(GNUInstallDirs) +include(../build/profile.cmake) set(CMAKE_C_STANDARD 99) -set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) set(SOURCE_FILES initialize_swiftnet.c @@ -27,8 +27,6 @@ set(SOURCE_FILES internal/datatype_allocator.c internal/datatype_vector.c internal/datatype_hashmap.c - internal/pcap_open.c - internal/pcap_send.c internal/check_existing_listener.c ) @@ -48,30 +46,39 @@ else() message(STATUS "No sanitizer enabled") endif() +if(BACKEND STREQUAL "pcap") + add_compile_definitions(SWIFT_NET_BACKEND_PCAP) + + list(APPEND SOURCE_FILES + internal/pcap/pcap_send.c + internal/pcap/pcap_open.c + ) +endif() + + add_compile_options(-march=native) add_library(swiftnet STATIC ${SOURCE_FILES}) add_library(swiftnet_shared SHARED ${SOURCE_FILES}) -option(SWIFT_NET_INTERNAL_TESTING "Enable internal testing" OFF) - if (SWIFT_NET_INTERNAL_TESTING) message("Internal Testing Enabled") add_compile_definitions(SWIFT_NET_INTERNAL_TESTING) - target_compile_options(swiftnet PRIVATE -O0) - target_link_options(swiftnet PRIVATE -O0) + target_compile_options(swiftnet PRIVATE -O0 -g3) + target_link_options(swiftnet PRIVATE -O0 -g3) - target_compile_options(swiftnet_shared PRIVATE -O0) - target_link_options(swiftnet_shared PRIVATE -O0) + target_compile_options(swiftnet_shared PRIVATE -O0 -g3) + target_link_options(swiftnet_shared PRIVATE -O0 -g3) else() message("Internal Testing Disabled") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + target_compile_options(swiftnet PRIVATE -O3 -march=native - -mtune=native -flto=auto -funroll-loops -fomit-frame-pointer @@ -81,11 +88,8 @@ else() -funsafe-math-optimizations -ffinite-math-only - -fvectorize -falign-functions=64 -falign-loops=64 - - -flto ) target_link_options(swiftnet PRIVATE -O3) @@ -93,7 +97,6 @@ else() target_compile_options(swiftnet_shared PRIVATE -O3 -march=native - -mtune=native -flto=auto -funroll-loops -fomit-frame-pointer @@ -103,42 +106,41 @@ else() -funsafe-math-optimizations -ffinite-math-only - -fvectorize -falign-functions=64 -falign-loops=64 - - -flto ) target_link_options(swiftnet_shared PRIVATE -O3) endif() -if(DEFINED ENV{VCPKG_ROOT} AND DEFINED CMAKE_VCPKG_TARGET_TRIPLET) - set(VCPKG_INCLUDE_DIR "$ENV{VCPKG_ROOT}/installed/${CMAKE_VCPKG_TARGET_TRIPLET}/include") - set(VCPKG_LIB_DIR "$ENV{VCPKG_ROOT}/installed/${CMAKE_VCPKG_TARGET_TRIPLET}/lib") - - find_path(PCAP_INCLUDE_DIR pcap.h - PATHS ${VCPKG_INCLUDE_DIR} /usr/include /usr/local/include /opt/homebrew/include - ) - find_library(PCAP_LIBRARY pcap - PATHS ${VCPKG_LIB_DIR} /usr/lib /usr/local/lib /opt/homebrew/lib - ) - - if(PCAP_INCLUDE_DIR AND PCAP_LIBRARY) - message(STATUS "libpcap found: ${PCAP_LIBRARY}") - target_include_directories(swiftnet PUBLIC ${PCAP_INCLUDE_DIR}) - target_link_libraries(swiftnet PUBLIC ${PCAP_LIBRARY}) - - target_include_directories(swiftnet_shared PUBLIC ${PCAP_INCLUDE_DIR}) - target_link_libraries(swiftnet_shared PUBLIC ${PCAP_LIBRARY}) +if(BACKEND STREQUAL "pcap") + if(DEFINED ENV{VCPKG_ROOT} AND DEFINED CMAKE_VCPKG_TARGET_TRIPLET) + set(VCPKG_INCLUDE_DIR "$ENV{VCPKG_ROOT}/installed/${CMAKE_VCPKG_TARGET_TRIPLET}/include") + set(VCPKG_LIB_DIR "$ENV{VCPKG_ROOT}/installed/${CMAKE_VCPKG_TARGET_TRIPLET}/lib") + + find_path(PCAP_INCLUDE_DIR pcap.h + PATHS ${VCPKG_INCLUDE_DIR} /usr/include /usr/local/include /opt/homebrew/include + ) + find_library(PCAP_LIBRARY pcap + PATHS ${VCPKG_LIB_DIR} /usr/lib /usr/local/lib /opt/homebrew/lib + ) + + if(PCAP_INCLUDE_DIR AND PCAP_LIBRARY) + message(STATUS "libpcap found: ${PCAP_LIBRARY}") + target_include_directories(swiftnet PUBLIC ${PCAP_INCLUDE_DIR}) + target_link_libraries(swiftnet PUBLIC ${PCAP_LIBRARY}) + + target_include_directories(swiftnet_shared PUBLIC ${PCAP_INCLUDE_DIR}) + target_link_libraries(swiftnet_shared PUBLIC ${PCAP_LIBRARY}) + else() + message(WARNING "libpcap not found!!!") + endif() else() - message(WARNING "libpcap not found!!!") - endif() -else() - target_link_options(swiftnet PRIVATE -lpcap) - target_link_options(swiftnet_shared PRIVATE -lpcap) + target_link_options(swiftnet PRIVATE -lpcap) + target_link_options(swiftnet_shared PRIVATE -lpcap) - message("using linking option: -lpcap") + message("using linking option: -lpcap") + endif() endif() set_target_properties(swiftnet PROPERTIES diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index c650ac3..a9676e0 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -1,4 +1,5 @@ #include "internal/internal.h" +#include "internal/networking.h" #include "swift_net.h" #include #include @@ -123,7 +124,7 @@ void swiftnet_client_cleanup(struct SwiftNetClientConnection* const client) { close_threads(CONNECTION_TYPE_CLIENT, client); - pcap_close(client->pcap); + SWIFTNET_CLOSE_CONNECTION(&client->network_data); allocator_free(&client_connection_memory_allocator, client); } @@ -139,7 +140,7 @@ void swiftnet_server_cleanup(struct SwiftNetServer* const server) { close_threads(CONNECTION_TYPE_SERVER, server); - pcap_close(server->pcap); + SWIFTNET_CLOSE_CONNECTION(&server->network_data); allocator_free(&server_memory_allocator, server); } diff --git a/src/cleanup_swiftnet.c b/src/cleanup_swiftnet.c index 36fdc92..5f4e223 100644 --- a/src/cleanup_swiftnet.c +++ b/src/cleanup_swiftnet.c @@ -1,4 +1,5 @@ #include "internal/internal.h" +#include "internal/networking.h" #include "swift_net.h" #include #include @@ -10,11 +11,11 @@ static inline void close_listeners() { LOOP_HASHMAP(&listeners, struct Listener* restrict const current_listener = hashmap_data; - pcap_breakloop(current_listener->pcap); + SWIFTNET_BREAK_RECEIVER_LOOP(¤t_listener->network_data); pthread_join(current_listener->listener_thread, NULL); - pcap_close(current_listener->pcap); + SWIFTNET_CLOSE_CONNECTION(¤t_listener->network_data); hashmap_destroy(¤t_listener->client_connections); hashmap_destroy(¤t_listener->servers); @@ -35,7 +36,6 @@ void swiftnet_cleanup() { allocator_destroy(&server_packet_data_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&client_packet_data_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&packet_buffer_memory_allocator ENABLE_INTERNAL_CHECK); - allocator_destroy(&hashmap_item_memory_allocator ENABLE_INTERNAL_CHECK); #ifdef SWIFT_NET_REQUESTS allocator_destroy(&requests_sent_memory_allocator ENABLE_INTERNAL_CHECK); @@ -45,6 +45,7 @@ void swiftnet_cleanup() { close_listeners(); + allocator_destroy(&hashmap_item_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&server_memory_allocator ENABLE_INTERNAL_CHECK); allocator_destroy(&client_connection_memory_allocator ENABLE_INTERNAL_CHECK); diff --git a/src/generic_functions.c b/src/generic_functions.c index d82e159..f039196 100644 --- a/src/generic_functions.c +++ b/src/generic_functions.c @@ -1,4 +1,5 @@ #include "internal/internal.h" +#include "internal/networking.h" #include "swift_net.h" #include #include @@ -88,7 +89,7 @@ void swiftnet_client_destroy_packet_data(struct SwiftNetClientPacketData* restri free(packet_data->data); } else { - allocator_free(&packet_buffer_memory_allocator, packet_data->data - PACKET_HEADER_SIZE - client_conn->prepend_size); + allocator_free(&packet_buffer_memory_allocator, packet_data->data - PACKET_HEADER_SIZE - GET_PREPEND_SIZE(&client_conn->network_data)); allocator_free(&client_packet_data_memory_allocator, packet_data); } } @@ -101,7 +102,7 @@ void swiftnet_server_destroy_packet_data(struct SwiftNetServerPacketData* restri free(packet_data->data); } else { - allocator_free(&packet_buffer_memory_allocator, packet_data->data - PACKET_HEADER_SIZE - server->prepend_size); + allocator_free(&packet_buffer_memory_allocator, packet_data->data - PACKET_HEADER_SIZE - GET_PREPEND_SIZE(&server->network_data)); allocator_free(&server_packet_data_memory_allocator, packet_data); } } diff --git a/src/handle_packets.c b/src/handle_packets.c index 3dfeaca..27202d8 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -1,3 +1,4 @@ +#include "internal/networking.h" #include "swift_net.h" #include #include @@ -72,25 +73,28 @@ static inline void swiftnet_handle_packets( struct PacketQueue* const packet_queue, const _Atomic bool* const closing, const bool loopback, - const uint16_t addr_type, - 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 + _Atomic bool *const processing_packets, + struct SwiftNetNetworkData network_data, + const uint32_t packet_len ) { + uint8_t prepend_size; + uint8_t addr_type; + uint32_t sender_address; uint8_t* restrict packet_buffer; - uint32_t packet_len; + prepend_size = GET_PREPEND_SIZE(&network_data); + addr_type = GET_ADDR_TYPE(&network_data); + packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); if (unlikely(packet_buffer == NULL)) { goto exit; } - packet_len = hdr->caplen; - memcpy(packet_buffer, packet, packet_len); if (unlikely(packet_len == 0)) { @@ -139,21 +143,20 @@ static inline void swiftnet_handle_packets( return; } -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; - +static void handle_client_init(struct SwiftNetClientConnection* const client_connection, const uint8_t* restrict const buffer, const uint32_t bytes_received) { struct SwiftNetPacketInfo* restrict packet_info; struct SwiftNetServerInformation* restrict server_information; - uint32_t bytes_received; + uint8_t prepend_size; + uint8_t addr_type; + prepend_size = GET_PREPEND_SIZE(&client_connection->network_data); + addr_type = GET_ADDR_TYPE(&client_connection->network_data); goto check_closing; check_closing: - client_connection = user; - if (atomic_load_explicit(&client_connection->closing, memory_order_acquire) == true) { return; } @@ -162,9 +165,7 @@ static void handle_client_init(struct SwiftNetClientConnection* const user, cons validate_packet_size: - bytes_received = hdr->caplen; - - if(bytes_received != PACKET_HEADER_SIZE + sizeof(struct SwiftNetServerInformation) + client_connection->prepend_size) { + if(bytes_received != PACKET_HEADER_SIZE + sizeof(struct SwiftNetServerInformation) + prepend_size) { #ifdef SWIFT_NET_DEBUG if (check_debug_flag(SWIFTNET_DEBUG_INITIALIZATION)) { send_debug_message("Invalid packet received from server. Expected server information: {\"bytes_received\": %u, \"expected_bytes\": %u}\n", bytes_received, PACKET_HEADER_SIZE + sizeof(struct SwiftNetServerInformation)); @@ -176,9 +177,8 @@ static void handle_client_init(struct SwiftNetClientConnection* const user, cons goto handle_mac_address; - handle_mac_address: - if (client_connection->addr_type == DLT_EN10MB) { + if (addr_type == DLT_EN10MB) { memcpy(client_connection->eth_header.ether_dhost, ((struct ether_header*)buffer)->ether_shost, sizeof(client_connection->eth_header.ether_dhost)); } @@ -186,13 +186,13 @@ static void handle_client_init(struct SwiftNetClientConnection* const user, cons 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)); + packet_info = (struct SwiftNetPacketInfo*)(buffer + prepend_size + sizeof(struct ip)); + server_information = (struct SwiftNetServerInformation*)(buffer + 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(((struct ip*)(buffer + client_connection->prepend_size))->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 + prepend_size))->ip_src)); } #endif @@ -225,7 +225,7 @@ static void handle_client_init(struct SwiftNetClientConnection* const user, cons return; } -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) { +static inline uint8_t handle_correct_receiver(const enum ConnectionType connection_type, struct Listener* const listener, const uint8_t* restrict const packet, const struct SwiftNetPortInfo* restrict const port_info, const uint32_t packet_len) { if (connection_type == CONNECTION_TYPE_CLIENT) { struct SwiftNetClientConnection* client_connection; @@ -235,14 +235,16 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ UNLOCK_ATOMIC_DATA_TYPE(&listener->client_connections.atomic_lock); if (client_connection == NULL) { - return; + return 0; } - if (client_connection->initialized == false) { - handle_client_init(client_connection, hdr, packet); + if (atomic_load_explicit(&client_connection->initialized, memory_order_acquire) == false) { + handle_client_init(client_connection, packet, packet_len); } else { - swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet, &client_connection->process_packets_mtx, &client_connection->process_packets_cond, &client_connection->processing_packets); + 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, packet, &client_connection->process_packets_mtx, &client_connection->process_packets_cond, &client_connection->processing_packets, client_connection->network_data, packet_len); } + + return 1; } else { struct SwiftNetServer* server; @@ -253,24 +255,28 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ UNLOCK_ATOMIC_DATA_TYPE(&listener->servers.atomic_lock); if (server == NULL) { - return; + return 0; } - swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet, &server->process_packets_mtx, &server->process_packets_cond, &server->processing_packets); + swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, packet, &server->process_packets_mtx, &server->process_packets_cond, &server->processing_packets, server->network_data, packet_len); + + return 1; } } +#ifdef SWIFT_NET_BACKEND_PCAP 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)); - - handle_correct_receiver(CONNECTION_TYPE_CLIENT, listener, hdr, packet, port_info); - handle_correct_receiver(CONNECTION_TYPE_SERVER, listener, hdr, packet, port_info); + if(handle_correct_receiver(CONNECTION_TYPE_CLIENT, listener, packet, port_info, hdr->caplen) == 0) handle_correct_receiver(CONNECTION_TYPE_SERVER, listener, packet, port_info, hdr->caplen); } +#endif + +void* interface_start_listening(void* listener_void) { + struct Listener* listener = listener_void; -void* interface_start_listening(void* const listener_void) { - pcap_loop(((struct Listener*)listener_void)->pcap, 0, pcap_packet_handle, listener_void); + SWIFTNET_LOOP_PACKETS(&listener->network_data, listener); return NULL; } diff --git a/src/initialize_client_connection.c b/src/initialize_client_connection.c index 08dc555..fe37009 100644 --- a/src/initialize_client_connection.c +++ b/src/initialize_client_connection.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -19,18 +18,19 @@ #include #include #include +#include "internal/networking.h" struct RequestServerInformationArgs { uint32_t size; struct in_addr server_addr; - pcap_t* pcap; + struct SwiftNetNetworkData* restrict network_data; uint32_t timeout_ms; - void* data; + void* restrict data; struct SwiftNetClientConnection* connection; }; -void* request_server_information(void* const request_server_information_args_void) { - const struct RequestServerInformationArgs* const request_server_information_args = request_server_information_args_void; +void* request_server_information(void* restrict const request_server_information_args_void) { + const struct RequestServerInformationArgs* restrict const request_server_information_args = request_server_information_args_void; struct timeval tv; uint32_t start; @@ -48,9 +48,7 @@ void* request_server_information(void* const request_server_information_args_voi end = (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); - if (end > start + request_server_information_args->timeout_ms) { - goto exit; - } + 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; @@ -62,7 +60,7 @@ void* request_server_information(void* const request_server_information_args_voi } #endif - SWIFTNET_PCAP_SEND_SAFE(request_server_information_args->pcap, request_server_information_args->data, request_server_information_args->size); + SWIFTNET_SEND_PACKET(request_server_information_args->network_data, request_server_information_args->data, request_server_information_args->size); usleep(250000); @@ -73,7 +71,7 @@ void* request_server_information(void* const request_server_information_args_voi 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) { +static inline struct SwiftNetClientConnection* const construct_client_connection(const bool loopback, const uint16_t destination_port, const in_addr_t server_address, struct SwiftNetNetworkData* const network_data) { struct SwiftNetClientConnection* const new_connection = allocator_allocate(&client_connection_memory_allocator); struct ether_header eth_header = { @@ -84,25 +82,23 @@ static inline struct SwiftNetClientConnection* const construct_client_connection 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 + *new_connection = (struct SwiftNetClientConnection){ + .eth_header = eth_header, + .port_info = (struct SwiftNetPortInfo){.source_port = rand(), .destination_port = destination_port}, + .server_addr.s_addr = server_address, + .packet_handler = NULL, + .loopback = loopback, + .network_data = *network_data, + .pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 40 * SWIFT_NET_MEMORY_USAGE), + .packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 40 * SWIFT_NET_MEMORY_USAGE), + .packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 40 * SWIFT_NET_MEMORY_USAGE), + .packets_completed = hashmap_create(&packet_completed_key_allocator), + .packets_sending = hashmap_create(&uint16_memory_allocator), + .pending_messages = hashmap_create(&pending_message_key_allocator), + .packet_queue = (struct PacketQueue){ + .first_node = NULL, + .last_node = NULL + }, }; UNLOCK_ATOMIC_DATA_TYPE(&new_connection->packet_queue.locked); @@ -130,13 +126,15 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add struct in_addr addr; uint32_t ip; bool loopback; - pcap_t* pcap; struct SwiftNetClientConnection* 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; + struct SwiftNetNetworkData net_data; + struct SwiftNetNetworkData null_net_data; + goto init_connection; @@ -148,12 +146,14 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add loopback = (ip >> 24) == 127; - pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); - if (unlikely(pcap == NULL)) { + net_data = swiftnet_initialize_networking(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + + memset(&null_net_data, 0, sizeof(null_net_data)); + if (unlikely(memcmp(&null_net_data, &net_data, sizeof(net_data))) == 0) { return NULL; } - new_connection = construct_client_connection(loopback, port, addr.s_addr, pcap); + new_connection = construct_client_connection(loopback, port, addr.s_addr, &net_data); goto request_initialization; @@ -170,12 +170,12 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add 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, &net_data, &new_connection->eth_header, PACKET_HEADER_SIZE + GET_PREPEND_SIZE(&new_connection->network_data), request_server_info_buffer); - HANDLE_CHECKSUM(request_server_info_buffer, sizeof(request_server_info_buffer), new_connection->prepend_size); + HANDLE_CHECKSUM(request_server_info_buffer, sizeof(request_server_info_buffer), &net_data); thread_args = (struct RequestServerInformationArgs){ - .pcap = pcap, + .network_data = &net_data, .data = request_server_info_buffer, .size = sizeof(request_server_info_buffer), .server_addr = addr, @@ -192,7 +192,7 @@ 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); - pcap_close(new_connection->pcap); + swiftnet_close_connection(&new_connection->network_data); allocator_free(&client_connection_memory_allocator, new_connection); diff --git a/src/initialize_server.c b/src/initialize_server.c index 7a9778f..b76c214 100644 --- a/src/initialize_server.c +++ b/src/initialize_server.c @@ -11,23 +11,36 @@ #include #include #include "internal/internal.h" +#include "internal/networking.h" #include "swift_net.h" -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 = DEFAULT_MAC_ADDRESS_STRUCT; +static inline struct SwiftNetServer* const construct_server(const bool loopback, const uint16_t server_port) { + struct SwiftNetServer* restrict new_server; + struct ether_header eth_header; + struct SwiftNetNetworkData null_net_data; + + + memset(&null_net_data, 0x00, sizeof(null_net_data)); + + struct SwiftNetNetworkData net_data = swiftnet_initialize_networking(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + if (unlikely(memcmp(&net_data, &null_net_data, sizeof(struct SwiftNetNetworkData)) == 0)) { + return NULL; + } + + new_server = allocator_allocate(&server_memory_allocator); + eth_header = DEFAULT_MAC_ADDRESS_STRUCT; 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 + *new_server = (struct SwiftNetServer){ + .network_data = net_data, + .eth_header = eth_header, + .server_port = server_port, + .loopback = loopback, + .packet_queue = (struct PacketQueue){ + .first_node = NULL, + .last_node = NULL + }, }; memset(&new_server->packet_callback_queue, 0x00, sizeof(struct PacketCallbackQueue)); @@ -40,9 +53,9 @@ static inline struct SwiftNetServer* const construct_server(const bool loopback, 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->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100); - new_server->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); + new_server->pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 40 * SWIFT_NET_MEMORY_USAGE); + new_server->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 40 * SWIFT_NET_MEMORY_USAGE); + new_server->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 40 * SWIFT_NET_MEMORY_USAGE); new_server->packets_completed = hashmap_create(&packet_completed_key_allocator); new_server->packets_sending = hashmap_create(&uint16_memory_allocator); @@ -52,19 +65,15 @@ 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 - struct SwiftNetServer* new_server; - pcap_t* pcap; + struct SwiftNetServer* restrict new_server; - pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); - if (unlikely(pcap == NULL)) { - PRINT_ERROR("Failed to open bpf"); - return NULL; + new_server = construct_server(loopback, port); + if(unlikely(new_server == NULL)) { + PRINT_ERROR("Failed to construct server"); + exit(EXIT_FAILURE); } - 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 53336aa..345312e 100644 --- a/src/initialize_swiftnet.c +++ b/src/initialize_swiftnet.c @@ -50,21 +50,21 @@ pthread_t memory_cleanup_thread; _Atomic bool swiftnet_closing; 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); + packet_queue_node_memory_allocator = allocator_create(sizeof(struct PacketQueueNode), 40 * SWIFT_NET_MEMORY_USAGE); + packet_callback_queue_node_memory_allocator = allocator_create(sizeof(struct PacketCallbackQueueNode), 40 * SWIFT_NET_MEMORY_USAGE); + server_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetServerPacketData), 40 * SWIFT_NET_MEMORY_USAGE); + client_packet_data_memory_allocator = allocator_create(sizeof(struct SwiftNetClientPacketData), 40 * SWIFT_NET_MEMORY_USAGE); + packet_buffer_memory_allocator = allocator_create(maximum_transmission_unit + sizeof(struct ether_header), 40 * SWIFT_NET_MEMORY_USAGE); 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); - hashmap_item_memory_allocator = allocator_create(sizeof(struct SwiftNetHashMapItem), 0xFF); - uint16_memory_allocator = allocator_create(sizeof(uint16_t), 0xFF); - pending_message_key_allocator = allocator_create(sizeof(struct PendingMessagesKey), 0xFF); - packet_completed_key_allocator = allocator_create(sizeof(struct PacketCompletedKey), 0xFF); + listener_memory_allocator = allocator_create(sizeof(struct Listener), 40 * SWIFT_NET_MEMORY_USAGE); + hashmap_item_memory_allocator = allocator_create(sizeof(struct SwiftNetHashMapItem), 0xFF * SWIFT_NET_MEMORY_USAGE); + uint16_memory_allocator = allocator_create(sizeof(uint16_t), 0xFF * SWIFT_NET_MEMORY_USAGE); + pending_message_key_allocator = allocator_create(sizeof(struct PendingMessagesKey), 0xFF * SWIFT_NET_MEMORY_USAGE); + packet_completed_key_allocator = allocator_create(sizeof(struct PacketCompletedKey), 0xFF * SWIFT_NET_MEMORY_USAGE); #ifdef SWIFT_NET_REQUESTS - requests_sent_memory_allocator = allocator_create(sizeof(struct RequestSent), 100); + requests_sent_memory_allocator = allocator_create(sizeof(struct RequestSent), 40 * SWIFT_NET_MEMORY_USAGE); #endif } diff --git a/src/internal/check_existing_listener.c b/src/internal/check_existing_listener.c index 3a16857..91f468b 100644 --- a/src/internal/check_existing_listener.c +++ b/src/internal/check_existing_listener.c @@ -1,4 +1,5 @@ #include "internal.h" +#include "networking.h" #include #include #include @@ -47,11 +48,12 @@ void* check_existing_listener(const char* restrict const interface_name, void* c *new_listener = (struct Listener){ .servers = hashmap_create(&uint16_memory_allocator), .client_connections = hashmap_create(&uint16_memory_allocator), - .pcap = swiftnet_pcap_open(interface_name), + .network_data = swiftnet_initialize_networking(interface_name), .loopback = loopback }; - new_listener->addr_type = pcap_datalink(new_listener->pcap), + new_listener->addr_type = GET_ADDR_TYPE(&new_listener->network_data); + memcpy(new_listener->interface_name, interface_name, interface_len + 1); diff --git a/src/internal/internal.h b/src/internal/internal.h index f135bab..40df122 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -34,11 +33,6 @@ #define DISABLE_INTERNAL_CHECK #endif -#define SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, len) \ - while(swiftnet_pcap_send(pcap, buffer, len) == -2) { \ - usleep(2000); \ - } \ - enum RequestLostPacketsReturnType { REQUEST_LOST_PACKETS_RETURN_UPDATED_BIT_ARRAY = 0x00, REQUEST_LOST_PACKETS_RETURN_COMPLETED_PACKET = 0x01 @@ -79,25 +73,8 @@ enum RequestLostPacketsReturnType { // Memory should contain either an eth hdr or any specific data depending on addr type (loopback or real interface) #define PACKET_PREPEND_SIZE(addr_type) ((addr_type == DLT_NULL) ? sizeof(uint32_t) : addr_type == DLT_EN10MB ? sizeof(struct ether_header) : 0) #define PACKET_HEADER_SIZE (sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo)) -#define HANDLE_PACKET_CONSTRUCTION(ip_header, packet_info, addr_type, eth_hdr, buffer_size, buffer_name) \ - uint8_t buffer_name[buffer_size]; \ - if(addr_type == DLT_NULL) { \ - uint32_t family = PF_INET; \ - memcpy(buffer_name, &family, sizeof(family)); \ - memcpy(buffer_name + sizeof(family), ip_header, sizeof(*ip_header)); \ - memcpy(buffer_name + sizeof(family) + sizeof(*ip_header), packet_info, sizeof(*packet_info)); \ - } else if(addr_type == DLT_EN10MB){ \ - memcpy(buffer_name, eth_hdr, sizeof(*eth_hdr)); \ - memcpy(buffer_name + sizeof(*eth_hdr), ip_header, sizeof(*ip_header)); \ - memcpy(buffer_name + sizeof(*eth_hdr) + sizeof(*ip_header), packet_info, sizeof(*packet_info)); \ - } \ - -// Simple crc16 call with proper memory order -#define HANDLE_CHECKSUM(buffer, size, prepend_size) \ - 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)} + +#define DEFAULT_MAC_ADDRESS_STRUCT (struct ether_header){.ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, .ether_type = htons(0x0800)} // Number used in ip.proto #define PROT_NUMBER 253 @@ -164,7 +141,7 @@ struct PacketCompletedKey { }; struct Listener { - pcap_t* pcap; + struct SwiftNetNetworkData network_data; pthread_t listener_thread; struct SwiftNetHashMap servers; struct SwiftNetHashMap client_connections; @@ -192,9 +169,6 @@ extern void* memory_cleanup_background_service(); 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); -extern int setup_bpf_settings(const int bpf); extern void* swiftnet_server_process_packets(void* const void_server); extern void* swiftnet_client_process_packets(void* const void_client); @@ -205,8 +179,6 @@ 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* 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* restrict const interface_name, void* const connection, const enum ConnectionType connection_type, const bool loopback); @@ -314,11 +286,9 @@ extern void swiftnet_send_packet( const struct in_addr* const target_addr, struct SwiftNetHashMap* const packets_sending, struct SwiftNetMemoryAllocator* const packets_sending_memory_allocator, - pcap_t* const pcap, const struct ether_header eth_hdr, const bool loopback, - const uint16_t addr_type, - const uint8_t prepend_size + const struct SwiftNetNetworkData network_data #ifdef SWIFT_NET_REQUESTS , struct RequestSent* const request_sent , const bool response diff --git a/src/internal/networking.h b/src/internal/networking.h new file mode 100644 index 0000000..a8fde7f --- /dev/null +++ b/src/internal/networking.h @@ -0,0 +1,75 @@ +#pragma once + +#include "../swift_net.h" +#include "internal.h" +#include +#include + +#ifdef SWIFT_NET_BACKEND_PCAP + +#include + // Simple crc16 call with proper memory order + #define HANDLE_CHECKSUM(buffer, size, network_data) \ + const uint32_t checksum = crc32(buffer, size); \ + memcpy(buffer + (network_data)->prepend_size + sizeof(struct ip) + offsetof(struct SwiftNetPacketInfo, checksum), &checksum, sizeof(checksum)); + + #define GET_ADDR_TYPE(network_data) (network_data)->addr_type + #define GET_PREPEND_SIZE(network_data) (network_data)->prepend_size + + #define HANDLE_PACKET_CONSTRUCTION(ip_header, packet_info, network_data, eth_hdr, buffer_size, buffer_name) \ + uint8_t buffer_name[buffer_size]; \ + if((network_data)->addr_type == DLT_NULL) { \ + uint32_t family = PF_INET; \ + memcpy(buffer_name, &family, sizeof(family)); \ + memcpy(buffer_name + sizeof(family), ip_header, sizeof(*ip_header)); \ + memcpy(buffer_name + sizeof(family) + sizeof(*ip_header), packet_info, sizeof(*packet_info)); \ + } else if((network_data)->addr_type == DLT_EN10MB){ \ + memcpy(buffer_name, eth_hdr, sizeof(*eth_hdr)); \ + memcpy(buffer_name + sizeof(*eth_hdr), ip_header, sizeof(*ip_header)); \ + memcpy(buffer_name + sizeof(*eth_hdr) + sizeof(*ip_header), packet_info, sizeof(*packet_info)); \ + } \ + + + extern pcap_t* swiftnet_pcap_open(const char* const restrict interface); + extern int swiftnet_pcap_send(pcap_t *pcap, const uint8_t *data, int len); + + inline static struct SwiftNetNetworkData swiftnet_initialize_networking(const char* const restrict interface) { + pcap_t* pcap = swiftnet_pcap_open(interface); + if (unlikely(pcap == NULL)) { + struct SwiftNetNetworkData net_data_null; + memset(&net_data_null, 0x00, sizeof(net_data_null)); + + return net_data_null; + } + + const uint8_t addr_type = pcap_datalink(pcap); + + struct SwiftNetNetworkData network_data = { + .pcap = pcap, + .addr_type = addr_type, + .prepend_size = PACKET_PREPEND_SIZE(addr_type) + }; + + return network_data; + } + + inline static void swiftnet_close_connection(struct SwiftNetNetworkData* restrict const network_data) { + pcap_close(network_data->pcap); + } + + #define SWIFTNET_BREAK_RECEIVER_LOOP(network_data) \ + pcap_breakloop((network_data)->pcap) + + #define SWIFTNET_LOOP_PACKETS(network_data, listener) \ + pcap_loop((network_data)->pcap, 0, pcap_packet_handle, (void*)listener) + + #define SWIFTNET_CLOSE_CONNECTION(network_data) \ + pcap_close((network_data)->pcap); + + #define SWIFTNET_SEND_PACKET(network_data, buffer, len) \ + while(swiftnet_pcap_send((network_data)->pcap, buffer, len) == -2) { \ + usleep(2000); \ + } +#elif SWIFTNET_PCAP_DPDK +// future backend functions +#endif diff --git a/src/internal/pcap_open.c b/src/internal/pcap/pcap_open.c similarity index 88% rename from src/internal/pcap_open.c rename to src/internal/pcap/pcap_open.c index af61122..65aff3d 100644 --- a/src/internal/pcap_open.c +++ b/src/internal/pcap/pcap_open.c @@ -1,7 +1,7 @@ -#include "internal.h" +#include "../internal.h" #include -pcap_t* swiftnet_pcap_open(const char* restrict const interface) { +pcap_t* swiftnet_pcap_open(const char* const restrict interface) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_t* p; struct bpf_program fp; @@ -34,4 +34,4 @@ pcap_t* swiftnet_pcap_open(const char* restrict const interface) { } return p; -} \ No newline at end of file +} diff --git a/src/internal/pcap_send.c b/src/internal/pcap/pcap_send.c similarity index 93% rename from src/internal/pcap_send.c rename to src/internal/pcap/pcap_send.c index 831c281..680d609 100644 --- a/src/internal/pcap_send.c +++ b/src/internal/pcap/pcap_send.c @@ -1,4 +1,4 @@ -#include "internal.h" +#include "../internal.h" #include #include diff --git a/src/make_request.c b/src/make_request.c index ea57759..c6766dd 100644 --- a/src/make_request.c +++ b/src/make_request.c @@ -37,7 +37,7 @@ struct SwiftNetClientPacketData* swiftnet_client_make_request(struct SwiftNetCli 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); + 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->eth_header, client->loopback, client->network_data, request_sent, false, 0); gettimeofday(&tv, NULL); @@ -83,7 +83,7 @@ struct SwiftNetServerPacketData* swiftnet_server_make_request(struct SwiftNetSer 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); + 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->eth_header, server->loopback, server->network_data, request_sent, false, 0); gettimeofday(&tv, NULL); start = (uint32_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; diff --git a/src/make_response.c b/src/make_response.c index cc903be..6334e3d 100644 --- a/src/make_response.c +++ b/src/make_response.c @@ -6,14 +6,14 @@ 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); + 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->eth_header, client->loopback, client->network_data, NULL, true, packet_data->metadata.packet_id); } 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}; - 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); + 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->eth_header, server->loopback, server->network_data, NULL, true, packet_data->metadata.packet_id); } #endif diff --git a/src/process_packets.c b/src/process_packets.c index ebe3acd..0b91029 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -1,4 +1,5 @@ #include "internal/internal.h" +#include "internal/networking.h" #include "swift_net.h" #include #include @@ -270,12 +271,15 @@ static inline struct SwiftNetPacketSending* get_packet_sending(struct SwiftNetHa return result; } -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) { +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 struct ether_header* const eth_hdr, const struct SwiftNetNetworkData* const net_data) { struct ip send_server_info_ip_header; struct SwiftNetPacketInfo packet_info_new; struct SwiftNetServerInformation server_info; + uint16_t prepend_size; + prepend_size = GET_PREPEND_SIZE(net_data); + 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( @@ -293,13 +297,14 @@ 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, eth_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) + + HANDLE_PACKET_CONSTRUCTION(&send_server_info_ip_header, &packet_info_new, net_data, eth_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer); memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + HANDLE_CHECKSUM(buffer, sizeof(buffer), net_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); + SWIFTNET_SEND_PACKET(net_data, buffer, sizeof(buffer)); } struct PacketQueueNode* wait_for_next_packet(struct PacketQueue* const packet_queue) { @@ -337,11 +342,10 @@ static inline bool packet_corrupted(const uint32_t checksum, const uint32_t chun static inline void swiftnet_process_packets( void* _Atomic * const packet_handler, - pcap_t* const pcap, const struct ether_header eth_hdr, const uint16_t source_port, const bool loopback, - const uint16_t addr_type, + const struct SwiftNetNetworkData network_data, struct SwiftNetHashMap* const packets_sending, struct SwiftNetMemoryAllocator* const packets_sending_messages_memory_allocator, struct SwiftNetHashMap* const pending_messages, @@ -352,8 +356,7 @@ static inline void swiftnet_process_packets( struct PacketQueue* const packet_queue, struct PacketCallbackQueue* const packet_callback_queue, void* const connection, - const _Atomic bool* const closing, - const uint8_t prepend_size, + _Atomic bool* const closing, pthread_mutex_t* const process_packets_mtx, pthread_cond_t* const process_packets_cond, pthread_mutex_t* const execute_callback_mtx, @@ -371,10 +374,15 @@ static inline void swiftnet_process_packets( uint32_t mtu; uint32_t chunk_data_size; struct SwiftNetPendingMessage* pending_message; + uint16_t prepend_size; + uint16_t addr_type; idle_stage = 0; + addr_type = GET_ADDR_TYPE(&network_data); + prepend_size = GET_PREPEND_SIZE(&network_data); + process_packet: if (atomic_load(closing) == true) { goto exit; @@ -479,13 +487,13 @@ static inline void swiftnet_process_packets( .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, &network_data, ð_hdr, prepend_size + PACKET_HEADER_SIZE + sizeof(server_info), buffer) memcpy(buffer + prepend_size + PACKET_HEADER_SIZE, &server_info, sizeof(server_info)); - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + HANDLE_CHECKSUM(buffer, sizeof(buffer), &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); + SWIFTNET_SEND_PACKET(&network_data, buffer, sizeof(buffer)); allocator_free(&packet_buffer_memory_allocator, packet_buffer); @@ -526,11 +534,11 @@ static inline void swiftnet_process_packets( } ); - HANDLE_PACKET_CONSTRUCTION(&send_packet_ip_header, &send_packet_info, addr_type, ð_hdr, prepend_size + PACKET_HEADER_SIZE, buffer) + HANDLE_PACKET_CONSTRUCTION(&send_packet_ip_header, &send_packet_info, &network_data, ð_hdr, prepend_size + PACKET_HEADER_SIZE, buffer); - HANDLE_CHECKSUM(buffer, sizeof(buffer), prepend_size) + HANDLE_CHECKSUM(buffer, sizeof(buffer), &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, sizeof(buffer)); + SWIFTNET_SEND_PACKET(&network_data, buffer, sizeof(buffer)); allocator_free(&packet_buffer_memory_allocator, packet_buffer); @@ -559,7 +567,7 @@ static inline void swiftnet_process_packets( header_size = PACKET_HEADER_SIZE + prepend_size; - HANDLE_PACKET_CONSTRUCTION(&send_lost_packets_ip_header, &packet_info_new, addr_type, ð_hdr, case_mtu + prepend_size, buffer) + HANDLE_PACKET_CONSTRUCTION(&send_lost_packets_ip_header, &packet_info_new, &network_data, ð_hdr, case_mtu + prepend_size, buffer) 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)); @@ -571,9 +579,9 @@ static inline void swiftnet_process_packets( 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)); - HANDLE_CHECKSUM(buffer, packet_length + prepend_size, prepend_size); + HANDLE_CHECKSUM(buffer, packet_length + prepend_size, &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer, packet_length + prepend_size); + SWIFTNET_SEND_PACKET(&network_data, buffer, packet_length + prepend_size); allocator_free(&packet_buffer_memory_allocator, packet_buffer); @@ -767,6 +775,10 @@ static inline void swiftnet_process_packets( bytes_to_write = (packet_info.chunk_index + 1) >= packet_info.chunk_amount ? packet_info.packet_length % chunk_data_size : chunk_data_size; + if (GET_ADDR_TYPE(&network_data) == DLT_EN10MB) { + memcpy(&sender.mac_address, eth_hdr.ether_shost, sizeof(sender.mac_address)); + } + if(pending_message->chunks_received_number + 1 == packet_info.chunk_amount) { pending_message->chunks_received_number++; @@ -873,9 +885,9 @@ static inline void swiftnet_process_packets( 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); + signal_delay_change(LOWER_DELAY, &ip_header, source_port, packet_info.port_info.source_port, ð_hdr, &network_data); } else { - signal_delay_change(INCREASE_DELAY, &ip_header, source_port, packet_info.port_info.source_port, addr_type, prepend_size, pcap, ð_hdr); + signal_delay_change(INCREASE_DELAY, &ip_header, source_port, packet_info.port_info.source_port, ð_hdr, &network_data); } pending_message->last_chunks_received_number = pending_message->chunks_received_number; @@ -911,7 +923,7 @@ void* swiftnet_server_process_packets(void* const void_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); + swiftnet_process_packets((void*)&server->packet_handler, server->eth_header, server->server_port, server->loopback, server->network_data, &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->process_packets_mtx, &server->process_packets_cond, &server->execute_callback_mtx, &server->execute_callback_cond, &server->processing_packets); return NULL; } @@ -922,7 +934,7 @@ void* swiftnet_client_process_packets(void* const void_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); + swiftnet_process_packets((void*)&client->packet_handler, client->eth_header, client->port_info.source_port, client->loopback, client->network_data, &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->process_packets_mtx, &client->process_packets_cond, &client->execute_callback_mtx, &client->execute_callback_cond, &client->processing_packets); return NULL; } diff --git a/src/send_packet.c b/src/send_packet.c index 8f19b83..509dcec 100644 --- a/src/send_packet.c +++ b/src/send_packet.c @@ -1,4 +1,6 @@ +#include "internal/networking.h" #include "swift_net.h" +#include #include #include #include @@ -16,17 +18,19 @@ #include "internal/internal.h" #include -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) { +static inline enum RequestLostPacketsReturnType request_lost_packets_bitarray(const uint8_t* restrict const raw_data, const uint32_t data_size, const struct SwiftNetNetworkData* restrict const network_data, struct SwiftNetPacketSending* const packet_sending) { uint8_t times_checked; enum PacketSendingUpdated status; + + goto request_lost_packets; 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)); } - SWIFTNET_PCAP_SEND_SAFE(pcap, raw_data, data_size); + SWIFTNET_SEND_PACKET(network_data, raw_data, data_size); for(times_checked = 0; times_checked < 0xFF; times_checked++) { status = atomic_load_explicit(&packet_sending->updated, memory_order_acquire); @@ -52,22 +56,21 @@ static inline enum RequestLostPacketsReturnType request_lost_packets_bitarray(co static inline void handle_lost_packets( struct SwiftNetPacketSending* const packet_sending, const uint32_t mtu, - const struct SwiftNetPacketBuffer* const packet, - pcap_t* const pcap, + const struct SwiftNetPacketBuffer* restrict const packet, const struct ether_header eth_hdr, - const struct in_addr* const destination_address, + const struct in_addr* restrict const destination_address, const uint16_t source_port, const uint16_t destination_port, struct SwiftNetMemoryAllocator* const packets_sending_memory_allocator, struct SwiftNetHashMap* const packets_sending, const bool loopback, - const uint16_t addr_type, - const uint8_t prepend_size + const struct SwiftNetNetworkData* restrict const network_data #ifdef SWIFT_NET_REQUESTS , const bool response , const uint8_t packet_type #endif ) { + uint8_t prepend_size = GET_PREPEND_SIZE(network_data); struct SwiftNetPortInfo port_info; struct ip request_lost_packets_ip_header; struct SwiftNetPacketInfo request_lost_packets_bit_array; @@ -76,7 +79,6 @@ static inline void handle_lost_packets( 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; @@ -95,9 +97,9 @@ static inline void handle_lost_packets( port_info ); - HANDLE_PACKET_CONSTRUCTION(&request_lost_packets_ip_header, &request_lost_packets_bit_array, addr_type, ð_hdr, PACKET_HEADER_SIZE + prepend_size, request_lost_packets_buffer) + HANDLE_PACKET_CONSTRUCTION(&request_lost_packets_ip_header, &request_lost_packets_bit_array, network_data, ð_hdr, PACKET_HEADER_SIZE + prepend_size, request_lost_packets_buffer); - HANDLE_CHECKSUM(request_lost_packets_buffer, sizeof(request_lost_packets_buffer), prepend_size) + HANDLE_CHECKSUM(request_lost_packets_buffer, sizeof(request_lost_packets_buffer), network_data); packet_length = packet->packet_append_pointer - packet->packet_data_start; chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); @@ -116,29 +118,16 @@ static inline void handle_lost_packets( resend_chunk_ip_header = construct_ip_header(*destination_address, mtu, packet_sending->packet_id); - if (addr_type == DLT_NULL) { - uint32_t family; - - - 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)); - } + HANDLE_PACKET_CONSTRUCTION(&resend_chunk_ip_header, &resend_chunk_packet_info, network_data, ð_hdr, prepend_size + PACKET_HEADER_SIZE, prepend_buffer); while(1) { uint32_t i; uint32_t lost_chunk_index; uint32_t current_offset; - uint8_t* current_buffer_header_ptr; + uint8_t* restrict 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); + request_lost_packets_bitarray_response = request_lost_packets_bitarray(request_lost_packets_buffer, PACKET_HEADER_SIZE + prepend_size, network_data, packet_sending); LOCK_ATOMIC_DATA_TYPE(&packets_sending->atomic_lock); @@ -186,13 +175,13 @@ static inline void handle_lost_packets( 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) + HANDLE_CHECKSUM(current_buffer_header_ptr, prepend_size + PACKET_HEADER_SIZE + bytes_to_complete, network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, current_buffer_header_ptr, bytes_to_complete + PACKET_HEADER_SIZE + prepend_size); + SWIFTNET_SEND_PACKET(network_data, current_buffer_header_ptr, bytes_to_complete + PACKET_HEADER_SIZE + prepend_size); } else { - HANDLE_CHECKSUM(current_buffer_header_ptr, mtu + prepend_size, prepend_size) + HANDLE_CHECKSUM(current_buffer_header_ptr, mtu + prepend_size, network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, current_buffer_header_ptr, mtu + prepend_size); + SWIFTNET_SEND_PACKET(network_data, current_buffer_header_ptr, mtu + prepend_size); } memcpy(current_buffer_header_ptr, temp_data_buffer, prepend_size + PACKET_HEADER_SIZE); @@ -211,11 +200,9 @@ inline void swiftnet_send_packet( const struct in_addr* const target_addr, struct SwiftNetHashMap* const packets_sending, struct SwiftNetMemoryAllocator* const packets_sending_memory_allocator, - pcap_t* const pcap, const struct ether_header eth_hdr, const bool loopback, - const uint16_t addr_type, - const uint8_t prepend_size + const struct SwiftNetNetworkData network_data #ifdef SWIFT_NET_REQUESTS , struct RequestSent* const request_sent , const bool response @@ -270,6 +257,8 @@ inline void swiftnet_send_packet( chunk_amount = (packet_length + (mtu - PACKET_HEADER_SIZE) - 1) / (mtu - PACKET_HEADER_SIZE); + const uint8_t prepend_size = GET_PREPEND_SIZE(&network_data); + if(packet_length > mtu) { struct SwiftNetPacketInfo packet_info; struct ip ip_header; @@ -277,7 +266,6 @@ inline void swiftnet_send_packet( 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; @@ -327,20 +315,8 @@ inline void swiftnet_send_packet( UNLOCK_ATOMIC_DATA_TYPE(&packets_sending->atomic_lock); - if (addr_type == DLT_NULL) { - uint32_t family; - - - 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)); - } - + HANDLE_PACKET_CONSTRUCTION(&ip_header, &packet_info, &network_data, ð_hdr, prepend_size + PACKET_HEADER_SIZE, prepend_buffer); + for(i = 0; ; i++) { current_offset = i * (mtu - PACKET_HEADER_SIZE); @@ -367,13 +343,13 @@ inline void swiftnet_send_packet( memcpy(buffer_header_location + prepend_size + offsetof(struct ip, ip_len), &bytes_to_send_net_order, SIZEOF_FIELD(struct ip, ip_len)); - HANDLE_CHECKSUM(buffer_header_location, bytes_to_send, prepend_size); + HANDLE_CHECKSUM(buffer_header_location, bytes_to_send, &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer_header_location, bytes_to_send); + SWIFTNET_SEND_PACKET(&network_data, buffer_header_location, bytes_to_send); memcpy(buffer_header_location, temp_data_buffer, prepend_size + PACKET_HEADER_SIZE); - handle_lost_packets(new_packet_sending, mtu, packet, pcap, eth_hdr, target_addr, port_info.source_port, port_info.destination_port, packets_sending_memory_allocator, packets_sending, loopback, addr_type, prepend_size + handle_lost_packets(new_packet_sending, mtu, packet, eth_hdr, target_addr, port_info.source_port, port_info.destination_port, packets_sending_memory_allocator, packets_sending, loopback, &network_data #ifdef SWIFT_NET_REQUESTS , response , packet_type @@ -384,9 +360,9 @@ inline void swiftnet_send_packet( } else { bytes_to_send = prepend_size + mtu; - HANDLE_CHECKSUM(buffer_header_location, bytes_to_send, prepend_size) + HANDLE_CHECKSUM(buffer_header_location, bytes_to_send, &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, buffer_header_location, bytes_to_send); + SWIFTNET_SEND_PACKET(&network_data, buffer_header_location, bytes_to_send); memcpy(buffer_header_location, temp_data_buffer, prepend_size + PACKET_HEADER_SIZE); @@ -415,30 +391,28 @@ inline void swiftnet_send_packet( ip_header = construct_ip_header(*target_addr, final_packet_size - prepend_size, packet_id); - if(addr_type == DLT_NULL) { - uint32_t family; - + if(GET_ADDR_TYPE(&network_data) == DLT_NULL) { + uint32_t family = PF_INET; - 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)); memcpy(packet->packet_buffer_start + PACKET_HEADER_SIZE + sizeof(struct ether_header), packet->packet_data_start, packet_length); - HANDLE_CHECKSUM(packet->packet_buffer_start + sizeof(struct ether_header) - sizeof(family), final_packet_size, prepend_size) + HANDLE_CHECKSUM(packet->packet_buffer_start + sizeof(struct ether_header) - sizeof(family), final_packet_size, &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, packet->packet_buffer_start + sizeof(struct ether_header) - sizeof(family), final_packet_size); - } else if(addr_type == DLT_EN10MB) { + SWIFTNET_SEND_PACKET(&network_data, packet->packet_buffer_start + sizeof(struct ether_header) - sizeof(family), final_packet_size); + } else if(GET_ADDR_TYPE(&network_data) == DLT_EN10MB) { memcpy(packet->packet_buffer_start, ð_hdr, sizeof(eth_hdr)); memcpy(packet->packet_buffer_start + sizeof(eth_hdr), &ip_header, sizeof(ip_header)); memcpy(packet->packet_buffer_start + sizeof(eth_hdr) + sizeof(ip_header), &packet_info, sizeof(packet_info)); memcpy(packet->packet_buffer_start + PACKET_HEADER_SIZE + sizeof(struct ether_header), packet->packet_data_start, packet_length); - HANDLE_CHECKSUM(packet->packet_buffer_start, final_packet_size, prepend_size) + HANDLE_CHECKSUM(packet->packet_buffer_start, final_packet_size, &network_data); - SWIFTNET_PCAP_SEND_SAFE(pcap, packet->packet_buffer_start, final_packet_size); + SWIFTNET_SEND_PACKET(&network_data, packet->packet_buffer_start, final_packet_size); } } } @@ -449,7 +423,7 @@ void swiftnet_client_send_packet(struct SwiftNetClientConnection* const client, 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 + 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->eth_header, client->loopback, client->network_data #ifdef SWIFT_NET_REQUESTS , NULL, false, 0 #endif @@ -472,7 +446,7 @@ void swiftnet_server_send_packet(struct SwiftNetServer* const server, struct Swi memcpy(ð_hdr, &server->eth_header, sizeof(eth_hdr)); memcpy(ð_hdr.ether_dhost, &target.mac_address, sizeof(eth_hdr.ether_dhost)); - swiftnet_send_packet(server, target.maximum_transmission_unit, port_info, packet, packet_length, &target.sender_address, &server->packets_sending, &server->packets_sending_memory_allocator, server->pcap, eth_hdr, server->loopback, server->addr_type, server->prepend_size + swiftnet_send_packet(server, target.maximum_transmission_unit, port_info, packet, packet_length, &target.sender_address, &server->packets_sending, &server->packets_sending_memory_allocator, eth_hdr, server->loopback, server->network_data #ifdef SWIFT_NET_REQUESTS , NULL, false, 0 #endif diff --git a/src/swift_net.h b/src/swift_net.h index 738a27a..4ef3a68 100644 --- a/src/swift_net.h +++ b/src/swift_net.h @@ -9,7 +9,13 @@ #include #include #include + +#ifdef SWIFT_NET_BACKEND_PCAP #include +#endif + +#ifdef SWIFT_NET_BACKEND_DPDK +#endif #ifdef __cplusplus extern "C" { @@ -35,6 +41,14 @@ extern "C" { // More memory = better performance #define SWIFT_NET_MEMORY_USAGE 5 +struct SwiftNetNetworkData { + #ifdef SWIFT_NET_BACKEND_PCAP + pcap_t* pcap; + uint16_t addr_type; + uint8_t prepend_size; + #endif +} SWIFT_NET_ALIGNED(8); + enum PacketType { MESSAGE = 0x01, REQUEST_INFORMATION = 0x02, @@ -263,9 +277,9 @@ struct SwiftNetClientConnection { struct SwiftNetMemoryAllocator packets_completed_memory_allocator; struct SwiftNetMemoryAllocator pending_messages_memory_allocator; struct SwiftNetMemoryAllocator packets_sending_memory_allocator; + struct SwiftNetNetworkData network_data; struct PacketQueue packet_queue; struct PacketCallbackQueue packet_callback_queue; - pcap_t* pcap; _Atomic(void (*)(struct SwiftNetClientPacketData* const, void* const user)) packet_handler; _Atomic(void*) packet_handler_user_arg; pthread_mutex_t process_packets_mtx; @@ -278,8 +292,6 @@ struct SwiftNetClientConnection { struct ether_header eth_header; uint32_t maximum_transmission_unit; struct in_addr server_addr; - uint16_t addr_type; - uint8_t prepend_size; bool loopback; _Atomic bool processing_packets; _Atomic bool closing; @@ -293,9 +305,9 @@ struct SwiftNetServer { struct SwiftNetMemoryAllocator packets_completed_memory_allocator; struct SwiftNetMemoryAllocator pending_messages_memory_allocator; struct SwiftNetMemoryAllocator packets_sending_memory_allocator; + struct SwiftNetNetworkData network_data; struct PacketQueue packet_queue; struct PacketCallbackQueue packet_callback_queue; - pcap_t* pcap; _Atomic(void (*)(struct SwiftNetServerPacketData* const, void* const user)) packet_handler; _Atomic(void*) packet_handler_user_arg; pthread_mutex_t process_packets_mtx; @@ -306,8 +318,6 @@ struct SwiftNetServer { pthread_t execute_callback_thread; struct ether_header eth_header; uint16_t server_port; - uint16_t addr_type; - uint8_t prepend_size; bool loopback; _Atomic bool processing_packets; _Atomic bool closing; diff --git a/tests/integration_tests/build/CMakeLists.txt b/tests/integration_tests/build/CMakeLists.txt index 80e3338..d7937ad 100644 --- a/tests/integration_tests/build/CMakeLists.txt +++ b/tests/integration_tests/build/CMakeLists.txt @@ -27,7 +27,7 @@ file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/../src/*.c") add_executable(run_tests ${SRC_FILES}) -target_link_libraries(run_tests PRIVATE -lpcap ${CMAKE_SOURCE_DIR}/../../../build/output/libswiftnet.a) +target_link_libraries(run_tests PRIVATE ${CMAKE_SOURCE_DIR}/../../../build/output/libswiftnet.a -lpcap ) target_link_options(run_tests PRIVATE -g -O0) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/tests/integration_tests/build/build_tests.sh b/tests/integration_tests/build/build_tests.sh index 9662abd..43d73ca 100755 --- a/tests/integration_tests/build/build_tests.sh +++ b/tests/integration_tests/build/build_tests.sh @@ -1,2 +1,8 @@ -cmake . -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread -B . +rm -f CMakeCache.txt +rm -rf CMakeFiles +rm -rf cmake +rm -f Makefile +rm -f cmake_install.cmake + +cmake . -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=none -B . make -B -j8