From a65483a9c380d52411e851719783d6c1686d2b6f Mon Sep 17 00:00:00 2001 From: HappyTanuki Date: Sat, 31 May 2025 03:19:58 +0900 Subject: [PATCH] =?UTF-8?q?iocp=20=EA=B5=AC=ED=98=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/include/asteroid/game.h | 8 + .../{ => vulkan_engine}/asset/loader.h | 2 +- .../asset/object/material.h | 2 +- .../{ => vulkan_engine}/asset/object/model.h | 4 +- .../include/{ => vulkan_engine}/utilities.h | 0 .../vulkan/buffer_handle.h | 0 .../{ => vulkan_engine}/vulkan/coordinate.h | 2 +- .../{ => vulkan_engine}/vulkan/engine.h | 2 +- .../{ => vulkan_engine}/vulkan/graphics.h | 0 .../{ => vulkan_engine}/vulkan/physics.h | 4 +- .../vulkan/texture_handle.h | 0 .../vulkan/uniform_transformations.h | 0 .../{ => vulkan_engine}/vulkan/vertex.h | 0 Client/src/asteroid/begin_play.cpp | 64 ++++ Client/src/asteroid/main.cpp | 37 ++ Client/src/{main.cpp => asteroid/tick.cpp} | 109 +----- Client/src/vulkan/graphics.cpp | 11 - .../src/{ => vulkan_engine}/asset/loader.cpp | 3 +- .../asset/object/model.cpp | 4 +- .../glfw/glfw_initialization.cpp | 0 .../{ => vulkan_engine}/glfw/glfw_moniotr.cpp | 0 .../{ => vulkan_engine}/glfw/glfw_window.cpp | 0 .../src/{ => vulkan_engine}/stb/stb_image.cpp | 2 +- Client/src/{ => vulkan_engine}/utilities.cpp | 4 +- .../{ => vulkan_engine}/vulkan/buffers.cpp | 7 +- .../src/{ => vulkan_engine}/vulkan/class.cpp | 2 +- .../{ => vulkan_engine}/vulkan/coordinate.cpp | 2 +- .../vulkan/devices_and_queues.cpp | 2 +- .../{ => vulkan_engine}/vulkan/drawing.cpp | 2 +- .../src/{ => vulkan_engine}/vulkan/engine.cpp | 2 +- .../vulkan/graphics_pipeline.cpp | 4 +- .../vulkan/instance_and_extensions.cpp | 4 +- .../{ => vulkan_engine}/vulkan/physics.cpp | 4 +- .../vulkan/presentation.cpp | 2 +- .../{ => vulkan_engine}/vulkan/texture.cpp | 3 +- .../vulkan/validation_layers.cpp | 4 +- .../vulkan/vk_function_ext_impl.cpp | 3 +- impl/precomp.cpp | 3 + impl/session/session.cpp | 67 +++- impl/socket/address.cpp | 94 +++-- impl/socket/iocp.cpp | 66 ++-- impl/socket/socket.cpp | 112 ++++++ impl/socket/tcp_socket.cpp | 2 +- impl/socket/udp_socket.cpp | 111 +----- impl/socket/wsa_manager.cpp | 2 +- impl/transport/transport.cpp | 4 +- include/precomp.h | 27 +- include/session/session.h | 20 +- include/socket/address.h | 5 +- include/socket/iocp.h | 360 +++++------------- include/socket/socket.h | 45 +++ include/socket/tcp_socket.h | 26 +- include/socket/udp_socket.h | 42 +- include/socket/wsa_manager.h | 2 +- include/transport/transport.h | 4 +- 55 files changed, 608 insertions(+), 683 deletions(-) create mode 100644 Client/include/asteroid/game.h rename Client/include/{ => vulkan_engine}/asset/loader.h (89%) rename Client/include/{ => vulkan_engine}/asset/object/material.h (68%) rename Client/include/{ => vulkan_engine}/asset/object/model.h (98%) rename Client/include/{ => vulkan_engine}/utilities.h (100%) rename Client/include/{ => vulkan_engine}/vulkan/buffer_handle.h (100%) rename Client/include/{ => vulkan_engine}/vulkan/coordinate.h (94%) rename Client/include/{ => vulkan_engine}/vulkan/engine.h (97%) rename Client/include/{ => vulkan_engine}/vulkan/graphics.h (100%) rename Client/include/{ => vulkan_engine}/vulkan/physics.h (87%) rename Client/include/{ => vulkan_engine}/vulkan/texture_handle.h (100%) rename Client/include/{ => vulkan_engine}/vulkan/uniform_transformations.h (100%) rename Client/include/{ => vulkan_engine}/vulkan/vertex.h (100%) create mode 100644 Client/src/asteroid/begin_play.cpp create mode 100644 Client/src/asteroid/main.cpp rename Client/src/{main.cpp => asteroid/tick.cpp} (55%) delete mode 100644 Client/src/vulkan/graphics.cpp rename Client/src/{ => vulkan_engine}/asset/loader.cpp (96%) rename Client/src/{ => vulkan_engine}/asset/object/model.cpp (89%) rename Client/src/{ => vulkan_engine}/glfw/glfw_initialization.cpp (100%) rename Client/src/{ => vulkan_engine}/glfw/glfw_moniotr.cpp (100%) rename Client/src/{ => vulkan_engine}/glfw/glfw_window.cpp (100%) rename Client/src/{ => vulkan_engine}/stb/stb_image.cpp (95%) rename Client/src/{ => vulkan_engine}/utilities.cpp (94%) rename Client/src/{ => vulkan_engine}/vulkan/buffers.cpp (98%) rename Client/src/{ => vulkan_engine}/vulkan/class.cpp (98%) rename Client/src/{ => vulkan_engine}/vulkan/coordinate.cpp (97%) rename Client/src/{ => vulkan_engine}/vulkan/devices_and_queues.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/drawing.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/engine.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/graphics_pipeline.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/instance_and_extensions.cpp (97%) rename Client/src/{ => vulkan_engine}/vulkan/physics.cpp (98%) rename Client/src/{ => vulkan_engine}/vulkan/presentation.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/texture.cpp (99%) rename Client/src/{ => vulkan_engine}/vulkan/validation_layers.cpp (96%) rename Client/src/{ => vulkan_engine}/vulkan/vk_function_ext_impl.cpp (95%) create mode 100644 impl/precomp.cpp create mode 100644 impl/socket/socket.cpp create mode 100644 include/socket/socket.h diff --git a/Client/include/asteroid/game.h b/Client/include/asteroid/game.h new file mode 100644 index 0000000..56e4730 --- /dev/null +++ b/Client/include/asteroid/game.h @@ -0,0 +1,8 @@ +#pragma once + +namespace veng { +class Engine; +} + +void BeginPlay(veng::Engine& engine); +void Tick(veng::Engine& engine, std::float_t delta_time); diff --git a/Client/include/asset/loader.h b/Client/include/vulkan_engine/asset/loader.h similarity index 89% rename from Client/include/asset/loader.h rename to Client/include/vulkan_engine/asset/loader.h index 65eea2b..17372a0 100644 --- a/Client/include/asset/loader.h +++ b/Client/include/vulkan_engine/asset/loader.h @@ -1,6 +1,6 @@ #pragma once -#include "asset/object/model.h" +#include "vulkan_engine/asset/object/model.h" #include "assimp/Importer.hpp" #include "assimp/postprocess.h" #include "assimp/scene.h" diff --git a/Client/include/asset/object/material.h b/Client/include/vulkan_engine/asset/object/material.h similarity index 68% rename from Client/include/asset/object/material.h rename to Client/include/vulkan_engine/asset/object/material.h index 6149499..afda162 100644 --- a/Client/include/asset/object/material.h +++ b/Client/include/vulkan_engine/asset/object/material.h @@ -1,6 +1,6 @@ #pragma once -#include "vulkan/texture_handle.h" +#include "vulkan_engine/vulkan/texture_handle.h" namespace veng { struct Material { diff --git a/Client/include/asset/object/model.h b/Client/include/vulkan_engine/asset/object/model.h similarity index 98% rename from Client/include/asset/object/model.h rename to Client/include/vulkan_engine/asset/object/model.h index 752b5a4..503d70a 100644 --- a/Client/include/asset/object/model.h +++ b/Client/include/vulkan_engine/asset/object/model.h @@ -5,8 +5,8 @@ #include #include "material.h" -#include "vulkan/buffer_handle.h" -#include "vulkan/vertex.h" +#include "vulkan_engine/vulkan/buffer_handle.h" +#include "vulkan_engine/vulkan/vertex.h" namespace veng { struct Model { diff --git a/Client/include/utilities.h b/Client/include/vulkan_engine/utilities.h similarity index 100% rename from Client/include/utilities.h rename to Client/include/vulkan_engine/utilities.h diff --git a/Client/include/vulkan/buffer_handle.h b/Client/include/vulkan_engine/vulkan/buffer_handle.h similarity index 100% rename from Client/include/vulkan/buffer_handle.h rename to Client/include/vulkan_engine/vulkan/buffer_handle.h diff --git a/Client/include/vulkan/coordinate.h b/Client/include/vulkan_engine/vulkan/coordinate.h similarity index 94% rename from Client/include/vulkan/coordinate.h rename to Client/include/vulkan_engine/vulkan/coordinate.h index 2b9ef5f..85a9213 100644 --- a/Client/include/vulkan/coordinate.h +++ b/Client/include/vulkan_engine/vulkan/coordinate.h @@ -2,7 +2,7 @@ #include -#include "asset/object/model.h" +#include "vulkan_engine/asset/object/model.h" namespace std { template <> diff --git a/Client/include/vulkan/engine.h b/Client/include/vulkan_engine/vulkan/engine.h similarity index 97% rename from Client/include/vulkan/engine.h rename to Client/include/vulkan_engine/vulkan/engine.h index 7b9902e..73c635a 100644 --- a/Client/include/vulkan/engine.h +++ b/Client/include/vulkan_engine/vulkan/engine.h @@ -1,6 +1,6 @@ #pragma once -#include "asset/loader.h" +#include "vulkan_engine/asset/loader.h" #include "graphics.h" #include "physics.h" #include "utils/thread_pool.h" diff --git a/Client/include/vulkan/graphics.h b/Client/include/vulkan_engine/vulkan/graphics.h similarity index 100% rename from Client/include/vulkan/graphics.h rename to Client/include/vulkan_engine/vulkan/graphics.h diff --git a/Client/include/vulkan/physics.h b/Client/include/vulkan_engine/vulkan/physics.h similarity index 87% rename from Client/include/vulkan/physics.h rename to Client/include/vulkan_engine/vulkan/physics.h index 3506cc4..3214b91 100644 --- a/Client/include/vulkan/physics.h +++ b/Client/include/vulkan_engine/vulkan/physics.h @@ -1,7 +1,7 @@ #pragma once -#include "asset/object/model.h" -#include "vulkan/vertex.h" +#include "vulkan_engine/asset/object/model.h" +#include "vulkan_engine/vulkan/vertex.h" #include "utils/thread_pool.h" namespace veng { diff --git a/Client/include/vulkan/texture_handle.h b/Client/include/vulkan_engine/vulkan/texture_handle.h similarity index 100% rename from Client/include/vulkan/texture_handle.h rename to Client/include/vulkan_engine/vulkan/texture_handle.h diff --git a/Client/include/vulkan/uniform_transformations.h b/Client/include/vulkan_engine/vulkan/uniform_transformations.h similarity index 100% rename from Client/include/vulkan/uniform_transformations.h rename to Client/include/vulkan_engine/vulkan/uniform_transformations.h diff --git a/Client/include/vulkan/vertex.h b/Client/include/vulkan_engine/vulkan/vertex.h similarity index 100% rename from Client/include/vulkan/vertex.h rename to Client/include/vulkan_engine/vulkan/vertex.h diff --git a/Client/src/asteroid/begin_play.cpp b/Client/src/asteroid/begin_play.cpp new file mode 100644 index 0000000..3dfa5f3 --- /dev/null +++ b/Client/src/asteroid/begin_play.cpp @@ -0,0 +1,64 @@ +#include "asteroid/game.h" + +#include "vulkan_engine/vulkan/engine.h" + +void BeginPlay(veng::Engine& engine) { + veng::Model* const player = engine.SpawnModel("player", "player"); + player->scale = glm::vec3(.02f); + player->colision = true; + player->OnColision = [](veng::Model* self, veng::Model* other) { + if (other->owner == self) return; + spdlog::info("{} and {} is nearby.", (void*)self, (void*)other); + + spdlog::info("{} 's owner: {}", (void*)self, (void*)self->owner); + spdlog::info("{} 's owner: {}", (void*)other, (void*)other->owner); + + other->colision = false; + other->visible = false; + }; + veng::Model* const player_flame = + engine.SpawnModel("player_flame", "player_flame"); + player_flame->scale = player->scale; + player_flame->colision = false; + + spdlog::info("player addr: {}", (void*)player); + + veng::Model* const other_player = engine.SpawnModel("player", "other_player"); + other_player->position = glm::vec3(1.f, 0.f, 0.f); + other_player->scale = glm::vec3(.02f); + other_player->colision = true; + other_player->OnColision = [](veng::Model* self, veng::Model* other) { + if (other->owner == self) return; + spdlog::info("{} and {} is nearby.", (void*)self, (void*)other); + + spdlog::info("{} 's owner: {}", (void*)self, (void*)self->owner); + spdlog::info("{} 's owner: {}", (void*)other, (void*)other->owner); + + other->colision = false; + other->visible = false; + }; + + spdlog::info("other player addr: {}", (void*)other_player); + + veng::Model* const camera_lag = engine.SpawnModel("", "camera_lag"); + camera_lag->colision = false; + camera_lag->position = player->position; + + veng::Model* const background = engine.SpawnModel("", "background"); + background->colision = false; + background->position = {background->position.x, background->position.y, 30.f}; + background->scale *= 100; + + veng::Model* const background0 = + engine.SpawnModel("background", "background0"); + background0->scale = background->scale; + veng::Model* const background1 = + engine.SpawnModel("background", "background1"); + background1->scale = background->scale; + veng::Model* const background2 = + engine.SpawnModel("background", "background2"); + background2->scale = background->scale; + veng::Model* const background3 = + engine.SpawnModel("background", "background3"); + background3->scale = background->scale; +} diff --git a/Client/src/asteroid/main.cpp b/Client/src/asteroid/main.cpp new file mode 100644 index 0000000..e4ca51a --- /dev/null +++ b/Client/src/asteroid/main.cpp @@ -0,0 +1,37 @@ +#include "asteroid/game.h" +#include "glfw/glfw_initialization.h" +#include "glfw/glfw_monitor.h" +#include "glfw/glfw_window.h" +#include "vulkan_engine/vulkan/engine.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "socket/iocp.h" + +std::int32_t main(std::int32_t argc, gsl::zstring* argv) { + Network::IOCP iocp; + + const veng::GlfwInitialization _glfw; + + veng::Window window("Vulkan Engine", {800, 600}); + window.TryMoveToMonitor(0); + + veng::Graphics graphics(&window); + veng::Engine engine(&graphics); + + engine.LoadModelAsset("assets/player.fbx", "player"); + engine.LoadModelAsset("assets/player_flame.fbx", "player_flame"); + engine.LoadModelAsset("assets/bullet.fbx", "bullet"); + engine.LoadModelAsset("assets/background.fbx", "background"); + + engine.BeginPlay = BeginPlay; + engine.Tick = Tick; + + engine.init(); + + while (!window.ShouldClose()) { + glfwPollEvents(); + + engine.Update(); + } + + return EXIT_SUCCESS; +} diff --git a/Client/src/main.cpp b/Client/src/asteroid/tick.cpp similarity index 55% rename from Client/src/main.cpp rename to Client/src/asteroid/tick.cpp index 634eaa1..3a2bf7e 100644 --- a/Client/src/main.cpp +++ b/Client/src/asteroid/tick.cpp @@ -1,79 +1,6 @@ -#include +#include "asteroid/game.h" -#include -#include -#include - -#include "glfw/glfw_initialization.h" -#include "glfw/glfw_monitor.h" -#include "glfw/glfw_window.h" -#include "precomp.h" -#include "vulkan/coordinate.h" -#include "vulkan/engine.h" -#include "vulkan/graphics.h" - -void BeginPlay(veng::Engine& engine) { - veng::Model* const player = engine.SpawnModel("player", "player"); - player->scale = glm::vec3(.02f); - player->colision = true; - player->OnColision = [](veng::Model* self, veng::Model* other) { - if (other->owner == self) return; - std::cout << self << " and " << other << " is Nearby." << std::endl; - - std::cout << self << "'s owner: " << self->owner << std::endl; - std::cout << other << "'s owner: " << other->owner << std::endl; - - std::cout << "Colided." << std::endl; - other->colision = false; - other->visible = false; - }; - veng::Model* const player_flame = - engine.SpawnModel("player_flame", "player_flame"); - player_flame->scale = player->scale; - player_flame->colision = false; - - std::cout << "player addr: " << player << std::endl; - - veng::Model* const other_player = engine.SpawnModel("player", "other_player"); - other_player->position = glm::vec3(1.f, 0.f, 0.f); - other_player->scale = glm::vec3(.02f); - other_player->colision = true; - other_player->OnColision = [](veng::Model* self, veng::Model* other) { - if (other->owner == self) return; - std::cout << self << " and " << other << " is Nearby." << std::endl; - - std::cout << self << "'s owner: " << self->owner << std::endl; - std::cout << other << "'s owner: " << other->owner << std::endl; - - std::cout << "Colided." << std::endl; - other->colision = false; - other->visible = false; - }; - - std::cout << "other player addr: " << other_player << std::endl; - - veng::Model* const camera_lag = engine.SpawnModel("", "camera_lag"); - camera_lag->colision = false; - camera_lag->position = player->position; - - veng::Model* const background = engine.SpawnModel("", "background"); - background->colision = false; - background->position = {background->position.x, background->position.y, 30.f}; - background->scale *= 100; - - veng::Model* const background0 = - engine.SpawnModel("background", "background0"); - background0->scale = background->scale; - veng::Model* const background1 = - engine.SpawnModel("background", "background1"); - background1->scale = background->scale; - veng::Model* const background2 = - engine.SpawnModel("background", "background2"); - background2->scale = background->scale; - veng::Model* const background3 = - engine.SpawnModel("background", "background3"); - background3->scale = background->scale; -} +#include "vulkan_engine/vulkan/engine.h" void Tick(veng::Engine& engine, std::float_t delta_time) { static std::float_t bullet_cooldown = 0.f; @@ -123,7 +50,7 @@ void Tick(veng::Engine& engine, std::float_t delta_time) { if (glfwGetKey(engine.vulkan_graphics->window->GetHandle(), GLFW_KEY_SPACE) == GLFW_PRESS) { if (bullet_cooldown > std::numeric_limits::epsilon()) { - bullet_cooldown - delta_time; + bullet_cooldown -= delta_time; } else { bullet_cooldown = .2f; veng::Model* const bullet = @@ -134,7 +61,7 @@ void Tick(veng::Engine& engine, std::float_t delta_time) { bullet->scale = player->scale; bullet->colision = true; - std::cout << "bullet address: " << bullet << std::endl; + spdlog::info("bullet address: {}", (void*)bullet); } } if (glfwGetKey(engine.vulkan_graphics->window->GetHandle(), GLFW_KEY_A) == @@ -178,31 +105,3 @@ void Tick(veng::Engine& engine, std::float_t delta_time) { sparse = glm::vec3(-1.f, -1.f, 0.f); background3->position = background->position + sparse * background->scale; } - -std::int32_t main(std::int32_t argc, gsl::zstring* argv) { - const veng::GlfwInitialization _glfw; - - veng::Window window("Vulkan Engine", {800, 600}); - window.TryMoveToMonitor(0); - - veng::Graphics graphics(&window); - veng::Engine engine(&graphics); - - engine.LoadModelAsset("assets/player.fbx", "player"); - engine.LoadModelAsset("assets/player_flame.fbx", "player_flame"); - engine.LoadModelAsset("assets/bullet.fbx", "bullet"); - engine.LoadModelAsset("assets/background.fbx", "background"); - - engine.BeginPlay = BeginPlay; - engine.Tick = Tick; - - engine.init(); - - while (!window.ShouldClose()) { - glfwPollEvents(); - - engine.Update(); - } - - return EXIT_SUCCESS; -} diff --git a/Client/src/vulkan/graphics.cpp b/Client/src/vulkan/graphics.cpp deleted file mode 100644 index 9f688fb..0000000 --- a/Client/src/vulkan/graphics.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "vulkan/graphics.h" - -#include - -#include - -#include "precomp.h" - -namespace veng { - -} // namespace veng diff --git a/Client/src/asset/loader.cpp b/Client/src/vulkan_engine/asset/loader.cpp similarity index 96% rename from Client/src/asset/loader.cpp rename to Client/src/vulkan_engine/asset/loader.cpp index d6421fa..9186c3b 100644 --- a/Client/src/asset/loader.cpp +++ b/Client/src/vulkan_engine/asset/loader.cpp @@ -1,6 +1,7 @@ -#include "asset/loader.h" +#include "vulkan_engine/asset/loader.h" #include "stb/stb_image.h" +#include "vulkan_engine/utilities.h" namespace veng { diff --git a/Client/src/asset/object/model.cpp b/Client/src/vulkan_engine/asset/object/model.cpp similarity index 89% rename from Client/src/asset/object/model.cpp rename to Client/src/vulkan_engine/asset/object/model.cpp index b867264..5c6143f 100644 --- a/Client/src/asset/object/model.cpp +++ b/Client/src/vulkan_engine/asset/object/model.cpp @@ -1,6 +1,6 @@ -#include "asset/object/model.h" +#include "vulkan_engine/asset/object/model.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" namespace veng { diff --git a/Client/src/glfw/glfw_initialization.cpp b/Client/src/vulkan_engine/glfw/glfw_initialization.cpp similarity index 100% rename from Client/src/glfw/glfw_initialization.cpp rename to Client/src/vulkan_engine/glfw/glfw_initialization.cpp diff --git a/Client/src/glfw/glfw_moniotr.cpp b/Client/src/vulkan_engine/glfw/glfw_moniotr.cpp similarity index 100% rename from Client/src/glfw/glfw_moniotr.cpp rename to Client/src/vulkan_engine/glfw/glfw_moniotr.cpp diff --git a/Client/src/glfw/glfw_window.cpp b/Client/src/vulkan_engine/glfw/glfw_window.cpp similarity index 100% rename from Client/src/glfw/glfw_window.cpp rename to Client/src/vulkan_engine/glfw/glfw_window.cpp diff --git a/Client/src/stb/stb_image.cpp b/Client/src/vulkan_engine/stb/stb_image.cpp similarity index 95% rename from Client/src/stb/stb_image.cpp rename to Client/src/vulkan_engine/stb/stb_image.cpp index bdc0ce6..611de2a 100644 --- a/Client/src/stb/stb_image.cpp +++ b/Client/src/vulkan_engine/stb/stb_image.cpp @@ -6,4 +6,4 @@ #ifndef NDEBUG #define __OPTIMIZE__ 1 -#endif \ No newline at end of file +#endif diff --git a/Client/src/utilities.cpp b/Client/src/vulkan_engine/utilities.cpp similarity index 94% rename from Client/src/utilities.cpp rename to Client/src/vulkan_engine/utilities.cpp index 1f8410f..561b620 100644 --- a/Client/src/utilities.cpp +++ b/Client/src/vulkan_engine/utilities.cpp @@ -1,9 +1,7 @@ -#include "utilities.h" +#include "vulkan_engine/utilities.h" #include -#include "precomp.h" - namespace veng { bool streq(gsl::czstring left, gsl::czstring right) { return std::strcmp(left, right) == 0; diff --git a/Client/src/vulkan/buffers.cpp b/Client/src/vulkan_engine/vulkan/buffers.cpp similarity index 98% rename from Client/src/vulkan/buffers.cpp rename to Client/src/vulkan_engine/vulkan/buffers.cpp index 8dc87bc..8ca2b25 100644 --- a/Client/src/vulkan/buffers.cpp +++ b/Client/src/vulkan_engine/vulkan/buffers.cpp @@ -1,9 +1,8 @@ #include -#include "asset/object/model.h" -#include "precomp.h" -#include "vulkan/graphics.h" -#include "vulkan/uniform_transformations.h" +#include "vulkan_engine/asset/object/model.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "vulkan_engine/vulkan/uniform_transformations.h" namespace veng { diff --git a/Client/src/vulkan/class.cpp b/Client/src/vulkan_engine/vulkan/class.cpp similarity index 98% rename from Client/src/vulkan/class.cpp rename to Client/src/vulkan_engine/vulkan/class.cpp index b052b65..848df6c 100644 --- a/Client/src/vulkan/class.cpp +++ b/Client/src/vulkan_engine/vulkan/class.cpp @@ -1,7 +1,7 @@ #include #include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" namespace veng { diff --git a/Client/src/vulkan/coordinate.cpp b/Client/src/vulkan_engine/vulkan/coordinate.cpp similarity index 97% rename from Client/src/vulkan/coordinate.cpp rename to Client/src/vulkan_engine/vulkan/coordinate.cpp index f7e969d..b8f0ec6 100644 --- a/Client/src/vulkan/coordinate.cpp +++ b/Client/src/vulkan_engine/vulkan/coordinate.cpp @@ -1,4 +1,4 @@ -#include "vulkan/coordinate.h" +#include "vulkan_engine/vulkan/coordinate.h" namespace veng { Coord Coord::operator+(const Coord& other) const { diff --git a/Client/src/vulkan/devices_and_queues.cpp b/Client/src/vulkan_engine/vulkan/devices_and_queues.cpp similarity index 99% rename from Client/src/vulkan/devices_and_queues.cpp rename to Client/src/vulkan_engine/vulkan/devices_and_queues.cpp index c0229ee..75834c1 100644 --- a/Client/src/vulkan/devices_and_queues.cpp +++ b/Client/src/vulkan_engine/vulkan/devices_and_queues.cpp @@ -1,7 +1,7 @@ #include #include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" namespace veng { diff --git a/Client/src/vulkan/drawing.cpp b/Client/src/vulkan_engine/vulkan/drawing.cpp similarity index 99% rename from Client/src/vulkan/drawing.cpp rename to Client/src/vulkan_engine/vulkan/drawing.cpp index 6433918..039c507 100644 --- a/Client/src/vulkan/drawing.cpp +++ b/Client/src/vulkan_engine/vulkan/drawing.cpp @@ -1,7 +1,7 @@ #include #include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" namespace veng { diff --git a/Client/src/vulkan/engine.cpp b/Client/src/vulkan_engine/vulkan/engine.cpp similarity index 99% rename from Client/src/vulkan/engine.cpp rename to Client/src/vulkan_engine/vulkan/engine.cpp index bdfcde6..6894698 100644 --- a/Client/src/vulkan/engine.cpp +++ b/Client/src/vulkan_engine/vulkan/engine.cpp @@ -1,4 +1,4 @@ -#include "vulkan/engine.h" +#include "vulkan_engine/vulkan/engine.h" #include "precomp.h" diff --git a/Client/src/vulkan/graphics_pipeline.cpp b/Client/src/vulkan_engine/vulkan/graphics_pipeline.cpp similarity index 99% rename from Client/src/vulkan/graphics_pipeline.cpp rename to Client/src/vulkan_engine/vulkan/graphics_pipeline.cpp index cb64a7a..3dc96da 100644 --- a/Client/src/vulkan/graphics_pipeline.cpp +++ b/Client/src/vulkan_engine/vulkan/graphics_pipeline.cpp @@ -1,7 +1,7 @@ #include -#include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "vulkan_engine/utilities.h" namespace veng { diff --git a/Client/src/vulkan/instance_and_extensions.cpp b/Client/src/vulkan_engine/vulkan/instance_and_extensions.cpp similarity index 97% rename from Client/src/vulkan/instance_and_extensions.cpp rename to Client/src/vulkan_engine/vulkan/instance_and_extensions.cpp index e08e9ae..185806b 100644 --- a/Client/src/vulkan/instance_and_extensions.cpp +++ b/Client/src/vulkan_engine/vulkan/instance_and_extensions.cpp @@ -1,7 +1,7 @@ #include -#include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "vulkan_engine/utilities.h" namespace veng { diff --git a/Client/src/vulkan/physics.cpp b/Client/src/vulkan_engine/vulkan/physics.cpp similarity index 98% rename from Client/src/vulkan/physics.cpp rename to Client/src/vulkan_engine/vulkan/physics.cpp index 533a1c0..057a48c 100644 --- a/Client/src/vulkan/physics.cpp +++ b/Client/src/vulkan_engine/vulkan/physics.cpp @@ -1,10 +1,8 @@ -#include "vulkan/physics.h" +#include "vulkan_engine/vulkan/physics.h" #include #include -#include "precomp.h" - namespace veng { void Physics::invokeOnColisionEvent( gsl::not_null thread_pool, gsl::span models) { diff --git a/Client/src/vulkan/presentation.cpp b/Client/src/vulkan_engine/vulkan/presentation.cpp similarity index 99% rename from Client/src/vulkan/presentation.cpp rename to Client/src/vulkan_engine/vulkan/presentation.cpp index 92e7c85..2940ed9 100644 --- a/Client/src/vulkan/presentation.cpp +++ b/Client/src/vulkan_engine/vulkan/presentation.cpp @@ -1,4 +1,4 @@ -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" #include #include "precomp.h" diff --git a/Client/src/vulkan/texture.cpp b/Client/src/vulkan_engine/vulkan/texture.cpp similarity index 99% rename from Client/src/vulkan/texture.cpp rename to Client/src/vulkan_engine/vulkan/texture.cpp index e20616b..fbd8370 100644 --- a/Client/src/vulkan/texture.cpp +++ b/Client/src/vulkan_engine/vulkan/texture.cpp @@ -1,7 +1,8 @@ #include #include "stb/stb_image.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "vulkan_engine/utilities.h" namespace veng { diff --git a/Client/src/vulkan/validation_layers.cpp b/Client/src/vulkan_engine/vulkan/validation_layers.cpp similarity index 96% rename from Client/src/vulkan/validation_layers.cpp rename to Client/src/vulkan_engine/vulkan/validation_layers.cpp index b37c94e..9d35603 100644 --- a/Client/src/vulkan/validation_layers.cpp +++ b/Client/src/vulkan_engine/vulkan/validation_layers.cpp @@ -1,5 +1,5 @@ -#include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" +#include "vulkan_engine/utilities.h" namespace veng { diff --git a/Client/src/vulkan/vk_function_ext_impl.cpp b/Client/src/vulkan_engine/vulkan/vk_function_ext_impl.cpp similarity index 95% rename from Client/src/vulkan/vk_function_ext_impl.cpp rename to Client/src/vulkan_engine/vulkan/vk_function_ext_impl.cpp index d4517a5..16441dc 100644 --- a/Client/src/vulkan/vk_function_ext_impl.cpp +++ b/Client/src/vulkan_engine/vulkan/vk_function_ext_impl.cpp @@ -1,5 +1,4 @@ -#include "precomp.h" -#include "vulkan/graphics.h" +#include "vulkan_engine/vulkan/graphics.h" VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, diff --git a/impl/precomp.cpp b/impl/precomp.cpp new file mode 100644 index 0000000..e745edf --- /dev/null +++ b/impl/precomp.cpp @@ -0,0 +1,3 @@ +#include "precomp.h" + +int close(int sock) { return ::closesocket(sock); } diff --git a/impl/session/session.cpp b/impl/session/session.cpp index b9745b8..a9e86d8 100644 --- a/impl/session/session.cpp +++ b/impl/session/session.cpp @@ -1,10 +1,71 @@ #include "session/session.h" +#include "socket/tcp_socket.h" +#include "socket/udp_socket.h" #include "utils/thread_pool.h" -namespace happytanuki { +namespace Network { -Session::Session(utils::ThreadPool* tp, SessionProtocol proto) { +Session::Session(gsl::not_null iocp, utils::ThreadPool* tp, + SessionType type, SessionProtocol proto, Network::Address addr) + : iocp_(iocp), tp_(tp), proto_(proto) { + switch (proto) { + case SessionProtocol::UDP: + case SessionProtocol::QUIC: { + Network::UDPSocket* sock = new Network::UDPSocket(); + sock_ = sock; + sock->init(addr.family); + switch (type) { + case SessionType::CONNECT: + ssl_ctx_ = ::SSL_CTX_new(::OSSL_QUIC_client_method()); + if (ssl_ctx_ == nullptr) { + spdlog::critical("SSL_CTX_new()"); + std::exit(EXIT_FAILURE); + } + ::SSL_CTX_set_verify(ssl_ctx_, SSL_VERIFY_PEER, NULL); + + if (!::SSL_CTX_set_default_verify_paths(ssl_ctx_)) { + spdlog::critical("SSL_CTX_set_default_verify_paths()"); + std::exit(EXIT_FAILURE); + } + break; + case SessionType::LISTEN: + sock->bind(addr); + break; + default: + std::exit(EXIT_FAILURE); + } + } break; + case SessionProtocol::TCP: + case SessionProtocol::TLS: { + Network::TCPSocket* sock = new Network::TCPSocket(); + sock_ = sock; + sock->init(addr.family); + switch (type) { + case SessionType::CONNECT: + sock->connect(addr); + break; + case SessionType::LISTEN: + sock->bind(addr); + sock->listen(SOMAXCONN); + break; + default: + std::exit(EXIT_FAILURE); + } + } break; + default: + std::exit(EXIT_FAILURE); + } + + ssl_ = ::SSL_new(ssl_ctx_); + if (ssl_ == nullptr) { + spdlog::critical("SSL_new()"); + std::exit(EXIT_FAILURE); + } } -} // namespace happytanuki +Session::~Session() { + if (sock_ != nullptr) delete sock_; +} + +} // namespace Network diff --git a/impl/socket/address.cpp b/impl/socket/address.cpp index bf8bbdb..81c4a09 100644 --- a/impl/socket/address.cpp +++ b/impl/socket/address.cpp @@ -1,10 +1,12 @@ #include "socket/address.h" +#include +#include +#include + #include -#include "precomp.h" - -namespace Socket { +namespace Network { Address::Address() { zeroFill(); } @@ -17,55 +19,56 @@ void Address::zeroFill() { memset(&addr_in6, 0, sizeof(addr_in6)); } void Address::set(int type, gsl::czstring presentationAddr, std::uint16_t port) { zeroFill(); + setType(type); - if (type == AF_INET) { - addr_in.sin_family = AF_INET; - ::inet_pton(AF_INET, presentationAddr, &addr_in.sin_addr); - addr_in.sin_port = htons(port); - length = sizeof(sockaddr_in); - } else if (type == AF_INET6) { - addr_in6.sin6_family = AF_INET6; - ::inet_pton(AF_INET6, presentationAddr, &addr_in6.sin6_addr); - addr_in6.sin6_port = htons(port); - length = sizeof(sockaddr_in6); + BIO_ADDRINFO* res; + if (!BIO_lookup_ex(presentationAddr, std::to_string(port).c_str(), + BIO_LOOKUP_CLIENT, type, SOCK_DGRAM, 0, &res)) { + throw std::runtime_error("can't resolve address"); } + + int sock = -1; + for (const BIO_ADDRINFO* ai = res; ai != nullptr; + ai = ::BIO_ADDRINFO_next(ai)) { + sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0); + if (sock == -1) continue; + } + ::close(sock); + + addr_in.sin_family = type; + ::inet_pton(type, presentationAddr, &addr_in.sin_addr); + addr_in.sin_port = htons(port); } void Address::set(int type, in_addr_t addr, std::uint16_t port) { zeroFill(); + setType(type); - if (type == AF_INET) { - addr_in.sin_family = AF_INET; - addr_in.sin_addr.s_addr = htonl(addr); - addr_in.sin_port = htons(port); - length = sizeof(sockaddr_in); - } + addr_in.sin_family = type; + addr_in.sin_addr.s_addr = htonl(addr); + addr_in.sin_port = htons(port); } void Address::set(int type, in_addr addr, std::uint16_t port) { zeroFill(); + setType(type); - if (type == AF_INET) { - addr_in.sin_family = AF_INET; - addr_in.sin_addr = addr; - addr_in.sin_port = htons(port); - length = sizeof(sockaddr_in); - } + addr_in.sin_family = type; + addr_in.sin_addr = addr; + addr_in.sin_port = htons(port); } void Address::set(int type, in6_addr addr, std::uint16_t port) { zeroFill(); + setType(type); - if (type == AF_INET6) { - addr_in6.sin6_family = AF_INET6; - addr_in6.sin6_addr = addr; - addr_in6.sin6_port = htons(port); - length = sizeof(sockaddr_in6); - } + addr_in6.sin6_family = type; + addr_in6.sin6_addr = addr; + addr_in6.sin6_port = htons(port); } void Address::setType(int type) { - zeroFill(); + family = type; if (type == AF_INET) length = sizeof(sockaddr_in); @@ -74,32 +77,23 @@ void Address::setType(int type) { } Address::operator std::string() { - std::optional port = getPort(); + char addrStr[INET6_ADDRSTRLEN]; - if (!port) return std::string(); + if (family != AF_INET && family != AF_INET6 || !getPort()) + return std::string(); - if (length == sizeof(addr_in)) { - char addrStr[INET_ADDRSTRLEN]; - ::inet_ntop(AF_INET, &addr_in.sin_addr, addrStr, sizeof(addrStr)); + ::inet_ntop(family, &addr, addrStr, sizeof(addrStr)); - return std::format("{}:{}", addrStr, port.value()); - } else if (length == sizeof(addr_in6)) { - char addrStr[INET6_ADDRSTRLEN]; - ::inet_ntop(AF_INET6, &addr_in6.sin6_addr, addrStr, sizeof(addrStr)); - - return std::format("{}:{}", addrStr, port.value()); - } - - return std::string(); + return std::format("{}:{}", addrStr, getPort()); } -std::uint16_t Address::getPort() { - if (length == sizeof(addr_in)) +std::uint16_t Address::getPort() const { + if (family == AF_INET) return ntohs(addr_in.sin_port); - else if (length == sizeof(addr_in6)) + else if (family == AF_INET6) return ntohs(addr_in6.sin6_port); else return 0; } -} // namespace Chattr +} // namespace Network diff --git a/impl/socket/iocp.cpp b/impl/socket/iocp.cpp index 3ee9bb3..550b3de 100644 --- a/impl/socket/iocp.cpp +++ b/impl/socket/iocp.cpp @@ -2,68 +2,52 @@ #include "utils/thread_pool.h" -namespace Socket { - -IOCP::IOCP() {} +namespace Network { IOCP::~IOCP() { destruct(); } void IOCP::destruct() { #ifdef __linux__ - uint64_t u = 1; - ::write(epollDetroyerFd, &u, sizeof(uint64_t)); - close(epollfd_); + #endif } void IOCP::registerSocket(IOCPPASSINDATA* data) { - data->event = IOCPEVENT::READ; #ifdef _WIN32 HANDLE returnData = ::CreateIoCompletionPort( (HANDLE)data->socket->sock, completionPort_, data->socket->sock, 0); if (returnData == 0) completionPort_ = returnData; -#elif __linux__ - int flags = ::fcntl(data->socket->sock, F_GETFL); - flags |= O_NONBLOCK; - fcntl(data->socket->sock, F_SETFL, flags); - - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLONESHOT; - data->sendQueue = std::make_shared>(); - ev.data.ptr = data; - int rc = epoll_ctl(epollfd_, EPOLL_CTL_ADD, data->socket->sock, &ev); - if (rc < 0) log::critical("epoll_ctl()"); #endif } -int IOCP::recv(IOCPPASSINDATA* data, int bufferCount) { - data->event = IOCPEVENT::READ; +//int IOCP::recv(IOCPPASSINDATA* data, int bufferCount) { +// data->event = IOCPEVENT::READ; +//#ifdef _WIN32 +// DWORD recvbytes = 0, flags = 0; +// return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, +// &flags, &data->overlapped, NULL); +//#endif +//} +// +//int IOCP::send(IOCPPASSINDATA* data, int bufferCount, int __flags) { +// data->event = IOCPEVENT::WRITE; +//#ifdef _WIN32 +// DWORD sendbytes = 0; +// return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, +// __flags, &data->overlapped, NULL); +//#endif +//} + +int IOCP::recv(IOCPPASSINDATA& data) { + data.event = IOCPEVENT::READ; #ifdef _WIN32 - DWORD recvbytes = 0, flags = 0; - return ::WSARecv(data->socket->sock, &data->wsabuf, bufferCount, &recvbytes, - &flags, &data->overlapped, NULL); -#elif __linux__ - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLONESHOT; - ev.data.ptr = data; - return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev); #endif } -int IOCP::send(IOCPPASSINDATA* data, int bufferCount, - int __flags) { - data->event = IOCPEVENT::WRITE; +int IOCP::send(std::vector data) { + data.event = IOCPEVENT::WRITE; #ifdef _WIN32 - DWORD sendbytes = 0; - return ::WSASend(data->socket->sock, &data->wsabuf, bufferCount, &sendbytes, - __flags, &data->overlapped, NULL); -#elif __linux__ - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLOUT | EPOLLONESHOT; - ev.data.ptr = data; - data->sendQueue->push(data); - return ::epoll_ctl(epollfd_, EPOLL_CTL_MOD, data->socket->sock, &ev); #endif } -} // namespace Chattr +} // namespace Network diff --git a/impl/socket/socket.cpp b/impl/socket/socket.cpp new file mode 100644 index 0000000..a10d899 --- /dev/null +++ b/impl/socket/socket.cpp @@ -0,0 +1,112 @@ +#include "socket/socket.h" + +namespace Network { + +Socket::Socket(int domain, int type, int protocol) { + init(domain, type, protocol); +} + +Socket::~Socket() { destruct(); } + +int Socket::init(int domain, int type, int protocol) { + this->domain = domain; + + sock = ::socket(domain, type, protocol); + if (sock == INVALID_SOCKET) spdlog::critical("socket()"); + + valid_ = true; + + return 0; +} + +void Socket::destruct() { + if (!valid_) return; +#ifdef _WIN32 + ::closesocket(sock); +#elif __linux__ + ::close(sock); +#endif + valid_ = false; +} + +Socket::operator SOCKET() { + if (valid_) { + valid_ = false; + return sock; + } + spdlog::critical("No valid socket created."); + return INVALID_SOCKET; +} + +void Socket::set(const SOCKET __sock, int __domain) { + if (__sock == INVALID_SOCKET) { + spdlog::critical("socket()"); + std::exit(EXIT_FAILURE); + } + + destruct(); + + sock = __sock; + valid_ = true; +}; + +int Socket::setsockopt(int level, int optname, const char* optval, + int optlen) { + return ::setsockopt(sock, level, optname, optval, optlen); +} + +int Socket::bind(Address __addr) { + bindAddr = __addr; + int retVal = ::bind(sock, &__addr.addr, __addr.length); + if (retVal == INVALID_SOCKET) { + spdlog::critical("bind()"); + std::exit(EXIT_FAILURE); + } + return retVal; +} + +int Socket::recvfrom(void* __restrict __buf, size_t __n, int __flags, + struct Address& __addr) { + std::lock_guard lock(readMutex); + int retVal = ::recvfrom(sock, (char*)__buf, __n, __flags, &__addr.addr, + &__addr.length); + if (retVal == SOCKET_ERROR) spdlog::error("recvfrom()"); + return retVal; +} + +int Socket::sendto(const void* __buf, size_t __n, int __flags, + struct Address __addr) { + std::lock_guard lock(writeMutex); + int retVal = + ::sendto(sock, (char*)__buf, __n, __flags, &__addr.addr, __addr.length); + if (retVal == SOCKET_ERROR) spdlog::error("sendto()"); + return retVal; +} + +Socket::Socket(const Socket& other_) { + memcpy(this, &other_, sizeof(Socket)); + valid_ = false; +} + +Socket::Socket(Socket&& other_) noexcept { + other_.valid_ = false; + memcpy(this, &other_, sizeof(Socket)); + valid_ = true; +} + +Socket& Socket::operator=(const Socket& other_) { + memcpy(this, &other_, sizeof(Socket)); + valid_ = false; + + return *this; +} + +Socket& Socket::operator=(Socket&& other_) noexcept { + other_.valid_ = false; + memcpy(this, &other_, sizeof(Socket)); + valid_ = true; + + return *this; +} + +} // namespace Socket diff --git a/impl/socket/tcp_socket.cpp b/impl/socket/tcp_socket.cpp index c5f6632..8e295c6 100644 --- a/impl/socket/tcp_socket.cpp +++ b/impl/socket/tcp_socket.cpp @@ -1,6 +1,6 @@ #include "socket/tcp_socket.h" -namespace Socket { +namespace Network { int TCPSocket::init(int domain) { return init(domain, SOCK_STREAM, 0); } diff --git a/impl/socket/udp_socket.cpp b/impl/socket/udp_socket.cpp index 7f16a97..8b4e850 100644 --- a/impl/socket/udp_socket.cpp +++ b/impl/socket/udp_socket.cpp @@ -1,112 +1,7 @@ #include "socket/udp_socket.h" -namespace Socket { +namespace Network { -UDPSocket::UDPSocket(int domain, int type, int protocol) { - init(domain, type, protocol); -} +int UDPSocket::init(int domain) { return init(domain, SOCK_DGRAM, 0); } -UDPSocket::~UDPSocket() { destruct(); } - -int UDPSocket::init(int domain, int type, int protocol) { - this->domain = domain; - - sock = ::socket(domain, type, protocol); - if (sock == INVALID_SOCKET) spdlog::critical("socket()"); - - valid_ = true; - - return 0; -} - -void UDPSocket::destruct() { - if (!valid_) return; -#ifdef _WIN32 - ::closesocket(sock); -#elif __linux__ - ::close(sock); -#endif - valid_ = false; -} - -UDPSocket::operator SOCKET() { - if (valid_) { - valid_ = false; - return sock; - } - spdlog::critical("No valid socket created."); - return INVALID_SOCKET; -} - -void UDPSocket::set(const SOCKET __sock, int __domain) { - if (__sock == INVALID_SOCKET) { - spdlog::critical("socket()"); - std::exit(EXIT_FAILURE); - } - - destruct(); - - sock = __sock; - valid_ = true; -}; - -int UDPSocket::setsockopt(int level, int optname, const char* optval, - int optlen) { - return ::setsockopt(sock, level, optname, optval, optlen); -} - -int UDPSocket::bind(Address __addr) { - bindAddr = __addr; - int retVal = ::bind(sock, &__addr.addr, __addr.length); - if (retVal == INVALID_SOCKET) { - spdlog::critical("bind()"); - std::exit(EXIT_FAILURE); - } - return retVal; -} - -int UDPSocket::recvfrom(void* __restrict __buf, size_t __n, int __flags, - struct Address& __addr) { - std::lock_guard lock(readMutex); - int retVal = ::recvfrom(sock, (char*)__buf, __n, __flags, &__addr.addr, - &__addr.length); - if (retVal == SOCKET_ERROR) spdlog::error("recvfrom()"); - return retVal; -} - -int UDPSocket::sendto(const void* __buf, size_t __n, int __flags, - struct Address __addr) { - std::lock_guard lock(writeMutex); - int retVal = - ::sendto(sock, (char*)__buf, __n, __flags, &__addr.addr, __addr.length); - if (retVal == SOCKET_ERROR) spdlog::error("sendto()"); - return retVal; -} - -UDPSocket::UDPSocket(const UDPSocket& other_) { - memcpy(this, &other_, sizeof(UDPSocket)); - valid_ = false; -} - -UDPSocket::UDPSocket(UDPSocket&& other_) noexcept { - other_.valid_ = false; - memcpy(this, &other_, sizeof(UDPSocket)); - valid_ = true; -} - -UDPSocket& UDPSocket::operator=(const UDPSocket& other_) { - memcpy(this, &other_, sizeof(UDPSocket)); - valid_ = false; - - return *this; -} - -UDPSocket& UDPSocket::operator=(UDPSocket&& other_) noexcept { - other_.valid_ = false; - memcpy(this, &other_, sizeof(UDPSocket)); - valid_ = true; - - return *this; -} - -} // namespace Socket +} // namespace Network diff --git a/impl/socket/wsa_manager.cpp b/impl/socket/wsa_manager.cpp index 2291cff..9a4468d 100644 --- a/impl/socket/wsa_manager.cpp +++ b/impl/socket/wsa_manager.cpp @@ -1,6 +1,6 @@ #include "socket/wsa_manager.h" -namespace Socket { +namespace Network { WSAManager::WSAManager() { #ifdef _WIN32 WSADATA wsa; diff --git a/impl/transport/transport.cpp b/impl/transport/transport.cpp index 7d18b3b..05178c2 100644 --- a/impl/transport/transport.cpp +++ b/impl/transport/transport.cpp @@ -1,10 +1,10 @@ #include "transport/transport.h" -namespace happytanuki { +namespace Network { Transport::Transport(utils::ThreadPool* tp) { tp_ = tp; } void Transport::Send() {} void Transport::Recv() {} -} // namespace happytanuki +} // namespace Network diff --git a/include/precomp.h b/include/precomp.h index 2e82590..24a0f22 100644 --- a/include/precomp.h +++ b/include/precomp.h @@ -1,4 +1,6 @@ #pragma once + +#include #include #include #include @@ -6,32 +8,31 @@ #include #include #include +#include #include #include #include -#include -#include #include "spdlog/spdlog.h" -#include "utilities.h" #ifdef _WIN32 #define NOMINMAX #include -#include #include #include +#include #include #define in_addr_t ULONG #elif __linux__ -#include -#include -#include #include -#include #include +#include #include +#include #include +#include +#include +#include #define SOCKET int #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 @@ -40,3 +41,13 @@ #endif #define MAX_BUFFERED_FRAMES (2) + +#ifdef _WIN32 +int close(int sock); +#elif __linux__ + +#else +#error "이 플랫폼은 지원되지 않습니다." +#endif + +enum class SessionProtocol { UDP, TCP, TLS, QUIC }; diff --git a/include/session/session.h b/include/session/session.h index 8bd973b..9ea55b0 100644 --- a/include/session/session.h +++ b/include/session/session.h @@ -7,16 +7,24 @@ #include "socket/iocp.h" #include "utils/thread_pool.h" -namespace happytanuki { +namespace Network { -enum class SessionProtocol { UDP, TCP, TLS, QUIC }; +enum class SessionType { LISTEN, CONNECT }; class Session { public: - Session(utils::ThreadPool* tp, SessionProtocol proto); + Session(gsl::not_null iocp, utils::ThreadPool* tp, + SessionType type, SessionProtocol proto, Network::Address addr); + ~Session(); private: - Socket::IOCP iocp_; - utils::ThreadPool* tp_; + gsl::not_null iocp_; + utils::ThreadPool* tp_ = nullptr; + + SessionProtocol proto_; + Network::Socket* sock_ = nullptr; + + SSL_CTX* ssl_ctx_ = nullptr; + SSL* ssl_ = nullptr; }; -} // namespace happytanuki +} // namespace Network diff --git a/include/socket/address.h b/include/socket/address.h index 61c153f..9013b8a 100644 --- a/include/socket/address.h +++ b/include/socket/address.h @@ -1,6 +1,6 @@ #pragma once -namespace Socket { +namespace Network { struct Address { Address(); @@ -14,8 +14,9 @@ struct Address { void setType(int type); operator std::string(); - std::uint16_t getPort(); + std::uint16_t getPort() const; + std::uint32_t family; union { struct sockaddr addr; struct sockaddr_in addr_in; diff --git a/include/socket/iocp.h b/include/socket/iocp.h index 16d6fe2..5872231 100644 --- a/include/socket/iocp.h +++ b/include/socket/iocp.h @@ -1,11 +1,15 @@ #pragma once +#include +#include +#include + #include #include #include -#include "socket/tcp_socket.h" -#include "socket/wsa_manager.h" +#include "socket.h" #include "utils/thread_pool.h" +#include "wsa_manager.h" #ifdef __linux__ @@ -20,7 +24,7 @@ typedef struct __WSABUF { #endif -namespace Socket { +namespace Network { class IOCP; @@ -29,9 +33,8 @@ enum class IOCPEVENT { QUIT, READ, WRITE }; struct IOCPPASSINDATA { OVERLAPPED overlapped; IOCPEVENT event; - std::shared_ptr socket; - std::uint32_t recvbytes; - std::uint32_t sendbytes; + std::shared_ptr socket; + SSL* ssl; std::uint32_t transferredbytes; WSABUF wsabuf; std::uint32_t bufsize; @@ -44,8 +47,6 @@ struct IOCPPASSINDATA { std::memset(&overlapped, 0, sizeof(overlapped)); event = IOCPEVENT::QUIT; socket = nullptr; - recvbytes = 0; - sendbytes = 0; transferredbytes = 0; this->bufsize = bufsize; IOCPInstance = nullptr; @@ -64,8 +65,6 @@ struct IOCPPASSINDATA { #endif { std::memset(&overlapped, 0, sizeof(overlapped)); - recvbytes = 0; - sendbytes = 0; wsabuf.buf = new char[bufsize]; std::memcpy(wsabuf.buf, other.wsabuf.buf, other.wsabuf.len); } @@ -79,8 +78,6 @@ struct IOCPPASSINDATA { std::memset(&overlapped, 0, sizeof(overlapped)); event = other.event; socket = other.socket; - recvbytes = 0; - sendbytes = 0; transferredbytes = other.transferredbytes; bufsize = other.bufsize; IOCPInstance = other.IOCPInstance; @@ -96,10 +93,53 @@ struct IOCPPASSINDATA { class IOCP { public: + ~IOCP(); + + template + void init(utils::ThreadPool* __IOCPThread, SessionProtocol proto, + std::function + callback, + _args&&... args) { + IOCPThread_ = __IOCPThread; + proto_ = proto; + + if (proto == SessionProtocol::TLS || proto == SessionProtocol::QUIC) { + rbio_ = ::BIO_new(::BIO_s_mem()); + wbio_ = ::BIO_new(::BIO_s_mem()); + } #ifdef _WIN32 - static void iocpWather( - utils::ThreadPool* threadPool, HANDLE completionPort_, - std::function callback) { + completionPort_ = + ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); + if (completionPort_ == NULL) { + spdlog::critical("CreateIoCompletionPort()"); + std::exit(EXIT_FAILURE); + } + int tCount = __IOCPThread->threadCount; + + spdlog::info("Resizing threadpool size to: {}", tCount * 2); + + __IOCPThread->respawnWorker(tCount * 2); + + for (int i = 0; i < tCount; i++) + __IOCPThread->enqueueJob(iocpWatcher_, IOCPThread_, callback, args...); +#endif + } + + void destruct(); + + void registerSocket(IOCPPASSINDATA* data); + + int send(std::vector data); + int recv(IOCPPASSINDATA& data); + + private: +#ifdef _WIN32 + template + void iocpWatcher_( + utils::ThreadPool* IOCPThread, + std::function + callback, + _args&&... args) { IOCPPASSINDATA* data; SOCKET sock; DWORD cbTransfrred; @@ -111,266 +151,74 @@ class IOCP { spdlog::debug("Disconnected. [{}]", (std::string)(data->socket->remoteAddr)); } else { + if (data->event == IOCPEVENT::READ && + (proto_ == SessionProtocol::TLS || proto_ == SessionProtocol::QUIC)) { + ::BIO_write(rbio_, data->wsabuf.buf, cbTransfrred); + ::SSL_read_ex(data->ssl, data->wsabuf.buf, data->bufsize); + } data->transferredbytes = cbTransfrred; } - threadPool->enqueueJob(callback, data); - threadPool->enqueueJob(iocpWather, completionPort_, callback); + + IOCPThread->enqueueJob(callback, IOCPThread, data, args...); + IOCPThread->enqueueJob(iocpWatcher_, callback, args...); }; #elif __linux__ - static void socketReader( - ThreadPool* threadPool, epoll_event event, int epollfd, - std::function callback) { - pthread_t tid = pthread_self(); - if (event.data.ptr == nullptr) { - spdlog::error("invalid call on {}", tid); - return; - } - - IOCPPASSINDATA* rootIocpData = (IOCPPASSINDATA*)event.data.ptr; - - std::lock_guard lock(rootIocpData->socket->readMutex); - while (true) { - char peekBuffer[1]; - int rc = rootIocpData->socket->recv(peekBuffer, 1, MSG_PEEK); - if (rc > 0) - ; - else if (rc == 0) { - rootIocpData->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(rootIocpData->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, rootIocpData->socket->sock, NULL); - threadPool->enqueueJob(callback, rootIocpData); - // delete rootIocpData; - return; - } else { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - spdlog::trace("No data to read on {}", tid); - return; - } else { - rootIocpData->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(rootIocpData->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, rootIocpData->socket->sock, NULL); - threadPool->enqueueJob(callback, rootIocpData); - // delete rootIocpData; - return; - } - } - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA(*rootIocpData); - ptr->wsabuf.len = 1500; - - int redSize = 0; - int headerSize = 8; - int totalRedSize = 0; - - while (totalRedSize < headerSize) { - redSize = ptr->socket->recv(ptr->buf + totalRedSize, - headerSize - totalRedSize, 0); - - if (redSize == SOCKET_ERROR) { - ptr->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(ptr->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - threadPool->enqueueJob(callback, ptr); - // delete ptr; - return; - } else if (redSize == 0) { - ptr->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(ptr->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - threadPool->enqueueJob(callback, ptr); - // delete ptr; - return; - } - totalRedSize += redSize; - } - - Packet packet; - ::memcpy(packet.serialized, ptr->buf, headerSize); - - redSize = 0; - int dataLength = ntohs(packet.__data.packetLength); - - while (totalRedSize < dataLength + headerSize) { - redSize = ptr->socket->recv(ptr->buf + totalRedSize, - dataLength + headerSize - totalRedSize, 0); - - if (redSize == SOCKET_ERROR) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - spdlog::trace("No data to read on {}", tid); - return; - } - ptr->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(ptr->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - threadPool->enqueueJob(callback, ptr); - // delete ptr; - return; - } else if (redSize == 0) { - ptr->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(ptr->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - threadPool->enqueueJob(callback, ptr); - // delete ptr; - return; - } - totalRedSize += redSize; - } - ptr->transferredbytes = totalRedSize; - threadPool->enqueueJob(callback, ptr); - } - }; - static void socketWriter( - ThreadPool* threadPool, epoll_event event, int epollfd, - std::function callback) { - pthread_t tid = pthread_self(); - - if (event.data.ptr == nullptr) { - spdlog::error("invalid call on {}", tid); - return; - } - - IOCPPASSINDATA* rootIocpData = (IOCPPASSINDATA*)event.data.ptr; - - std::lock_guard lock(rootIocpData->socket->writeMutex); - while (!rootIocpData->sendQueue->empty()) { - IOCPPASSINDATA* data = rootIocpData->sendQueue->front(); - rootIocpData->sendQueue->pop(); - - if (data == nullptr) { - spdlog::error("invalid call on {}", tid); - break; - } - - int packetSize = data->wsabuf.len; - int totalSentSize = 0; - int sentSize = 0; - - spdlog::trace("Sending to: [{}]", (std::string)data->socket->remoteAddr); - - while (totalSentSize < packetSize) { - sentSize = data->socket->send(data->buf + totalSentSize, - packetSize - totalSentSize, 0); - - if (sentSize == SOCKET_ERROR) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - spdlog::warn("buffer full"); - continue; - } - data->event = IOCPEVENT::QUIT; - spdlog::debug("Disconnected. [{}]", - (std::string)(data->socket->remoteAddr)); - ::epoll_ctl(epollfd, EPOLL_CTL_DEL, data->socket->sock, NULL); - threadPool->enqueueJob(callback, data); - // delete data; - return; - } - totalSentSize += sentSize; - } - data->transferredbytes = totalSentSize; - threadPool->enqueueJob(callback, data); - } - }; - static void iocpWatcher( - ThreadPool* threadPool, int epollfd, int epollDetroyerFd, - std::function callback) { - struct epoll_event events[FD_SETSIZE]; - pthread_t tid = pthread_self(); - - int nready = ::epoll_wait(epollfd, events, FD_SETSIZE, -1); - - for (int i = 0; i < nready; i++) { - struct epoll_event current_event = events[i]; - - if (current_event.events & EPOLLIN) { - if (current_event.data.fd == epollDetroyerFd) { - return; - } - std::function task(callback); - threadPool->enqueueJob(socketReader, current_event, epollfd, task); - } else if (current_event.events & EPOLLOUT) { - std::function task(callback); - threadPool->enqueueJob(socketWriter, current_event, epollfd, task); - } - if (--nready <= 0) break; - } - threadPool->enqueueJob(iocpWatcher, epollfd, epollDetroyerFd, callback); - }; #endif - IOCP(); - ~IOCP(); - - template - void init(utils::ThreadPool* __IOCPThread, _Callable&& callback) { - IOCPThread_ = __IOCPThread; + void packet_sender_(utils::ThreadPool* IOCPThread) { #ifdef _WIN32 - completionPort_ = - ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); - if (completionPort_ == NULL) { - spdlog::critical("CreateIoCompletionPort()"); - std::exit(EXIT_FAILURE); - } + std::lock_guard lock(send_queue_mutex_); #elif __linux__ - epollfd_ = ::epoll_create(1); - epollDetroyerFd = ::eventfd(0, EFD_NONBLOCK); - struct epoll_event ev; - ev.events = EPOLLIN; - ev.data.fd = epollDetroyerFd; - ::epoll_ctl(epollfd_, EPOLL_CTL_ADD, epollDetroyerFd, &ev); -#endif - auto boundFunc = [callback = std::move(callback)]( - utils::ThreadPool* __IOCPThread, - IOCPPASSINDATA* data) mutable { - callback(__IOCPThread, data); - }; -#ifdef _WIN32 - int tCount = __IOCPThread->threadCount; - - spdlog::info("Resizing threadpool size to: {}", tCount * 2); - - __IOCPThread->respawnWorker(tCount * 2); - - for (int i = 0; i < tCount; i++) { - std::function task(boundFunc); - __IOCPThread->enqueueJob(iocpWather, completionPort_, task); - } -#elif __linux__ - __IOCPThread->respawnWorker(__IOCPThread->threadCount + 1); - spdlog::info("Spawning 1 Epoll Waiter..."); - __IOCPThread->enqueueJob(iocpWatcher, epollfd_, epollDetroyerFd, boundFunc); #endif } - void destruct(); - - void registerSocket(IOCPPASSINDATA* data); - - int recv(IOCPPASSINDATA* data, int bufferCount); - int send(IOCPPASSINDATA* data, int bufferCount, int __flags); - -#ifdef __linux__ - int epollDetroyerFd = -1; -#endif - - private: struct WSAManager* wsaManager = WSAManager::GetInstance(); utils::ThreadPool* IOCPThread_; + BIO* rbio_ = nullptr; + BIO* wbio_ = nullptr; + + SessionProtocol proto_; + + // 밑의 unordered_map들에 키를 추가/제거 하려는 스레드는 이 뮤텍스를 잡아야 함. + std::mutex socket_mod_mutex_; + + // 각 소켓별 뮤텍스. 다른 스레드가 읽는 중이라면 수신 순서 보장을 위해 다른 + // 스레드는 수신을 포기하고 이전 스레드에 전송을 위임해야 함. (ONESHOT으로 + // 인해 발생하지 않을 것으로 기대되는 행동이기는 하나 보장되지 않을 수 + // 있으므로) 수신 스레드는 epoll이나 iocp를 통해 적당히 수신받아 이 큐를 + // 채워야 함. (항시 socket에 대한 큐에 대해 읽기 시도가 행해질 수 있어야 + // 한다는 뜻임) EPOLLIN에 대해서는 ONESHOT으로 등록해 놓고 읽는 도중에 버퍼에 + // 새 값이 채워질 수 있으므로 읽기가 끝나고 나서 재등록한다 + std::unordered_map recv_queue_mutex_; + // 각 소켓별 패킷, int는 그 vector의 시작 인덱스(vector의 끝까지 다 읽었으면 + // 그 vector는 list에서 삭제되어야 하며, 데이터는 평문으로 변환하여 저장한다) + std::unordered_map, std::uint32_t>>> + recv_queue_; + + // 각 소켓별 뮤텍스. 다른 스레드가 쓰는 중이라면 송신 순서 보장을 위해 다른 + // 스레드는 대기한다. condition variable을 쓰지 않는 이유는 소켓 갯수만큼의 + // 스레드가 대기할 수 없기 때문이며, 송신 등록 시에 적당히 송신 스레드를 + // 스폰해야 함. 이 변수는 항상 송신 스레드에 의해 관리되어야만 하며, + // 윈도우에서는 송신을 iocp가 대행하기 때문에 이 큐가 필요 없는 것처럼 느껴질 + // 수 있으나, 송신 순서를 보장하기 위해 WSASend를 한 스레드가 연속해서 + // 호출해야만 하는데 이는 한번 쓰기 호출 시에 송신 중 데이터를 추가하려는 + // 스레드가 데이터를 추가하고 미전송된 경우를 대비하여 최대 1개까지의 스레드가 + // 대기하도록 한다. 리눅스에서도 send_queue에 데이터를 쌓고 최대 1개까지의 + // 스레드가 대기하도록 한다. + std::unordered_map pending_try_empty_; + std::unordered_map sending_; + std::unordered_map send_queue_mutex_; + std::unordered_map> send_queue_; + #ifdef _WIN32 HANDLE completionPort_ = INVALID_HANDLE_VALUE; #elif __linux__ - int epollfd_ = -1; - std::unordered_map, std::mutex> writeMutex; - std::unordered_map, std::queue> - writeBuffer; + #endif }; -} // namespace Socket +} // namespace Network diff --git a/include/socket/socket.h b/include/socket/socket.h new file mode 100644 index 0000000..049a7f4 --- /dev/null +++ b/include/socket/socket.h @@ -0,0 +1,45 @@ +#pragma once +#include "address.h" + +namespace Network { + +struct Address; + +class Socket { + public: + Socket() = default; + Socket(int domain, int type, int protocol); + ~Socket(); + + int init(int domain, int type, int protocol); + void destruct(); + + operator SOCKET(); + void set(const SOCKET __sock, int __domain); + int setsockopt(int level, int optname, const char* optval, int optlen); + + int bind(Address __addr); + + int recvfrom(void* __restrict __buf, size_t __n, int __flags, + struct Address& __addr); + int sendto(const void* __buf, size_t __n, int __flags, struct Address __addr); + + Socket(const Socket&); + Socket(Socket&&) noexcept; + Socket& operator=(const Socket&); + Socket& operator=(Socket&&) noexcept; + + struct Address bindAddr = {}; + struct Address remoteAddr = {}; + + int domain = 0; + SOCKET sock = INVALID_SOCKET; + + std::mutex readMutex; + std::mutex writeMutex; + + protected: + bool valid_ = false; +}; + +} // namespace Socket diff --git a/include/socket/tcp_socket.h b/include/socket/tcp_socket.h index 8f5f43f..0f3f3ae 100644 --- a/include/socket/tcp_socket.h +++ b/include/socket/tcp_socket.h @@ -1,18 +1,18 @@ #pragma once -#include "udp_socket.h" +#include "socket.h" -namespace Socket { +namespace Network { -class TCPSocket : public UDPSocket { -public: - using UDPSocket::UDPSocket; - using UDPSocket::init; - int init(int domain); - int listen(int __n); - void accept(TCPSocket& newSock, Address& addr); - int connect(Socket::Address& serveraddr); - int recv(void *__restrict __buf, size_t __n, int __flags); - int send(const void *__buf, size_t __n, int __flags); +class TCPSocket : public Socket { + public: + using Socket::init; + using Socket::Socket; + int init(int domain); + int listen(int __n); + void accept(TCPSocket& newSock, Address& addr); + int connect(Network::Address& serveraddr); + int recv(void* __restrict __buf, size_t __n, int __flags); + int send(const void* __buf, size_t __n, int __flags); }; -} +} // namespace Network diff --git a/include/socket/udp_socket.h b/include/socket/udp_socket.h index 2d8c231..28618ba 100644 --- a/include/socket/udp_socket.h +++ b/include/socket/udp_socket.h @@ -1,45 +1,15 @@ #pragma once -#include "address.h" +#include "socket.h" -namespace Socket { +namespace Network { struct Address; -class UDPSocket { +class UDPSocket : public Socket { public: - UDPSocket() = default; - UDPSocket(int domain, int type, int protocol); - ~UDPSocket(); - - int init(int domain, int type, int protocol); - void destruct(); - - operator SOCKET(); - void set(const SOCKET __sock, int __domain); - int setsockopt(int level, int optname, const char* optval, int optlen); - - int bind(Address __addr); - - int recvfrom(void* __restrict __buf, size_t __n, int __flags, - struct Address& __addr); - int sendto(const void* __buf, size_t __n, int __flags, struct Address __addr); - - UDPSocket(const UDPSocket&); - UDPSocket(UDPSocket&&) noexcept; - UDPSocket& operator=(const UDPSocket&); - UDPSocket& operator=(UDPSocket&&) noexcept; - - struct Address bindAddr = {}; - struct Address remoteAddr = {}; - - int domain = 0; - SOCKET sock = INVALID_SOCKET; - - std::mutex readMutex; - std::mutex writeMutex; - - protected: - bool valid_ = false; + using Socket::init; + using Socket::Socket; + int init(int domain); }; } // namespace Socket diff --git a/include/socket/wsa_manager.h b/include/socket/wsa_manager.h index 3256e5e..ebc3a9e 100644 --- a/include/socket/wsa_manager.h +++ b/include/socket/wsa_manager.h @@ -1,6 +1,6 @@ #pragma once -namespace Socket { +namespace Network { struct WSAManager { public: diff --git a/include/transport/transport.h b/include/transport/transport.h index 6698759..cf2b898 100644 --- a/include/transport/transport.h +++ b/include/transport/transport.h @@ -2,7 +2,7 @@ #include "utils/thread_pool.h" -namespace happytanuki { +namespace Network { class Transport { public: @@ -15,4 +15,4 @@ class Transport { utils::ThreadPool* tp_; }; -} // namespace happytanuki +} // namespace Network