Start tinkering with UDP

This commit is contained in:
Kurt Sassenrath 2024-01-15 22:56:38 -08:00
parent 29d7ad94f1
commit 07698b70b4
3 changed files with 134 additions and 10 deletions

View File

@ -94,14 +94,18 @@ awaitable<void> 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;
}

View File

@ -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(

View File

@ -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 <boost/asio/as_tuple.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/deferred.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/signal_set.hpp>
#include <fmt/ranges.h>
#include <map>
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<void> listen() noexcept;
net::io_context io_context_;
udp::endpoint local_endpoint_;
std::map<udp::endpoint, int> 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<void> 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<std::byte, 4096> 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<server> parselink::make_server(
std::string_view address, std::uint16_t user_port, std::uint16_t) {
using impl = udp_server;
return std::make_unique<impl>(address, user_port);
}