diff --git a/source/client/client.cpp b/source/client/client.cpp index 26e4a14..2e29472 100644 --- a/source/client/client.cpp +++ b/source/client/client.cpp @@ -94,14 +94,18 @@ awaitable simple_client::connect_to_server() noexcept { net::ip::tcp::socket socket(io_context_); - logger.debug("Attempting connection with {}", results.begin()->endpoint()); - auto [ec2] = co_await socket.async_connect(*results.begin(), no_ex_coro); - if (ec2) { - logger.error("connection to {} failed: {}", results.begin()->endpoint(), - ec2); - co_return; + for (auto const& r : results) { + logger.debug("Connecting to {}", r.endpoint()); + auto [ec] = co_await socket.async_connect(r, no_ex_coro); + if (!ec) { + logger.error("connection to {} failed: {}", + results.begin()->endpoint(), ec); + continue; + } } + logger.error("Unable to connect to any resolved endpoints."); + co_return; } diff --git a/source/server/BUILD b/source/server/BUILD index 87b94d9..2da5832 100644 --- a/source/server/BUILD +++ b/source/server/BUILD @@ -1,5 +1,13 @@ # parselink +cc_library( + name = "headers", + hdrs = [ + "//include/parselink:server.h", + ], + visibility = ["//visibility:public"], +) + cc_library( name = "server", srcs = [ @@ -20,11 +28,37 @@ cc_library( ) cc_library( - name = "headers", - hdrs = [ - "//include/parselink:server.h", + name = "udp_server", + srcs = [ + "udp_server.cpp", + ], + deps = [ + "headers", + "//include/parselink:msgpack", + "//include/parselink:proto", + "//include/parselink:server", + "//include/parselink:utility", + "//source/logging", + "@hydrogen", + "@boost//:asio", + ], + visibility = [ + # TODO: Fix visibility + "//visibility:public", + ], +) + +cc_binary( + name = "udp_parselinkd", + srcs = [ + "main.cpp", + ], + deps = [ + "//source/logging", + "//source/proto", + ":udp_server", + "@boost//:beast", ], - visibility = ["//visibility:public"], ) cc_binary( diff --git a/source/server/udp_server.cpp b/source/server/udp_server.cpp new file mode 100644 index 0000000..da080d1 --- /dev/null +++ b/source/server/udp_server.cpp @@ -0,0 +1,86 @@ +#include "parselink/server.h" + +#include "parselink/logging.h" +#include "parselink/msgpack/core/packer.h" +#include "parselink/msgpack/core/unpacker.h" +#include "parselink/proto/parser.h" +#include "parselink/proto/session.h" +#include "parselink/utility/file.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace parselink; + +using namespace std::chrono_literals; + +namespace net = boost::asio; +using udp = net::ip::udp; + +namespace { +logging::logger logger{"udp.server"}; +constexpr auto no_ex_coro = net::as_tuple(net::use_awaitable); +} // namespace + +class udp_server : public server { +public: + udp_server(std::string_view address, std::uint16_t port) noexcept; + + std::error_code run() noexcept; + +private: + net::awaitable listen() noexcept; + + net::io_context io_context_; + udp::endpoint local_endpoint_; + std::map remotes_; +}; + +udp_server::udp_server(std::string_view address, std::uint16_t port) noexcept + : io_context_{1} + , local_endpoint_{ + net::ip::address::from_string(std::string{address}), port} { + // Load keys, config data from file. + logger.debug("Creating server."); +} + +net::awaitable udp_server::listen() noexcept { + auto exec = co_await net::this_coro::executor; + logger.debug("Binding listener socket to {}.", local_endpoint_); + udp::socket listener{exec, local_endpoint_}; + + while (true) { + udp::endpoint remote; + std::array buff; + auto [ec, br] = co_await listener.async_receive_from( + net::buffer(buff), remote, no_ex_coro); + if (!ec) { + logger.debug("From {}: {}", remote, std::span(buff.begin(), br)); + } + } + + co_return; +} + +std::error_code udp_server::run() noexcept { + co_spawn(io_context_, listen(), net::detached); + + io_context_.run(); + + return {}; +} + +std::unique_ptr parselink::make_server( + std::string_view address, std::uint16_t user_port, std::uint16_t) { + using impl = udp_server; + return std::make_unique(address, user_port); +}