Compare commits

...

1 Commits
main ... server

Author SHA1 Message Date
afe34e252d WIP Server stuff: key gen 2024-01-07 22:51:15 -08:00
5 changed files with 186 additions and 15 deletions

View File

@ -18,13 +18,13 @@
#ifndef message_0c61530748b9f966
#define message_0c61530748b9f966
#include <tl/expected.hpp>
#include <cstdint>
#include <span>
#include <string_view>
#include <variant>
#include <tl/expected.hpp>
namespace parselink {
namespace proto {
@ -44,8 +44,8 @@ struct error_message {
// C->S: Request to (re)connect.
struct connect_message {
std::uint32_t user_id; // The user id.
std::uint32_t version; // The version of the client.
std::uint32_t user_id; // The user id.
std::span<std::byte> session_token; // An optional existing session token.
};

View File

@ -20,14 +20,15 @@
#include "parselink/msgpack/token.h"
#include "parselink/proto/session_id.h"
#include <tl/expected.hpp>
#include <chrono>
#include <cstdint>
#include <functional>
#include <span>
#include <string>
#include <tl/expected.hpp>
template <>
struct std::hash<std::span<std::byte const>> {
constexpr static std::uint32_t seed_var = 0x811c9dc5;

View File

@ -0,0 +1,131 @@
//-----------------------------------------------------------------------------
// ___ __ _ _
// / _ \__ _ _ __ ___ ___ / /(_)_ __ | | __
// / /_)/ _` | '__/ __|/ _ \/ / | | '_ \| |/ /
// / ___/ (_| | | \__ \ __/ /__| | | | | <
// \/ \__,_|_| |___/\___\____/_|_| |_|_|\_\ .
//
//-----------------------------------------------------------------------------
// Author: Kurt Sassenrath
// Module: Utility
//
// Utility wrappers for dealing with files.
//
// Copyright (c) 2023 Kurt Sassenrath.
//
// License TBD.
//-----------------------------------------------------------------------------
#ifndef utility_file_8b49e5e471a7c3e5
#define utility_file_8b49e5e471a7c3e5
#include <fmt/format.h>
#include <tl/expected.hpp>
#include <algorithm>
#include <fcntl.h>
#include <system_error>
#include <unistd.h>
#include <vector>
namespace parselink {
namespace utility {
namespace file {
struct [[nodiscard]] handle {
constexpr handle() noexcept = default;
constexpr handle(int fd) noexcept
: fd_(fd) {
if (fd_ < 0) fd_ = -errno;
}
constexpr handle(handle const&) noexcept = delete;
constexpr handle(handle&& other) noexcept
: fd_(other.fd_) {
other.fd_ = -1;
}
constexpr handle& operator=(handle const&) noexcept = delete;
constexpr handle& operator=(handle&& other) noexcept {
close();
fd_ = other.fd_;
return *this;
}
constexpr operator bool() const noexcept { return fd_ >= 0; }
constexpr int operator*() const noexcept { return fd_; }
void close() {
if (*this) {
::close(fd_);
fd_ = -1;
}
}
int fd_{-1};
};
inline tl::expected<handle, std::error_code> open(
std::string_view path, int flags) noexcept {
handle file(::open(std::string{path}.c_str(), flags));
if (file) {
return file;
} else {
return tl::make_unexpected(
std::make_error_code(static_cast<std::errc>(-*file)));
}
}
inline tl::expected<std::vector<std::byte>, std::error_code> read_some(
handle file, std::size_t amount) noexcept {
std::vector<std::byte> data;
if (!file) {
return tl::make_unexpected(
std::make_error_code(static_cast<std::errc>(-*file)));
}
data.resize(amount);
auto amt_read = ::read(*file, data.data(), amount);
if (amt_read < data.size()) {
data.resize(amt_read);
}
return data;
}
inline tl::expected<std::vector<std::byte>, std::error_code> read(
handle file) noexcept {
std::vector<std::byte> data;
if (!file) {
return tl::make_unexpected(
std::make_error_code(static_cast<std::errc>(-*file)));
}
auto cur = lseek(*file, 0, SEEK_CUR);
auto end = lseek(*file, 0, SEEK_END);
std::size_t amount = end - cur;
lseek(*file, SEEK_SET, cur);
data.resize(amount);
auto amt_read = ::read(*file, data.data(), amount);
if (amt_read < data.size()) {
data.resize(amt_read);
}
return data;
}
} // namespace file
} // namespace utility
} // namespace parselink
#endif // utility_file_8b49e5e471a7c3e5

View File

@ -19,12 +19,13 @@
//-----------------------------------------------------------------------------
#include "parselink/proto/session.h"
#include "hydrogen.h"
#include "parselink/logging.h"
#include "parselink/msgpack/token.h"
#include <fmt/ranges.h>
#include "hydrogen.h"
namespace {
void ensure_initialized() {
@ -187,14 +188,11 @@ tl::expected<connect_info, error> proto::parse_connect(
}
}
session::session(std::string_view user_id, close_handle hdl) noexcept
session::session(std::string_view user_id) noexcept
: id_()
, user_id_(std::string{user_id})
, closer_(std::move(hdl))
, last_activity_(std::chrono::system_clock::now()) {
logger.debug("New session with id {} created for {}", id_.raw(), user_id_);
}
session::~session() {
if (closer_) closer_("Destroyed");
}
session::~session() {}

View File

@ -25,6 +25,11 @@
#include "parselink/msgpack/token/reader.h"
#include "parselink/msgpack/token/views.h"
#include "parselink/proto/session.h"
#include "parselink/utility/file.h"
#include <fmt/ranges.h>
#include "hydrogen.h"
#include <boost/asio/as_tuple.hpp>
#include <boost/asio/bind_executor.hpp>
#include <boost/asio/co_spawn.hpp>
@ -39,8 +44,6 @@
#include <boost/asio/write.hpp>
#include <unordered_set>
#include <fmt/ranges.h>
using namespace parselink;
#include <fmt/ranges.h>
@ -151,6 +154,7 @@ namespace {
logging::logger logger("server");
constexpr auto no_ex_coro = net::as_tuple(use_awaitable);
constexpr auto no_ex_defer = net::as_tuple(deferred);
} // namespace
#include <parselink/server/memory_session_manager.h>
@ -171,6 +175,9 @@ public:
private:
awaitable<void> user_listen();
tl::expected<tl::monostate, std::error_code> load_keys() noexcept;
hydro_kx_keypair kp_;
net::io_context io_context_;
net::io_context::strand session_strand_;
memory_session_manager session_mgr_;
@ -279,8 +286,6 @@ public:
co_return;
}
session_ = *session;
auto writer = msgpack::writer(msgbuf);
}
enum class state { init, authenticated, active };
@ -298,6 +303,8 @@ monolithic_server::monolithic_server(std::string_view address,
, addr_(net::ip::address::from_string(std::string{address}))
, user_port_{user_port}
, websocket_port_{websocket_port} {
load_keys();
logger.debug("Creating monolithic_server(address = {}, user_port = {}, "
"websocket_port = {})",
address, user_port_, websocket_port_);
@ -329,6 +336,40 @@ std::error_code monolithic_server::run() noexcept {
return {};
}
tl::expected<tl::monostate, std::error_code>
monolithic_server::load_keys() noexcept {
std::string_view filename = "server_kp.keys";
auto load_key =
[this](auto raw) -> tl::expected<tl::monostate, std::error_code> {
if (sizeof(kp_) != raw.size()) {
return tl::make_unexpected(
std::make_error_code(std::errc::bad_message));
}
std::ranges::transform(std::begin(raw),
std::next(std::begin(raw), sizeof(kp_.pk)), std::begin(kp_.pk),
[](auto c) { return std::bit_cast<unsigned char>(c); });
return tl::monostate{};
};
auto generate_keys = [this](auto const& err)
-> tl::expected<tl::monostate, std::error_code> {
logger.warning("Could not load server keys, generating a keypair");
hydro_kx_keygen(&kp_);
std::span<std::byte, sizeof(kp_.pk)> pk(
reinterpret_cast<std::byte*>(kp_.pk), sizeof(kp_.pk));
std::span<std::byte, sizeof(kp_.sk)> sk(
reinterpret_cast<std::byte*>(kp_.sk), sizeof(kp_.pk));
logger.debug("\n\tPK: {}\n\tSK: {}", pk, sk);
return tl::monostate{};
};
return utility::file::open(filename, O_RDWR | O_CREAT)
.and_then(utility::file::read)
.and_then(load_key)
.or_else(generate_keys);
}
net::awaitable<tl::expected<proto::session*, proto::error>>
monolithic_server::create_session(std::shared_ptr<user_connection> const& conn,
proto::connect_info const& info) {