0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-10 14:08:56 +02:00

ircd::net::dns: Add explicit qtype to opts and integrate w/ query stack.

This commit is contained in:
Jason Volk 2018-10-02 22:38:08 -07:00
parent 58c7a4885b
commit 95c6f69e5d
6 changed files with 94 additions and 40 deletions

View file

@ -48,6 +48,13 @@ namespace ircd::net::dns
/// DNS resolution options
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
/// 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

View file

@ -73,11 +73,7 @@ ircd::net::dns::_resolve_ipport(const hostport &hp,
hp.port = record.port;
hp.host = record.tgt?: unmake_SRV_key(hp.host);
// Have to kill the service name to not run another SRV query now.
hp.service = {};
opts.srv = {};
opts.proto = {};
opts.qtype = 0;
_resolve__A(hp, opts, [calluser(std::move(calluser))]
(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.
void
ircd::net::dns::_resolve__SRV(const hostport &hp,
const opts &opts,
opts opts,
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))]
(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.
void
ircd::net::dns::_resolve__A(const hostport &hp,
const opts &opts,
opts opts,
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))]
(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.
void
ircd::net::dns::_resolve__(const hostport &hp,
const opts &op,
const opts &opts,
callback cb)
{
if(op.cache_check)
if(cache::get(hp, op, cb))
if(unlikely(!opts.qtype))
throw error
{
"A query type is required; not specified; cannot be deduced here."
};
if(opts.cache_check)
if(cache::get(hp, opts, cb))
return;
resolver_call(hp, op, std::move(cb));
resolver_call(hp, opts, std::move(cb));
}

View file

@ -17,8 +17,8 @@ namespace ircd::net::dns
constexpr const size_t MAX_COUNT {64};
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__SRV(const hostport &, const opts &, callback_SRV_one);
extern "C" void _resolve__A(const hostport &, opts, callback_A_one);
extern "C" void _resolve__SRV(const hostport &, opts, callback_SRV_one);
extern "C" void _resolve_ipport(const hostport &, const opts &, callback_ipport_one);
}

View file

@ -178,8 +178,7 @@ ircd::net::dns::cache::_get(const hostport &hp,
std::exception_ptr eptr;
size_t count{0};
//TODO: Better deduction
if(hp.service || opts.srv) // deduced SRV query
if(opts.qtype == 33) // deduced SRV query
{
assert(!empty(host(hp)));
thread_local char srvbuf[512];
@ -224,7 +223,7 @@ ircd::net::dns::cache::_get(const hostport &hp,
++it;
}
}
else // Deduced A query (for now)
else if(opts.qtype == 1)
{
auto &map{cache_A};
const auto &key{rstrip(host(hp), '.')};

View file

@ -60,20 +60,6 @@ ircd::net::dns::resolver::retry_max
// 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
ircd::net::dns::resolver_init()
{
@ -88,6 +74,20 @@ ircd::net::dns::resolver_fini()
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
//
@ -291,22 +291,34 @@ ircd::net::dns::resolver::operator()(const hostport &hp,
ircd::const_buffer
ircd::net::dns::resolver::make_query(const mutable_buffer &buf,
const tag &tag)
const
{
//TODO: Better deduction
if(tag.hp.service || tag.opts.srv)
thread_local char hostbuf[512];
string_view hoststr;
switch(tag.opts.qtype)
{
thread_local char srvbuf[512];
const string_view srvhost
case 0: throw error
{
make_SRV_key(srvbuf, host(tag.hp), tag.opts)
"A query type is required to form a question."
};
const rfc1035::question question{srvhost, "SRV"};
return rfc1035::make_query(buf, tag.id, question);
case 33: // SRV
{
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);
}

View file

@ -46,7 +46,7 @@ struct ircd::net::dns::resolver
void submit(tag &);
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 &&);
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];
tag(const hostport &, const dns::opts &, callback &&);
tag(tag &&) = delete;
tag(const tag &) = delete;
};
inline