95 lines
2.2 KiB
C++
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();
|
|
};
|
|
|
|
}
|