0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-28 11:48:54 +02:00

ircd::rfc1035: Dynamic abstraction for resource records; minor comments.

This commit is contained in:
Jason Volk 2018-02-03 10:39:01 -08:00
parent d53eef4ab6
commit 46bf944227
2 changed files with 66 additions and 8 deletions

View file

@ -125,6 +125,8 @@ static_assert
"The RFC1035 header is not the right size in this environment"
);
/// DNS operation code
///
enum class ircd::rfc1035::op
:uint8_t
{
@ -135,37 +137,68 @@ enum class ircd::rfc1035::op
UPDATE = 5, ///< Update [RFC 2136]
};
/// Resource record abstract base
///
struct ircd::rfc1035::record
{
struct A;
struct AAAA;
struct CNAME;
struct SRV;
uint16_t type;
time_t ttl;
const_buffer rdata;
template<class T> const T &as() const;
record(const answer &);
virtual ~record() noexcept;
};
template<class T>
const T &
ircd::rfc1035::record::as()
const
{
return dynamic_cast<T &>(*this);
}
//
// Types of records
//
/// IPv4 address record
struct ircd::rfc1035::record::A
:record
{
uint32_t ip4;
A(const const_buffer &rdata);
A(const answer &);
};
/// IPv6 address record
struct ircd::rfc1035::record::AAAA
:record
{
uint128_t ip6;
AAAA(const const_buffer &rdata);
AAAA(const answer &);
};
/// Canonical name aliasing record
struct ircd::rfc1035::record::CNAME
:record
{
string_view name;
char namebuf[256];
CNAME(const const_buffer &rdata);
CNAME(const answer &);
};
/// Service record
struct ircd::rfc1035::record::SRV
:record
{
uint16_t priority;
uint16_t weight;
@ -173,5 +206,5 @@ struct ircd::rfc1035::record::SRV
string_view tgt;
char tgtbuf[256];
SRV(const const_buffer &rdata);
SRV(const answer &);
};

View file

@ -174,7 +174,25 @@ ircd::rfc1035::answer::parse(const const_buffer &in)
return { data(in), pos };
}
ircd::rfc1035::record::A::A(const const_buffer &rdata)
//
// Record
//
ircd::rfc1035::record::record(const answer &answer)
:type{answer.qtype}
,ttl{answer.ttl}
,rdata{answer.rdata}
{
}
/// vtable
ircd::rfc1035::record::~record()
noexcept
{
}
ircd::rfc1035::record::A::A(const answer &answer)
:record{answer}
{
assert(size(rdata) == 4);
if(unlikely(size(rdata) < 4))
@ -186,7 +204,8 @@ ircd::rfc1035::record::A::A(const const_buffer &rdata)
ip4 = bswap(*(const uint32_t *)data(rdata));
}
ircd::rfc1035::record::AAAA::AAAA(const const_buffer &rdata)
ircd::rfc1035::record::AAAA::AAAA(const answer &answer)
:record{answer}
{
assert(size(rdata) == 16);
if(unlikely(size(rdata) < 16))
@ -198,7 +217,8 @@ ircd::rfc1035::record::AAAA::AAAA(const const_buffer &rdata)
ip6 = bswap(*(const uint128_t *)data(rdata));
}
ircd::rfc1035::record::CNAME::CNAME(const const_buffer &rdata)
ircd::rfc1035::record::CNAME::CNAME(const answer &answer)
:record{answer}
{
if(unlikely(size(rdata) < 1))
throw error
@ -210,7 +230,8 @@ ircd::rfc1035::record::CNAME::CNAME(const const_buffer &rdata)
name = string_view{namebuf, len};
}
ircd::rfc1035::record::SRV::SRV(const const_buffer &rdata)
ircd::rfc1035::record::SRV::SRV(const answer &answer)
:record{answer}
{
if(unlikely(size(rdata) < 2 + 2 + 2 + 1))
throw error
@ -231,6 +252,10 @@ ircd::rfc1035::record::SRV::SRV(const const_buffer &rdata)
assert(std::distance(pos, end(rdata)) == 0);
}
//
// Util / misc
//
ircd::const_buffer
ircd::rfc1035::make_name(const mutable_buffer &out,
const string_view &fqdn)