mirror of
https://github.com/matrix-construct/construct
synced 2024-09-27 19:28:52 +02:00
ircd::net::dns: Add support for netdb; interface to getservbyname(3).
This commit is contained in:
parent
4b41efcdc8
commit
0e25a2e055
3 changed files with 91 additions and 1 deletions
|
@ -921,6 +921,7 @@ dnl unix platform
|
||||||
RB_CHK_SYSHEADER(unistd.h, [UNISTD_H])
|
RB_CHK_SYSHEADER(unistd.h, [UNISTD_H])
|
||||||
RB_CHK_SYSHEADER(signal.h, [SIGNAL_H])
|
RB_CHK_SYSHEADER(signal.h, [SIGNAL_H])
|
||||||
RB_CHK_SYSHEADER(ifaddrs.h, [IFADDRS_H])
|
RB_CHK_SYSHEADER(ifaddrs.h, [IFADDRS_H])
|
||||||
|
RB_CHK_SYSHEADER(netdb.h, [NETDB_H])
|
||||||
RB_CHK_SYSHEADER(fcntl.h, [FCNTL_H])
|
RB_CHK_SYSHEADER(fcntl.h, [FCNTL_H])
|
||||||
RB_CHK_SYSHEADER(elf.h, [ELF_H])
|
RB_CHK_SYSHEADER(elf.h, [ELF_H])
|
||||||
RB_CHK_SYSHEADER(link.h, [LINK_H])
|
RB_CHK_SYSHEADER(link.h, [LINK_H])
|
||||||
|
|
|
@ -37,9 +37,13 @@ namespace ircd::net::dns
|
||||||
bool expired(const json::object &rr, const time_t &rr_ts, const time_t &min_ttl);
|
bool expired(const json::object &rr, const time_t &rr_ts, const time_t &min_ttl);
|
||||||
bool expired(const json::object &rr, const time_t &rr_ts);
|
bool expired(const json::object &rr, const time_t &rr_ts);
|
||||||
json::object random_choice(const json::array &);
|
json::object random_choice(const json::array &);
|
||||||
|
|
||||||
string_view make_SRV_key(const mutable_buffer &out, const hostport &, const opts &);
|
string_view make_SRV_key(const mutable_buffer &out, const hostport &, const opts &);
|
||||||
string_view unmake_SRV_key(const string_view &);
|
string_view unmake_SRV_key(const string_view &);
|
||||||
|
|
||||||
|
uint16_t service_port(std::nothrow_t, const string_view &name, const string_view &prot = {});
|
||||||
|
uint16_t service_port(const string_view &name, const string_view &prot = {});
|
||||||
|
|
||||||
// Callback-based interface
|
// Callback-based interface
|
||||||
void resolve(const hostport &, const opts &, callback);
|
void resolve(const hostport &, const opts &, callback);
|
||||||
void resolve(const hostport &, const opts &, callback_one); // convenience
|
void resolve(const hostport &, const opts &, callback_one); // convenience
|
||||||
|
@ -86,6 +90,10 @@ struct ircd::net::dns::opts
|
||||||
/// the returned record is a reference to the cached error.
|
/// the returned record is a reference to the cached error.
|
||||||
bool nxdomain_exceptions {true};
|
bool nxdomain_exceptions {true};
|
||||||
|
|
||||||
|
/// When false, queries to translate service strings to port numbers using
|
||||||
|
/// netdb (i.e. /etc/services) will be disabled if they were to occur.
|
||||||
|
bool service_port {true};
|
||||||
|
|
||||||
opts() = default;
|
opts() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
// full license for this software is available in the LICENSE file.
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#include <RB_INC_NETDB_H
|
||||||
#include <ircd/net/dns_cache.h>
|
#include <ircd/net/dns_cache.h>
|
||||||
|
|
||||||
namespace ircd::net::dns
|
namespace ircd::net::dns
|
||||||
|
@ -112,16 +113,22 @@ ircd::net::dns::resolve(const hostport &hp,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::net::dns::resolve(const hostport &hp,
|
ircd::net::dns::resolve(const hostport &hp_,
|
||||||
const opts &opts,
|
const opts &opts,
|
||||||
callback cb)
|
callback cb)
|
||||||
{
|
{
|
||||||
|
hostport hp(hp_);
|
||||||
if(unlikely(!opts.qtype))
|
if(unlikely(!opts.qtype))
|
||||||
throw error
|
throw error
|
||||||
{
|
{
|
||||||
"Query type is required; not specified; cannot be deduced here."
|
"Query type is required; not specified; cannot be deduced here."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Make any necessary attempt to translate a service name into a portnum.
|
||||||
|
if(likely(opts.service_port))
|
||||||
|
if(!port(hp) && service(hp))
|
||||||
|
port(hp) = service_port(std::nothrow, service(hp), opts.proto);
|
||||||
|
|
||||||
// Try to satisfy from the cache first. This requires a ctx.
|
// Try to satisfy from the cache first. This requires a ctx.
|
||||||
if(likely(ctx::current && opts.cache_check))
|
if(likely(ctx::current && opts.cache_check))
|
||||||
if(cache::get(hp, opts, cb))
|
if(cache::get(hp, opts, cb))
|
||||||
|
@ -532,3 +539,77 @@ ircd::net::dns::new_record(mutable_buffer &buf,
|
||||||
consume(buf, sizeof(type));
|
consume(buf, sizeof(type));
|
||||||
return new (pos) type(answer);
|
return new (pos) type(answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
ircd::net::dns::service_port(const string_view &name,
|
||||||
|
const string_view &prot)
|
||||||
|
{
|
||||||
|
const auto ret
|
||||||
|
{
|
||||||
|
service_port(std::nothrow, name, prot)
|
||||||
|
};
|
||||||
|
|
||||||
|
if(unlikely(!ret))
|
||||||
|
throw error
|
||||||
|
{
|
||||||
|
"Port for service %s:%s not found",
|
||||||
|
name,
|
||||||
|
prot?: "*"_sv,
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
uint16_t
|
||||||
|
ircd::net::dns::service_port(std::nothrow_t,
|
||||||
|
const string_view &name,
|
||||||
|
const string_view &prot)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
thread_local struct ::servent res, *ent {nullptr};
|
||||||
|
thread_local char _name[32], _prot[32], buf[2048];
|
||||||
|
|
||||||
|
strlcpy(_name, name);
|
||||||
|
strlcpy(_prot, prot);
|
||||||
|
syscall
|
||||||
|
(
|
||||||
|
::getservbyname_r,
|
||||||
|
_name,
|
||||||
|
prot? _prot : nullptr,
|
||||||
|
&res,
|
||||||
|
buf,
|
||||||
|
sizeof(buf),
|
||||||
|
&ent
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(!ent || ent->s_port != 0);
|
||||||
|
assert(!ent || name == ent->s_name);
|
||||||
|
assert(!ent || !prot || prot == ent->s_proto);
|
||||||
|
return ent?
|
||||||
|
htons(ent->s_port):
|
||||||
|
0U;
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
log::critical
|
||||||
|
{
|
||||||
|
log, "Failure when translating service %s:%s to port number :%s",
|
||||||
|
name,
|
||||||
|
prot?: "*"_sv,
|
||||||
|
e.what(),
|
||||||
|
};
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
uint16_t
|
||||||
|
ircd::net::dns::service_port(std::nothrow_t,
|
||||||
|
const string_view &name,
|
||||||
|
const string_view &prot)
|
||||||
|
{
|
||||||
|
//TODO: XXX
|
||||||
|
always_assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue