diff --git a/repertory/librepertory/src/rpc/server/server.cpp b/repertory/librepertory/src/rpc/server/server.cpp index f69bf963..694c80a3 100644 --- a/repertory/librepertory/src/rpc/server/server.cpp +++ b/repertory/librepertory/src/rpc/server/server.cpp @@ -143,9 +143,15 @@ void server::start() { initialize(*server_); - fmt::println("port|{}", config_.get_api_port()); server_thread_ = std::make_unique([this]() { - server_->set_socket_options([](auto && /* sock */) {}); +#ifdef _WIN32 + server_->set_socket_options([](auto &&sock) { + int enable = 1; + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + reinterpret_cast(&enable), sizeof(enable)); + }); +#endif // _WIN32 + server_->listen("127.0.0.1", config_.get_api_port()); }); event_system::instance().raise(function_name, "server"); diff --git a/repertory/repertory/include/cli/mount.hpp b/repertory/repertory/include/cli/mount.hpp index d1c5c8ce..5a12873e 100644 --- a/repertory/repertory/include/cli/mount.hpp +++ b/repertory/repertory/include/cli/mount.hpp @@ -112,7 +112,6 @@ mount(std::vector args, std::string data_directory, std::cerr << "FATAL: Unable to get available port" << std::endl; return exit_code::startup_exception; } - fmt::println("port|{}", port); config.set_api_port(port); } @@ -147,13 +146,6 @@ mount(std::vector args, std::string data_directory, << " Drive" << std::endl; if (prov == provider_type::remote) { try { - std::uint16_t port{}; - if (not utils::get_next_available_port( - config.get_remote_config().api_port, port)) { - std::cerr << "FATAL: Unable to get available port" << std::endl; - return exit_code::startup_exception; - } - auto remote_cfg = config.get_remote_config(); remote_cfg.host_name_or_ip = remote_host; remote_cfg.api_port = remote_port; diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index acc32c03..a39b1a3a 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -109,7 +109,13 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) server_(server) { REPERTORY_USES_FUNCTION_NAME(); - server->set_socket_options([](auto && /* sock */) {}); +#ifdef _WIN32 + server_->set_socket_options([](auto &&sock) { + int enable = 1; + setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, + reinterpret_cast(&enable), sizeof(enable)); + }); +#endif // _WIN32 server_->set_pre_routing_handler( [this](const httplib::Request &req, diff --git a/support/src/utils/common.cpp b/support/src/utils/common.cpp index 92382f6f..f086f796 100644 --- a/support/src/utils/common.cpp +++ b/support/src/utils/common.cpp @@ -25,8 +25,8 @@ #include "utils/string.hpp" namespace repertory::utils { -auto compare_version_strings(std::string version1, - std::string version2) -> std::int32_t { +auto compare_version_strings(std::string version1, std::string version2) + -> std::int32_t { if (utils::string::contains(version1, "-")) { version1 = utils::string::split(version1, '-', true)[0U]; @@ -131,23 +131,46 @@ auto get_next_available_port(std::uint16_t first_port, using ip::tcp; boost::system::error_code error_code{}; - while (first_port != 0U) { - io_context ctx{}; - tcp::acceptor acceptor(ctx); - acceptor.open(tcp::v4(), error_code) || - acceptor.bind({tcp::v4(), first_port}, error_code); - if (not error_code) { - break; + + std::uint32_t check_port{first_port}; + while (check_port <= 65535U) { + { + io_context ctx{}; + tcp::socket socket(ctx); + socket.connect( + { + tcp::endpoint(ip::address_v4::loopback(), + static_cast(check_port)), + }, + error_code); + if (not error_code) { + ++check_port; + continue; + } } - ++first_port; + { + io_context ctx{}; + tcp::acceptor acceptor(ctx); + acceptor.open(tcp::v4(), error_code); + if (error_code) { + ++check_port; + continue; + } + + acceptor.bind({tcp::v4(), static_cast(check_port)}, + error_code); + if (error_code) { + ++check_port; + continue; + } + } + + available_port = static_cast(check_port); + return true; } - if (not error_code) { - available_port = first_port; - } - - return not error_code; + return false; } #endif // defined(PROJECT_ENABLE_BOOST)