94 lines
2.7 KiB
C++
94 lines
2.7 KiB
C++
#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) {
|
|
auto sp = std::span(buff.begin(), br);
|
|
logger.debug("From {}: {}", remote, std::span(buff.begin(), br));
|
|
msgpack::unpacker unpacker(sp);
|
|
unpacker.unpack<proto::error_message>()
|
|
.map([](auto msg) { logger.debug("Got error message"); })
|
|
.map_error([](auto err) {
|
|
logger.error("Error getting msg: {}", err);
|
|
});
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|