mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::rfc1035: Dynamic abstraction for resource records; minor comments.
This commit is contained in:
parent
d53eef4ab6
commit
46bf944227
2 changed files with 66 additions and 8 deletions
|
@ -125,6 +125,8 @@ static_assert
|
||||||
"The RFC1035 header is not the right size in this environment"
|
"The RFC1035 header is not the right size in this environment"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// DNS operation code
|
||||||
|
///
|
||||||
enum class ircd::rfc1035::op
|
enum class ircd::rfc1035::op
|
||||||
:uint8_t
|
:uint8_t
|
||||||
{
|
{
|
||||||
|
@ -135,37 +137,68 @@ enum class ircd::rfc1035::op
|
||||||
UPDATE = 5, ///< Update [RFC 2136]
|
UPDATE = 5, ///< Update [RFC 2136]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Resource record abstract base
|
||||||
|
///
|
||||||
struct ircd::rfc1035::record
|
struct ircd::rfc1035::record
|
||||||
{
|
{
|
||||||
struct A;
|
struct A;
|
||||||
struct AAAA;
|
struct AAAA;
|
||||||
struct CNAME;
|
struct CNAME;
|
||||||
struct SRV;
|
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
|
struct ircd::rfc1035::record::A
|
||||||
|
:record
|
||||||
{
|
{
|
||||||
uint32_t ip4;
|
uint32_t ip4;
|
||||||
|
|
||||||
A(const const_buffer &rdata);
|
A(const answer &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// IPv6 address record
|
||||||
struct ircd::rfc1035::record::AAAA
|
struct ircd::rfc1035::record::AAAA
|
||||||
|
:record
|
||||||
{
|
{
|
||||||
uint128_t ip6;
|
uint128_t ip6;
|
||||||
|
|
||||||
AAAA(const const_buffer &rdata);
|
AAAA(const answer &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Canonical name aliasing record
|
||||||
struct ircd::rfc1035::record::CNAME
|
struct ircd::rfc1035::record::CNAME
|
||||||
|
:record
|
||||||
{
|
{
|
||||||
string_view name;
|
string_view name;
|
||||||
char namebuf[256];
|
char namebuf[256];
|
||||||
|
|
||||||
CNAME(const const_buffer &rdata);
|
CNAME(const answer &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Service record
|
||||||
struct ircd::rfc1035::record::SRV
|
struct ircd::rfc1035::record::SRV
|
||||||
|
:record
|
||||||
{
|
{
|
||||||
uint16_t priority;
|
uint16_t priority;
|
||||||
uint16_t weight;
|
uint16_t weight;
|
||||||
|
@ -173,5 +206,5 @@ struct ircd::rfc1035::record::SRV
|
||||||
string_view tgt;
|
string_view tgt;
|
||||||
char tgtbuf[256];
|
char tgtbuf[256];
|
||||||
|
|
||||||
SRV(const const_buffer &rdata);
|
SRV(const answer &);
|
||||||
};
|
};
|
||||||
|
|
|
@ -174,7 +174,25 @@ ircd::rfc1035::answer::parse(const const_buffer &in)
|
||||||
return { data(in), pos };
|
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);
|
assert(size(rdata) == 4);
|
||||||
if(unlikely(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));
|
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);
|
assert(size(rdata) == 16);
|
||||||
if(unlikely(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));
|
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))
|
if(unlikely(size(rdata) < 1))
|
||||||
throw error
|
throw error
|
||||||
|
@ -210,7 +230,8 @@ ircd::rfc1035::record::CNAME::CNAME(const const_buffer &rdata)
|
||||||
name = string_view{namebuf, len};
|
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))
|
if(unlikely(size(rdata) < 2 + 2 + 2 + 1))
|
||||||
throw error
|
throw error
|
||||||
|
@ -231,6 +252,10 @@ ircd::rfc1035::record::SRV::SRV(const const_buffer &rdata)
|
||||||
assert(std::distance(pos, end(rdata)) == 0);
|
assert(std::distance(pos, end(rdata)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Util / misc
|
||||||
|
//
|
||||||
|
|
||||||
ircd::const_buffer
|
ircd::const_buffer
|
||||||
ircd::rfc1035::make_name(const mutable_buffer &out,
|
ircd::rfc1035::make_name(const mutable_buffer &out,
|
||||||
const string_view &fqdn)
|
const string_view &fqdn)
|
||||||
|
|
Loading…
Reference in a new issue