diff --git a/include/ircd/rfc1035.h b/include/ircd/rfc1035.h index 4bafe72cf..741687ce1 100644 --- a/include/ircd/rfc1035.h +++ b/include/ircd/rfc1035.h @@ -79,6 +79,10 @@ struct ircd::rfc1035::question /// struct ircd::rfc1035::answer { + struct A; + struct AAAA; + struct SRV; + uint16_t qtype; uint16_t qclass; uint32_t ttl; @@ -133,3 +137,28 @@ enum class ircd::rfc1035::op NOTIFY = 4, ///< Notify [RFC 1996] UPDATE = 5, ///< Update [RFC 2136] }; + +struct ircd::rfc1035::answer::A +{ + uint32_t ip4; + + A(const const_buffer &rdata); +}; + +struct ircd::rfc1035::answer::AAAA +{ + uint128_t ip6; + + AAAA(const const_buffer &rdata); +}; + +struct ircd::rfc1035::answer::SRV +{ + uint16_t priority; + uint16_t weight; + uint16_t port; + size_t tgtlen; + char tgt[256]; + + SRV(const const_buffer &rdata); +}; diff --git a/ircd/rfc1035.cc b/ircd/rfc1035.cc index 97c365f53..89f58ff42 100644 --- a/ircd/rfc1035.cc +++ b/ircd/rfc1035.cc @@ -172,6 +172,48 @@ ircd::rfc1035::answer::parse(const const_buffer &in) return { data(in), pos }; } +ircd::rfc1035::answer::A::A(const const_buffer &rdata) +{ + if(unlikely(size(rdata) < 4)) + throw error + { + "A record data underflow" + }; + + ip4 = bswap(*(const uint32_t *)data(rdata)); +} + +ircd::rfc1035::answer::AAAA::AAAA(const const_buffer &rdata) +{ + if(unlikely(size(rdata) < 16)) + throw error + { + "AAAA record data underflow" + }; + + ip6 = bswap(*(const uint128_t *)data(rdata)); +} + +ircd::rfc1035::answer::SRV::SRV(const const_buffer &rdata) +{ + if(unlikely(size(rdata) < 2 + 2 + 2 + 1)) + throw error + { + "SRV record data underflow" + }; + + const char *pos(data(rdata)); + priority = bswap(*(const uint16_t *)pos); pos += 2; + weight = bswap(*(const uint16_t *)pos); pos += 2; + port = bswap(*(const uint16_t *)pos); pos += 2; + + const const_buffer tgtbuf{pos, end(rdata)}; + tgtlen = parse_name(tgt, tgtbuf); + pos += tgtlen; + + assert(std::distance(pos, end(rdata)) == 0); +} + ircd::const_buffer ircd::rfc1035::make_name(const mutable_buffer &out, const string_view &fqdn) @@ -205,7 +247,7 @@ ircd::rfc1035::parse_name(const mutable_buffer &out, if(unlikely(empty(in))) throw error { - "Name input buffer is too small" + "Name input buffer underflow" }; const char *pos(data(in));