mirror of
https://github.com/matrix-construct/construct
synced 2024-11-12 13:01:07 +01:00
ircd::net::dns: Move resolver into libircd proper.
This commit is contained in:
parent
7e51d5dfca
commit
cfc76f1777
9 changed files with 197 additions and 187 deletions
|
@ -47,6 +47,7 @@ namespace ircd::net
|
|||
#include <ircd/net/socket.h>
|
||||
#include <ircd/net/acceptor.h>
|
||||
#include <ircd/net/acceptor_udp.h>
|
||||
#include <ircd/net/dns_resolver.h>
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
|
|
|
@ -93,6 +93,10 @@ namespace ircd::net::dns::cache
|
|||
{
|
||||
using closure = std::function<bool (const string_view &, const json::object &)>;
|
||||
|
||||
extern conf::item<seconds> min_ttl;
|
||||
extern conf::item<seconds> error_ttl;
|
||||
extern conf::item<seconds> nxdomain_ttl;
|
||||
|
||||
string_view make_type(const mutable_buffer &out, const string_view &);
|
||||
string_view make_type(const mutable_buffer &out, const uint16_t &);
|
||||
|
||||
|
|
127
include/ircd/net/dns_resolver.h
Normal file
127
include/ircd/net/dns_resolver.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
//
|
||||
// This file is not part of the ircd.h precompiled header because it contains
|
||||
// boost::asio assets which we cannot forward declare. It is part of the
|
||||
// ircd/asio.h precompiled header.
|
||||
//
|
||||
|
||||
namespace ircd::net::dns
|
||||
{
|
||||
struct tag;
|
||||
struct resolver extern *resolver_instance;
|
||||
|
||||
using answers = vector_view<const rfc1035::answer>;
|
||||
using answers_callback = std::function<void (std::exception_ptr, const tag &, const answers &)>;
|
||||
|
||||
constexpr const size_t MAX_COUNT {64};
|
||||
|
||||
uint16_t resolver_call(const hostport &, const opts &);
|
||||
void resolver_init(answers_callback);
|
||||
void resolver_fini();
|
||||
}
|
||||
|
||||
struct ircd::net::dns::resolver
|
||||
{
|
||||
using header = rfc1035::header;
|
||||
|
||||
static conf::item<std::string> servers;
|
||||
static conf::item<milliseconds> timeout;
|
||||
static conf::item<milliseconds> send_rate;
|
||||
static conf::item<size_t> send_burst;
|
||||
static conf::item<size_t> retry_max;
|
||||
|
||||
answers_callback callback;
|
||||
std::vector<ip::udp::endpoint> server; // The list of active servers
|
||||
size_t server_next{0}; // Round-robin state to hit servers
|
||||
ctx::dock dock, done;
|
||||
ctx::mutex mutex;
|
||||
std::map<uint16_t, tag> tags; // The active requests
|
||||
steady_point send_last; // Time of last send
|
||||
std::deque<uint16_t> sendq; // Queue of frames for rate-limiting
|
||||
ip::udp::socket ns; // A pollable activity object
|
||||
|
||||
// util
|
||||
void add_server(const ipport &);
|
||||
void add_server(const string_view &);
|
||||
void set_servers(const string_view &list);
|
||||
void set_servers();
|
||||
|
||||
// removal (must have lock)
|
||||
void unqueue(tag &);
|
||||
void remove(tag &);
|
||||
decltype(tags)::iterator remove(tag &, const decltype(tags)::iterator &);
|
||||
void error_one(tag &, const std::exception_ptr &, const bool &remove = true);
|
||||
void error_one(tag &, const std::system_error &, const bool &remove = true);
|
||||
void error_all(const std::error_code &, const bool &remove = true);
|
||||
void cancel_all(const bool &remove = true);
|
||||
|
||||
// reception
|
||||
bool handle_error(const header &, tag &);
|
||||
void handle_reply(const header &, const const_buffer &body, tag &);
|
||||
void handle_reply(const ipport &, const header &, const const_buffer &body);
|
||||
void handle(const ipport &, const mutable_buffer &);
|
||||
void recv_worker();
|
||||
ctx::context recv_context;
|
||||
|
||||
// submission
|
||||
void send_query(const ip::udp::endpoint &, tag &);
|
||||
void queue_query(tag &);
|
||||
void send_query(tag &);
|
||||
void submit(tag &);
|
||||
|
||||
// timeout
|
||||
bool check_timeout(const uint16_t &id, tag &, const steady_point &expired);
|
||||
void check_timeouts(const milliseconds &timeout);
|
||||
void timeout_worker();
|
||||
ctx::context timeout_context;
|
||||
|
||||
// sendq
|
||||
void flush(const uint16_t &);
|
||||
void sendq_work();
|
||||
void sendq_clear();
|
||||
void sendq_worker();
|
||||
ctx::context sendq_context;
|
||||
|
||||
template<class... A> tag &set_tag(A&&...);
|
||||
const_buffer make_query(const mutable_buffer &buf, tag &);
|
||||
uint16_t operator()(const hostport &, const opts &);
|
||||
|
||||
resolver(answers_callback);
|
||||
~resolver() noexcept;
|
||||
};
|
||||
|
||||
struct ircd::net::dns::tag
|
||||
{
|
||||
uint16_t id {0};
|
||||
hostport hp;
|
||||
dns::opts opts; // note: invalid after query sent
|
||||
const_buffer question;
|
||||
steady_point last {steady_point::min()};
|
||||
uint8_t tries {0};
|
||||
uint rcode {0};
|
||||
ipport server;
|
||||
char hostbuf[rfc1035::NAME_BUFSIZE];
|
||||
char qbuf[512];
|
||||
|
||||
tag(const hostport &hp, const dns::opts &opts)
|
||||
:hp{hp}
|
||||
,opts{opts}
|
||||
{
|
||||
this->hp.host = { hostbuf, copy(hostbuf, hp.host) };
|
||||
this->hp.service = {};
|
||||
}
|
||||
|
||||
tag(tag &&) = delete;
|
||||
tag(const tag &) = delete;
|
||||
tag &operator=(tag &&) = delete;
|
||||
tag &operator=(const tag &) = delete;
|
||||
};
|
|
@ -147,6 +147,7 @@ libircd_la_SOURCES += db_port.cc
|
|||
libircd_la_SOURCES += db_env.cc
|
||||
libircd_la_SOURCES += db.cc
|
||||
libircd_la_SOURCES += net.cc
|
||||
libircd_la_SOURCES += net_dns_resolver.cc
|
||||
libircd_la_SOURCES += server.cc
|
||||
libircd_la_SOURCES += client.cc
|
||||
libircd_la_SOURCES += resource.cc
|
||||
|
@ -193,6 +194,7 @@ magic.lo: AM_CPPFLAGS := @MAGIC_CPPFLAGS@ ${AM_CPPFLAGS}
|
|||
endif
|
||||
mods.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||
net.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||
net_dns_resolver.lo: AM_CPPFLAGS := ${ASIO_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||
openssl.lo: AM_CPPFLAGS := @SSL_CPPFLAGS@ @CRYPTO_CPPFLAGS@ ${AM_CPPFLAGS}
|
||||
parse.lo: AM_CPPFLAGS := ${SPIRIT_UNIT_CPPFLAGS} ${AM_CPPFLAGS}
|
||||
parse.lo: AM_CXXFLAGS := ${SPIRIT_UNIT_CXXFLAGS} ${AM_CXXFLAGS}
|
||||
|
|
47
ircd/net.cc
47
ircd/net.cc
|
@ -4201,6 +4201,27 @@ ircd::net::dns::log
|
|||
"net.dns"
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::min_ttl)
|
||||
ircd::net::dns::cache::min_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.min_ttl" },
|
||||
{ "default", 28800L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::error_ttl)
|
||||
ircd::net::dns::cache::error_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.error_ttl" },
|
||||
{ "default", 1200L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::nxdomain_ttl)
|
||||
ircd::net::dns::cache::nxdomain_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.nxdomain_ttl" },
|
||||
{ "default", 86400L },
|
||||
};
|
||||
|
||||
/// Linkage for default opts
|
||||
decltype(ircd::net::dns::opts_default)
|
||||
ircd::net::dns::opts_default;
|
||||
|
@ -4322,28 +4343,16 @@ bool
|
|||
ircd::net::dns::expired(const json::object &rr,
|
||||
const time_t &rr_ts)
|
||||
{
|
||||
static mods::import<conf::item<seconds>> min_ttl
|
||||
const seconds &min_seconds
|
||||
{
|
||||
"net_dns", "ircd::net::dns::cache::min_ttl"
|
||||
cache::min_ttl
|
||||
};
|
||||
|
||||
static mods::import<conf::item<seconds>> error_ttl
|
||||
const seconds &err_seconds
|
||||
{
|
||||
"net_dns", "ircd::net::dns::cache::error_ttl"
|
||||
cache::error_ttl
|
||||
};
|
||||
|
||||
const conf::item<seconds> &min_ttl_item
|
||||
{
|
||||
static_cast<conf::item<seconds> &>(min_ttl)
|
||||
};
|
||||
|
||||
const conf::item<seconds> &error_ttl_item
|
||||
{
|
||||
static_cast<conf::item<seconds> &>(error_ttl)
|
||||
};
|
||||
|
||||
const seconds &min_seconds(min_ttl_item);
|
||||
const seconds &err_seconds(error_ttl_item);
|
||||
const time_t &min
|
||||
{
|
||||
is_error(rr)?
|
||||
|
@ -4359,7 +4368,11 @@ ircd::net::dns::expired(const json::object &rr,
|
|||
const time_t &rr_ts,
|
||||
const time_t &min_ttl)
|
||||
{
|
||||
const auto ttl(get_ttl(rr));
|
||||
const auto &ttl
|
||||
{
|
||||
get_ttl(rr)
|
||||
};
|
||||
|
||||
return rr_ts + std::max(ttl, min_ttl) < ircd::time();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,37 @@
|
|||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#include "net_dns.h"
|
||||
|
||||
decltype(ircd::net::dns::resolver_instance)
|
||||
ircd::net::dns::resolver_instance;
|
||||
|
||||
decltype(ircd::net::dns::resolver::timeout)
|
||||
ircd::net::dns::resolver::timeout
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.timeout" },
|
||||
{ "default", 10000L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::send_rate)
|
||||
ircd::net::dns::resolver::send_rate
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.send_rate" },
|
||||
{ "default", 67L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::send_burst)
|
||||
ircd::net::dns::resolver::send_burst
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.send_burst" },
|
||||
{ "default", 5L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::retry_max)
|
||||
ircd::net::dns::resolver::retry_max
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.retry_max" },
|
||||
{ "default", 4L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::servers)
|
||||
ircd::net::dns::resolver::servers
|
||||
{
|
||||
|
@ -26,34 +52,6 @@ ircd::net::dns::resolver::servers
|
|||
}
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::timeout)
|
||||
ircd::net::dns::resolver::timeout
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.timeout" },
|
||||
{ "default", 10000L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::send_rate)
|
||||
ircd::net::dns::resolver::send_rate
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.send_rate" },
|
||||
{ "default", 60L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::send_burst)
|
||||
ircd::net::dns::resolver::send_burst
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.send_burst" },
|
||||
{ "default", 8L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::resolver::retry_max)
|
||||
ircd::net::dns::resolver::retry_max
|
||||
{
|
||||
{ "name", "ircd.net.dns.resolver.retry_max" },
|
||||
{ "default", 4L },
|
||||
};
|
||||
|
||||
//
|
||||
// interface
|
||||
//
|
||||
|
@ -62,7 +60,6 @@ void
|
|||
ircd::net::dns::resolver_init(answers_callback callback)
|
||||
{
|
||||
assert(!ircd::net::dns::resolver_instance);
|
||||
|
||||
ircd::net::dns::resolver_instance = new resolver
|
||||
{
|
||||
std::move(callback)
|
|
@ -40,11 +40,10 @@ AM_LDFLAGS = \
|
|||
moduledir = @moduledir@
|
||||
|
||||
stats_la_SOURCES = stats.cc
|
||||
net_dns_la_SOURCES = net_dns.cc net_dns_cache.cc net_dns_resolver.cc
|
||||
net_dns_la_SOURCES = net_dns_cache.cc net_dns.cc
|
||||
net_dns_la_CPPFLAGS = -include $(top_srcdir)/include/ircd/asio.h
|
||||
net_dns_la_CPPFLAGS += $(AM_CPPFLAGS) @BOOST_CPPFLAGS@
|
||||
net_dns_la_LDFLAGS = $(AM_LDFLAGS) @BOOST_LDFLAGS@
|
||||
net_dns_la_LIBADD = $(AM_LIBS) @BOOST_LIBS@
|
||||
console_la_SOURCES = console.cc
|
||||
web_root_la_SOURCES = web_root.cc
|
||||
web_hook_la_SOURCES = web_hook.cc
|
||||
|
|
|
@ -10,19 +10,6 @@
|
|||
|
||||
#include <ircd/asio.h>
|
||||
|
||||
extern ircd::mapi::header
|
||||
IRCD_MODULE;
|
||||
|
||||
namespace ircd::net::dns
|
||||
{
|
||||
struct tag;
|
||||
|
||||
using answers = vector_view<const rfc1035::answer>;
|
||||
using answers_callback = std::function<void (std::exception_ptr, const tag &, const answers &)>;
|
||||
|
||||
constexpr const size_t MAX_COUNT {64};
|
||||
}
|
||||
|
||||
namespace ircd::net::dns::cache
|
||||
{
|
||||
struct waiter;
|
||||
|
@ -40,10 +27,6 @@ namespace ircd::net::dns::cache
|
|||
void fini();
|
||||
void init();
|
||||
|
||||
extern conf::item<seconds> min_ttl IRCD_MODULE_EXPORT_DATA;
|
||||
extern conf::item<seconds> error_ttl IRCD_MODULE_EXPORT_DATA;
|
||||
extern conf::item<seconds> nxdomain_ttl IRCD_MODULE_EXPORT_DATA;
|
||||
|
||||
extern const m::room::id::buf room_id;
|
||||
extern m::hookfn<m::vm::eval &> hook;
|
||||
extern std::list<waiter> waiting;
|
||||
|
@ -65,114 +48,3 @@ struct ircd::net::dns::cache::waiter
|
|||
waiter &operator=(waiter &&) = delete;
|
||||
waiter &operator=(const waiter &) = delete;
|
||||
};
|
||||
|
||||
//
|
||||
// s_dns_resolver.cc
|
||||
//
|
||||
|
||||
namespace ircd::net::dns
|
||||
{
|
||||
// Resolver instance
|
||||
struct resolver extern *resolver_instance;
|
||||
|
||||
uint16_t resolver_call(const hostport &, const opts &);
|
||||
void resolver_init(answers_callback);
|
||||
void resolver_fini();
|
||||
}
|
||||
|
||||
struct ircd::net::dns::resolver
|
||||
{
|
||||
using header = rfc1035::header;
|
||||
|
||||
static conf::item<std::string> servers;
|
||||
static conf::item<milliseconds> timeout;
|
||||
static conf::item<milliseconds> send_rate;
|
||||
static conf::item<size_t> send_burst;
|
||||
static conf::item<size_t> retry_max;
|
||||
|
||||
answers_callback callback;
|
||||
std::vector<ip::udp::endpoint> server; // The list of active servers
|
||||
size_t server_next{0}; // Round-robin state to hit servers
|
||||
ctx::dock dock, done;
|
||||
ctx::mutex mutex;
|
||||
std::map<uint16_t, tag> tags; // The active requests
|
||||
steady_point send_last; // Time of last send
|
||||
std::deque<uint16_t> sendq; // Queue of frames for rate-limiting
|
||||
ip::udp::socket ns; // A pollable activity object
|
||||
|
||||
// util
|
||||
void add_server(const ipport &);
|
||||
void add_server(const string_view &);
|
||||
void set_servers(const string_view &list);
|
||||
void set_servers();
|
||||
|
||||
// removal (must have lock)
|
||||
void unqueue(tag &);
|
||||
void remove(tag &);
|
||||
decltype(tags)::iterator remove(tag &, const decltype(tags)::iterator &);
|
||||
void error_one(tag &, const std::exception_ptr &, const bool &remove = true);
|
||||
void error_one(tag &, const std::system_error &, const bool &remove = true);
|
||||
void error_all(const std::error_code &, const bool &remove = true);
|
||||
void cancel_all(const bool &remove = true);
|
||||
|
||||
// reception
|
||||
bool handle_error(const header &, tag &);
|
||||
void handle_reply(const header &, const const_buffer &body, tag &);
|
||||
void handle_reply(const ipport &, const header &, const const_buffer &body);
|
||||
void handle(const ipport &, const mutable_buffer &);
|
||||
void recv_worker();
|
||||
ctx::context recv_context;
|
||||
|
||||
// submission
|
||||
void send_query(const ip::udp::endpoint &, tag &);
|
||||
void queue_query(tag &);
|
||||
void send_query(tag &);
|
||||
void submit(tag &);
|
||||
|
||||
// timeout
|
||||
bool check_timeout(const uint16_t &id, tag &, const steady_point &expired);
|
||||
void check_timeouts(const milliseconds &timeout);
|
||||
void timeout_worker();
|
||||
ctx::context timeout_context;
|
||||
|
||||
// sendq
|
||||
void flush(const uint16_t &);
|
||||
void sendq_work();
|
||||
void sendq_clear();
|
||||
void sendq_worker();
|
||||
ctx::context sendq_context;
|
||||
|
||||
template<class... A> tag &set_tag(A&&...);
|
||||
const_buffer make_query(const mutable_buffer &buf, tag &);
|
||||
uint16_t operator()(const hostport &, const opts &);
|
||||
|
||||
resolver(answers_callback);
|
||||
~resolver() noexcept;
|
||||
};
|
||||
|
||||
struct ircd::net::dns::tag
|
||||
{
|
||||
uint16_t id {0};
|
||||
hostport hp;
|
||||
dns::opts opts; // note: invalid after query sent
|
||||
const_buffer question;
|
||||
steady_point last {steady_point::min()};
|
||||
uint8_t tries {0};
|
||||
uint rcode {0};
|
||||
ipport server;
|
||||
char hostbuf[rfc1035::NAME_BUFSIZE];
|
||||
char qbuf[512];
|
||||
|
||||
tag(const hostport &hp, const dns::opts &opts)
|
||||
:hp{hp}
|
||||
,opts{opts}
|
||||
{
|
||||
this->hp.host = { hostbuf, copy(hostbuf, hp.host) };
|
||||
this->hp.service = {};
|
||||
}
|
||||
|
||||
tag(tag &&) = delete;
|
||||
tag(const tag &) = delete;
|
||||
tag &operator=(tag &&) = delete;
|
||||
tag &operator=(const tag &) = delete;
|
||||
};
|
||||
|
|
|
@ -10,27 +10,6 @@
|
|||
|
||||
#include "net_dns.h"
|
||||
|
||||
decltype(ircd::net::dns::cache::error_ttl)
|
||||
ircd::net::dns::cache::error_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.error_ttl" },
|
||||
{ "default", 1200L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::nxdomain_ttl)
|
||||
ircd::net::dns::cache::nxdomain_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.nxdomain_ttl" },
|
||||
{ "default", 86400L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::min_ttl)
|
||||
ircd::net::dns::cache::min_ttl
|
||||
{
|
||||
{ "name", "ircd.net.dns.cache.min_ttl" },
|
||||
{ "default", 28800L },
|
||||
};
|
||||
|
||||
decltype(ircd::net::dns::cache::room_id)
|
||||
ircd::net::dns::cache::room_id
|
||||
{
|
||||
|
@ -172,7 +151,15 @@ try
|
|||
rr0.~object();
|
||||
array.~array();
|
||||
content.~object();
|
||||
send(room_id, m::me(), type, state_key, json::object(out.completed()));
|
||||
const m::room room
|
||||
{
|
||||
room_id
|
||||
};
|
||||
|
||||
if(unlikely(!exists(room)))
|
||||
create(room);
|
||||
|
||||
send(room, m::me(), type, state_key, json::object(out.completed()));
|
||||
return true;
|
||||
}
|
||||
catch(const http::error &e)
|
||||
|
@ -297,6 +284,14 @@ try
|
|||
|
||||
array.~array();
|
||||
content.~object();
|
||||
const m::room room
|
||||
{
|
||||
room_id
|
||||
};
|
||||
|
||||
if(unlikely(!exists(room)))
|
||||
create(room);
|
||||
|
||||
send(room_id, m::me(), type, state_key, json::object{out.completed()});
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue