Skip to content

Commit

Permalink
udp2p: basic setup
Browse files Browse the repository at this point in the history
  • Loading branch information
rtgiskard committed Oct 6, 2024
1 parent c7fa5ff commit b7fcb09
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/udp2p/peer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <asio/steady_timer.hpp>

#include "peer.h"

namespace mtrx {
namespace udp2p {

void Peer::run() {
logger_->info("run ..");

// TODO: do_sth()
asio::steady_timer t(ctx_, asio::chrono::seconds(2));
t.async_wait([&](const std::error_code &) { logger_->info("timer done"); });

ctx_.run();
};

uint64_t Peer::connectServer() {
return 0;
};

void Peer::disconnectServer() {};

}; // namespace udp2p
}; // namespace mtrx
54 changes: 54 additions & 0 deletions src/udp2p/peer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef INCLUDE_UDP2P_PEER_H
#define INCLUDE_UDP2P_PEER_H

#include <cstdint>

#include <asio/awaitable.hpp>
#include <asio/io_context.hpp>

#include <spdlog/spdlog.h>

namespace mtrx {
namespace udp2p {

struct PeerInfo {
uint64_t id; // peer id generated by server

int localPort; // local port to send and to accept packets
};

class Peer {
public:
Peer(asio::io_context & ctx) : ctx_(ctx) {
logger_ = spdlog::default_logger()->clone("peer");
};

~Peer(){};

void run();
void stop();

uint64_t connectServer();
void disconnectServer();

bool scanInfo();
bool reportInfo();

bool getPeerInfo();
void connectPeer();
void disconnectPeer();

bool connectPeerByHP(); // hole punching, luky?
bool connectPeerByLocalAddr();
bool connectPeerByRelay();

private:
PeerInfo info;
asio::io_context & ctx_;
std::shared_ptr<spdlog::logger> logger_;
};

}; // namespace udp2p
}; // namespace mtrx

#endif
44 changes: 44 additions & 0 deletions src/udp2p/server.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <string>

#include <asio/detached.hpp>
#include <asio/awaitable.hpp>
#include <asio/use_awaitable.hpp>
#include <asio/co_spawn.hpp>
#include <asio/buffer.hpp>
#include <asio/ip/address.hpp>
#include <asio/ip/udp.hpp>

#include "server.h"
#include "utils/misc.h"

namespace mtrx {
namespace udp2p {

void Server::serv(const std::string & addr, uint port) {
logger_->info("serv ..");

auto endpoint = asio::ip::udp::endpoint(asio::ip::make_address(addr), port);
auto socket = asio::ip::udp::socket(ctx_, endpoint);

asio::co_spawn(
ctx_,
[&socket, this]() -> asio::awaitable<void> {
char buffer[1024];
asio::ip::udp::endpoint remote_endpoint;
while (true) {
size_t n = co_await socket.async_receive_from(
asio::buffer(buffer), remote_endpoint, asio::use_awaitable);

logger_->debug("get: {}", utils::hexFromBytes(buffer, n));

co_await socket.async_send_to(asio::buffer(buffer, n), remote_endpoint,
asio::use_awaitable);
}
},
asio::detached);

ctx_.run();
}

}; // namespace udp2p
}; // namespace mtrx
33 changes: 33 additions & 0 deletions src/udp2p/server.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef INCLUDE_UDP2P_SERVER_H
#define INCLUDE_UDP2P_SERVER_H

#include <asio/io_context.hpp>
#include <spdlog/spdlog.h>

#include "udp2p/manager.h"

namespace mtrx {
namespace udp2p {

class Server {
public:
Server(asio::io_context & ctx) : ctx_(ctx) {
logger_ = spdlog::default_logger()->clone("server");
};

void serv(const std::string & addr, uint port);

private:
asio::io_context & ctx_;
AuthManager authKeeper_;
std::shared_ptr<spdlog::logger> logger_;
};

class Relay {
public:
void serv();
};

}; // namespace udp2p
}; // namespace mtrx
#endif
63 changes: 63 additions & 0 deletions src/udp2p/udp2p.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <cstring>
#include <memory>
#include <thread>

#include <asio/signal_set.hpp>
#include <asio/detail/chrono.hpp>
#include <asio/steady_timer.hpp>

#include "udp2p.h"

namespace mtrx {
namespace udp2p {

void Udp2p::run() {
logger_->info("run mode: {}", static_cast<int>(config_.mode));

switch (config_.mode) {
case Udp2p_Mode::UDP2P_MODE_PEER:
peer_ptr_ = std::make_unique<Peer>(ctx_);
break;
case Udp2p_Mode::UDP2P_MODE_SERVER:
server_ptr_ = std::make_unique<Server>(ctx_);
break;
case Udp2p_Mode::UDP2P_MODE_HYBRID:
peer_ptr_ = std::make_unique<Peer>(ctx_);
server_ptr_ = std::make_unique<Server>(ctx_);
break;
}

// hold sub threads to join at the end
std::vector<std::thread> threads;
if (peer_ptr_)
threads.push_back(std::thread([this]() { peer_ptr_->run(); }));
if (server_ptr_)
threads.push_back(std::thread(
[this]() { server_ptr_->serv(config_.server_addr, config_.server_port); }));

// handle signals
asio::signal_set signals(ctx_, SIGINT, SIGTERM);
signals.async_wait([&](const asio::error_code & ec, int sig_num) {
if (!ec) {
logger_->warn("get signal: {}({})", sig_num, strsignal(sig_num));
stop();
} else
logger_->warn("signal ec: {}, {}", ec.value(), ec.message());
});

// run the event loop
ctx_.run();

// wait sub threads
for (auto & t : threads)
t.join();
}

void Udp2p::stop() {
logger_->info("stop ..");
// notify peer/server via the stop
ctx_.stop();
}

}; // namespace udp2p
}; // namespace mtrx
53 changes: 53 additions & 0 deletions src/udp2p/udp2p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef INCLUDE_UDP2P_UDP2P_H
#define INCLUDE_UDP2P_UDP2P_H

#include <cstdint>
#include <memory>
#include <string>

#include <asio/io_context.hpp>
#include <spdlog/spdlog.h>

#include "udp2p/peer.h"
#include "udp2p/server.h"

namespace mtrx {
namespace udp2p {

enum class Udp2p_Mode {
UDP2P_MODE_PEER, // peer only
UDP2P_MODE_SERVER, // server only
UDP2P_MODE_HYBRID // peer + server
};

class Config {
public:
Udp2p_Mode mode;
std::string server_addr;
int server_port;
uint64_t peer_id; // peer to connect
};

class Udp2p {
public:
Udp2p(Config & config) : config_(config) {
logger_ = spdlog::default_logger()->clone("udp2p");
}

void run();
void stop();

private:
Config & config_;
asio::io_context ctx_;

std::unique_ptr<Server> server_ptr_ = nullptr;
std::unique_ptr<Peer> peer_ptr_ = nullptr;

std::shared_ptr<spdlog::logger> logger_;
};

}; // namespace udp2p
}; // namespace mtrx

#endif

0 comments on commit b7fcb09

Please sign in to comment.