73 lines
1.9 KiB
C++
73 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <sys/socket.h>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <condition_variable>
|
|
#include <event.h>
|
|
|
|
namespace ts::dns {
|
|
class DNSServer;
|
|
class DNSServerBinding {
|
|
friend class DNSServer;
|
|
private:
|
|
struct BindingBuffer {
|
|
BindingBuffer* next{nullptr};
|
|
sockaddr_storage target{};
|
|
size_t size{0};
|
|
};
|
|
|
|
public:
|
|
DNSServer* server{nullptr};
|
|
std::shared_ptr<DNSServerBinding> self{nullptr};
|
|
|
|
sockaddr_storage address{};
|
|
int socket{0};
|
|
std::string error{};
|
|
|
|
inline bool active() const { return this->socket != 0; }
|
|
|
|
std::mutex io_lock{};
|
|
|
|
event* read_event{nullptr};
|
|
event* write_event{nullptr};
|
|
|
|
BindingBuffer* write_buffer_head{nullptr};
|
|
BindingBuffer* write_buffer_tail{nullptr};
|
|
|
|
void send(const sockaddr_storage& /* target */, const void* /* buffer */, size_t /* length */);
|
|
};
|
|
|
|
class DNSHandler;
|
|
class DNSServer {
|
|
public:
|
|
DNSServer(std::shared_ptr<DNSHandler> handler) : handler{std::move(handler)} {};
|
|
virtual ~DNSServer();
|
|
|
|
bool start(const std::vector<sockaddr_storage>& /* bindings */, std::string& /* error */);
|
|
void stop();
|
|
|
|
[[nodiscard]] const std::vector<std::shared_ptr<DNSServerBinding>>& bindings() const { return this->_bindings; }
|
|
private:
|
|
std::shared_ptr<DNSHandler> handler;
|
|
|
|
std::mutex bind_lock{};
|
|
std::vector<std::shared_ptr<DNSServerBinding>> _bindings;
|
|
bool started{false};
|
|
|
|
std::thread event_base_executor{};
|
|
struct event* event_base_ticker{nullptr};
|
|
struct event_base* event_base{nullptr};
|
|
|
|
bool bind(DNSServerBinding& /* binding */, std::string& /* error */);
|
|
void unbind(DNSServerBinding& /* binding */);
|
|
|
|
void event_cb_timer();
|
|
static void event_cb_read(evutil_socket_t fd, short, void *binding);
|
|
static void event_cb_write(evutil_socket_t fd, short, void *binding);
|
|
void event_executor();
|
|
};
|
|
} |