mirror of
https://github.com/matrix-construct/construct
synced 2024-09-28 11:48:54 +02:00
ircd::net::dns: Add explicit qtype to opts and integrate w/ query stack.
This commit is contained in:
parent
58c7a4885b
commit
95c6f69e5d
6 changed files with 94 additions and 40 deletions
|
@ -48,6 +48,13 @@ namespace ircd::net::dns
|
||||||
/// DNS resolution options
|
/// DNS resolution options
|
||||||
struct ircd::net::dns::opts
|
struct ircd::net::dns::opts
|
||||||
{
|
{
|
||||||
|
/// Specifies the rfc1035 query type. If this is non-zero a query of this
|
||||||
|
/// type will be made or an exception will be thrown if it is not possible
|
||||||
|
/// to make the query with this type. A zero value means automatic and the
|
||||||
|
/// type will deduced and set internally. To translate a string type like
|
||||||
|
/// "SRV" to the type integer for this value see ircd/rfc1035.h.
|
||||||
|
uint16_t qtype {0};
|
||||||
|
|
||||||
/// Overrides the SRV query to make for this resolution. If empty an
|
/// Overrides the SRV query to make for this resolution. If empty an
|
||||||
/// SRV query may still be made from other deductions. This string is
|
/// SRV query may still be made from other deductions. This string is
|
||||||
/// copied at the start of the resolution. It must be a fully qualified
|
/// copied at the start of the resolution. It must be a fully qualified
|
||||||
|
|
|
@ -73,11 +73,7 @@ ircd::net::dns::_resolve_ipport(const hostport &hp,
|
||||||
hp.port = record.port;
|
hp.port = record.port;
|
||||||
|
|
||||||
hp.host = record.tgt?: unmake_SRV_key(hp.host);
|
hp.host = record.tgt?: unmake_SRV_key(hp.host);
|
||||||
|
opts.qtype = 0;
|
||||||
// Have to kill the service name to not run another SRV query now.
|
|
||||||
hp.service = {};
|
|
||||||
opts.srv = {};
|
|
||||||
opts.proto = {};
|
|
||||||
|
|
||||||
_resolve__A(hp, opts, [calluser(std::move(calluser))]
|
_resolve__A(hp, opts, [calluser(std::move(calluser))]
|
||||||
(std::exception_ptr eptr, const hostport &hp, const rfc1035::record::A &record)
|
(std::exception_ptr eptr, const hostport &hp, const rfc1035::record::A &record)
|
||||||
|
@ -91,9 +87,25 @@ ircd::net::dns::_resolve_ipport(const hostport &hp,
|
||||||
/// the vector with stochastic respect for weighting and priority.
|
/// the vector with stochastic respect for weighting and priority.
|
||||||
void
|
void
|
||||||
ircd::net::dns::_resolve__SRV(const hostport &hp,
|
ircd::net::dns::_resolve__SRV(const hostport &hp,
|
||||||
const opts &opts,
|
opts opts,
|
||||||
callback_SRV_one callback)
|
callback_SRV_one callback)
|
||||||
{
|
{
|
||||||
|
static const auto &qtype
|
||||||
|
{
|
||||||
|
rfc1035::qtype.at("SRV")
|
||||||
|
};
|
||||||
|
|
||||||
|
if(unlikely(opts.qtype && opts.qtype != qtype))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"Specified query type '%s' (%u) but user's callback is for SRV records only.",
|
||||||
|
rfc1035::rqtype.at(opts.qtype),
|
||||||
|
opts.qtype
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!opts.qtype)
|
||||||
|
opts.qtype = qtype;
|
||||||
|
|
||||||
_resolve__(hp, opts, [callback(std::move(callback))]
|
_resolve__(hp, opts, [callback(std::move(callback))]
|
||||||
(std::exception_ptr eptr, const hostport &hp, const vector_view<const rfc1035::record *> rrs)
|
(std::exception_ptr eptr, const hostport &hp, const vector_view<const rfc1035::record *> rrs)
|
||||||
{
|
{
|
||||||
|
@ -121,9 +133,25 @@ ircd::net::dns::_resolve__SRV(const hostport &hp,
|
||||||
/// the vector randomly.
|
/// the vector randomly.
|
||||||
void
|
void
|
||||||
ircd::net::dns::_resolve__A(const hostport &hp,
|
ircd::net::dns::_resolve__A(const hostport &hp,
|
||||||
const opts &opts,
|
opts opts,
|
||||||
callback_A_one callback)
|
callback_A_one callback)
|
||||||
{
|
{
|
||||||
|
static const auto &qtype
|
||||||
|
{
|
||||||
|
rfc1035::qtype.at("A")
|
||||||
|
};
|
||||||
|
|
||||||
|
if(unlikely(opts.qtype && opts.qtype != qtype))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"Specified query type '%s' (%u) but user's callback is for A records only.",
|
||||||
|
rfc1035::rqtype.at(opts.qtype),
|
||||||
|
opts.qtype
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!opts.qtype)
|
||||||
|
opts.qtype = qtype;
|
||||||
|
|
||||||
_resolve__(hp, opts, [callback(std::move(callback))]
|
_resolve__(hp, opts, [callback(std::move(callback))]
|
||||||
(std::exception_ptr eptr, const hostport &hp, const vector_view<const rfc1035::record *> &rrs)
|
(std::exception_ptr eptr, const hostport &hp, const vector_view<const rfc1035::record *> &rrs)
|
||||||
{
|
{
|
||||||
|
@ -150,12 +178,18 @@ ircd::net::dns::_resolve__A(const hostport &hp,
|
||||||
/// Fundamental callback with a vector of abstract resource records.
|
/// Fundamental callback with a vector of abstract resource records.
|
||||||
void
|
void
|
||||||
ircd::net::dns::_resolve__(const hostport &hp,
|
ircd::net::dns::_resolve__(const hostport &hp,
|
||||||
const opts &op,
|
const opts &opts,
|
||||||
callback cb)
|
callback cb)
|
||||||
{
|
{
|
||||||
if(op.cache_check)
|
if(unlikely(!opts.qtype))
|
||||||
if(cache::get(hp, op, cb))
|
throw error
|
||||||
|
{
|
||||||
|
"A query type is required; not specified; cannot be deduced here."
|
||||||
|
};
|
||||||
|
|
||||||
|
if(opts.cache_check)
|
||||||
|
if(cache::get(hp, opts, cb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
resolver_call(hp, op, std::move(cb));
|
resolver_call(hp, opts, std::move(cb));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ namespace ircd::net::dns
|
||||||
constexpr const size_t MAX_COUNT {64};
|
constexpr const size_t MAX_COUNT {64};
|
||||||
|
|
||||||
extern "C" void _resolve__(const hostport &, const opts &, callback);
|
extern "C" void _resolve__(const hostport &, const opts &, callback);
|
||||||
extern "C" void _resolve__A(const hostport &, const opts &, callback_A_one);
|
extern "C" void _resolve__A(const hostport &, opts, callback_A_one);
|
||||||
extern "C" void _resolve__SRV(const hostport &, const opts &, callback_SRV_one);
|
extern "C" void _resolve__SRV(const hostport &, opts, callback_SRV_one);
|
||||||
extern "C" void _resolve_ipport(const hostport &, const opts &, callback_ipport_one);
|
extern "C" void _resolve_ipport(const hostport &, const opts &, callback_ipport_one);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,7 @@ ircd::net::dns::cache::_get(const hostport &hp,
|
||||||
std::exception_ptr eptr;
|
std::exception_ptr eptr;
|
||||||
size_t count{0};
|
size_t count{0};
|
||||||
|
|
||||||
//TODO: Better deduction
|
if(opts.qtype == 33) // deduced SRV query
|
||||||
if(hp.service || opts.srv) // deduced SRV query
|
|
||||||
{
|
{
|
||||||
assert(!empty(host(hp)));
|
assert(!empty(host(hp)));
|
||||||
thread_local char srvbuf[512];
|
thread_local char srvbuf[512];
|
||||||
|
@ -224,7 +223,7 @@ ircd::net::dns::cache::_get(const hostport &hp,
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Deduced A query (for now)
|
else if(opts.qtype == 1)
|
||||||
{
|
{
|
||||||
auto &map{cache_A};
|
auto &map{cache_A};
|
||||||
const auto &key{rstrip(host(hp), '.')};
|
const auto &key{rstrip(host(hp), '.')};
|
||||||
|
|
|
@ -60,20 +60,6 @@ ircd::net::dns::resolver::retry_max
|
||||||
// interface
|
// interface
|
||||||
//
|
//
|
||||||
|
|
||||||
void
|
|
||||||
ircd::net::dns::resolver_call(const hostport &hp,
|
|
||||||
const opts &opts,
|
|
||||||
callback &&cb)
|
|
||||||
{
|
|
||||||
if(unlikely(!resolver))
|
|
||||||
throw error
|
|
||||||
{
|
|
||||||
"Cannot resolve '%s': resolver unavailable"
|
|
||||||
};
|
|
||||||
|
|
||||||
(*resolver)(hp, opts, std::move(cb));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::net::dns::resolver_init()
|
ircd::net::dns::resolver_init()
|
||||||
{
|
{
|
||||||
|
@ -88,6 +74,20 @@ ircd::net::dns::resolver_fini()
|
||||||
ircd::net::dns::resolver = nullptr;
|
ircd::net::dns::resolver = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ircd::net::dns::resolver_call(const hostport &hp,
|
||||||
|
const opts &opts,
|
||||||
|
callback &&cb)
|
||||||
|
{
|
||||||
|
if(unlikely(!resolver))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"Cannot resolve '%s': resolver unavailable"
|
||||||
|
};
|
||||||
|
|
||||||
|
(*resolver)(hp, opts, std::move(cb));
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// resolver::resolver
|
// resolver::resolver
|
||||||
//
|
//
|
||||||
|
@ -291,22 +291,34 @@ ircd::net::dns::resolver::operator()(const hostport &hp,
|
||||||
ircd::const_buffer
|
ircd::const_buffer
|
||||||
ircd::net::dns::resolver::make_query(const mutable_buffer &buf,
|
ircd::net::dns::resolver::make_query(const mutable_buffer &buf,
|
||||||
const tag &tag)
|
const tag &tag)
|
||||||
const
|
|
||||||
{
|
{
|
||||||
//TODO: Better deduction
|
thread_local char hostbuf[512];
|
||||||
if(tag.hp.service || tag.opts.srv)
|
string_view hoststr;
|
||||||
|
switch(tag.opts.qtype)
|
||||||
{
|
{
|
||||||
thread_local char srvbuf[512];
|
case 0: throw error
|
||||||
const string_view srvhost
|
|
||||||
{
|
{
|
||||||
make_SRV_key(srvbuf, host(tag.hp), tag.opts)
|
"A query type is required to form a question."
|
||||||
};
|
};
|
||||||
|
|
||||||
const rfc1035::question question{srvhost, "SRV"};
|
case 33: // SRV
|
||||||
return rfc1035::make_query(buf, tag.id, question);
|
{
|
||||||
|
hoststr = make_SRV_key(hostbuf, host(tag.hp), tag.opts);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
hoststr = host(tag.hp);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rfc1035::question question{host(tag.hp), "A"};
|
assert(hoststr);
|
||||||
|
assert(tag.opts.qtype);
|
||||||
|
const rfc1035::question question
|
||||||
|
{
|
||||||
|
hoststr, tag.opts.qtype
|
||||||
|
};
|
||||||
|
|
||||||
return rfc1035::make_query(buf, tag.id, question);
|
return rfc1035::make_query(buf, tag.id, question);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct ircd::net::dns::resolver
|
||||||
void submit(tag &);
|
void submit(tag &);
|
||||||
|
|
||||||
template<class... A> tag &set_tag(A&&...);
|
template<class... A> tag &set_tag(A&&...);
|
||||||
const_buffer make_query(const mutable_buffer &buf, const tag &) const;
|
static const_buffer make_query(const mutable_buffer &buf, const tag &);
|
||||||
void operator()(const hostport &, const opts &, callback &&);
|
void operator()(const hostport &, const opts &, callback &&);
|
||||||
|
|
||||||
bool check_timeout(const uint16_t &id, tag &, const steady_point &expired);
|
bool check_timeout(const uint16_t &id, tag &, const steady_point &expired);
|
||||||
|
@ -75,6 +75,8 @@ struct ircd::net::dns::resolver::tag
|
||||||
char qbuf[384];
|
char qbuf[384];
|
||||||
|
|
||||||
tag(const hostport &, const dns::opts &, callback &&);
|
tag(const hostport &, const dns::opts &, callback &&);
|
||||||
|
tag(tag &&) = delete;
|
||||||
|
tag(const tag &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|
Loading…
Reference in a new issue