ArtifactEngine/Shared/Network/Connection.h
2026-03-11 18:05:19 -04:00

95 lines
2.2 KiB
C++

#pragma once
#include <string>
#include <unordered_map>
#include <ngtcp2/ngtcp2.h>
#include <gnutls/gnutls.h>
#include <ev.h>
// Platform-specific socket includes and helpers
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using socket_t = SOCKET;
#define CLOSE_SOCKET closesocket
#define SOCKLEN_T int
#define IS_INVALID_SOCKET(s) ((s) == INVALID_SOCKET)
#define GET_LAST_ERROR() WSAGetLastError()
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
using socket_t = int;
#define CLOSE_SOCKET close
#define SOCKLEN_T socklen_t
#define IS_INVALID_SOCKET(s) ((s) < 0)
#define GET_LAST_ERROR() errno
#endif
namespace Artifact {
namespace {
struct Ngtcp2CidEqual {
bool operator()(const ngtcp2_cid& a, const ngtcp2_cid& b) const noexcept {
return a.datalen == b.datalen &&
std::memcmp(a.data, b.data, a.datalen) == 0;
}
};
struct Ngtcp2CidHash {
size_t operator()(const ngtcp2_cid& cid) const noexcept {
size_t h = cid.datalen;
for (uint8_t i = 0; i < cid.datalen; ++i) {
h = (h * 31) ^ cid.data[i]; // or better hash as above
}
return h;
}
};
}
class Connection {
public:
ngtcp2_settings settings;
ngtcp2_transport_params transportParams;
ngtcp2_callbacks callbacks;
ngtcp2_cid dcid, scid;
gnutls_session_t session;
ngtcp2_conn * conn;
Connection();
void readPacket(ngtcp2_pkt_info * info, void * packet);
};
class ClientConnection: public Connection {
public:
ClientConnection(std::string host, std::string port);
};
class ServerConnection: public Connection {
public:
ngtcp2_path path;
ServerConnection(ngtcp2_path path);
};
class ServerListener {
socket_t socketDescriptor;
std::unordered_map<ngtcp2_cid, std::unique_ptr<ServerConnection>, Ngtcp2CidHash, Ngtcp2CidEqual> connections;
ngtcp2_addr localAddr;
struct ev_loop * loop;
ev_io watcher;
public:
ServerListener(std::string port);
static void onReadable(struct ev_loop *, ev_io * watcher, int);
void run();
};
}