1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Refactored DNS.

This commit is contained in:
Matias Fontanini
2012-10-07 19:25:10 -03:00
parent 676bea9035
commit 39623ef7ee
4 changed files with 237 additions and 132 deletions

View File

@@ -121,30 +121,117 @@ namespace Tins {
/**
* \brief Struct that represent DNS queries.
*/
struct Query {
std::string name;
uint16_t type, qclass;
class Query {
public:
/**
* \brief Constructs a DNS query.
*
* \param nm The name of the domain being resolved.
* \param tp The query type.
* \param cl The query class.
*/
Query(const std::string &nm, QueryType tp, QueryClass cl)
: name_(nm), type_(tp), qclass_(cl) {}
Query(const std::string &nm, uint16_t t, uint16_t c) :
name(nm), type(t), qclass(c) {}
Query() {}
/**
* \brief Default constructs this Query.
*/
Query() : type_(), qclass_() {}
/**
* \brief Setter for the name field.
*
* \param nm The name to be set.
*/
void dname(const std::string &nm) {
name_ = nm;
}
/**
* \brief Setter for the query type field.
*
* \param tp The query type to be set.
*/
void type(QueryType tp) {
type_ = tp;
}
/**
* \brief Setter for the query class field.
*
* \param cl The query class to be set.
*/
void query_class(QueryClass cl) {
qclass_ = cl;
}
/**
* \brief Getter for the name field.
*/
const std::string &dname() const { return name_; }
/**
* \brief Getter for the query type field.
*/
QueryType type() const { return type_; }
/**
* \brief Getter for the query class field.
*/
QueryClass query_class() const { return qclass_; }
private:
std::string name_;
QueryType type_;
QueryClass qclass_;
};
/**
* \brief Struct that represent DNS resource records.
*/
struct Resource {
std::string dname, addr;
uint16_t type, qclass;
uint32_t ttl;
class Resource {
public:
Resource(const std::string &nm, const std::string &ad,
uint16_t t, uint16_t c, uint32_t tt) :
dname(nm), addr(ad), type(t), qclass(c), ttl(tt) {}
uint16_t t, uint16_t c, uint32_t tt)
: dname_(nm), addr_(ad), type_(t), qclass_(c), ttl_(tt) {}
Resource() : type_(), qclass_(), ttl_() {}
/**
* \brief Getter for the dname field.
*
* This returns the domain name for which this record
* provides an answer.
*/
const std::string &dname() const { return dname_; }
/**
* Getter for the type field.
*/
const std::string &data() const { return addr_; }
/**
* Getter for the query type field.
*/
uint16_t type() const { return type_; }
/**
* Getter for the query class field.
*/
uint16_t query_class() const { return qclass_; }
/**
* Getter for the type field.
*/
uint32_t ttl() const { return ttl_; }
private:
std::string dname_, addr_;
uint16_t type_, qclass_;
uint32_t ttl_;
};
typedef std::list<Query> queries_type;
typedef std::list<Resource> resources_type;
typedef IPv4Address address_type;
/**
* \brief Default constructor.
@@ -154,9 +241,7 @@ namespace Tins {
DNS();
/**
* \brief Constructor which creates a DNS object from a buffer
* and adds all identifiable PDUs found in the buffer as
* children of this one.
* \brief Constructor which creates a DNS object from a buffer.
* \param buffer The buffer from which this PDU will be
* constructed.
* \param total_sz The total size of the buffer.
@@ -253,28 +338,28 @@ namespace Tins {
*
* \return uint16_t containing the value of the questions field.
*/
uint16_t questions() const { return Endian::be_to_host(dns.questions); }
uint16_t questions_count() const { return Endian::be_to_host(dns.questions); }
/**
* \brief Setter for the answers field.
*
* \return uint16_t containing the value of the answers field.
*/
uint16_t answers() const { return Endian::be_to_host(dns.answers); }
uint16_t answers_count() const { return Endian::be_to_host(dns.answers); }
/**
* \brief Setter for the authority field.
*
* \return uint16_t containing the value of the authority field.
*/
uint16_t authority() const { return Endian::be_to_host(dns.authority); }
uint16_t authority_count() const { return Endian::be_to_host(dns.authority); }
/**
* \brief Setter for the additional field.
*
* \return uint16_t containing the value of the additional field.
*/
uint16_t additional() const { return Endian::be_to_host(dns.additional); }
uint16_t additional_count() const { return Endian::be_to_host(dns.additional); }
/**
* \brief Getter for the PDU's type.
@@ -373,14 +458,6 @@ namespace Tins {
void rcode(uint8_t new_rcode);
// Methods
/**
* \brief Add a query to perform.
*
* \param name The name to be resolved.
* \param type The type of this query.
* \param qclass The class of this query.
*/
void add_query(const std::string &name, QueryType type, QueryClass qclass);
/**
* \brief Add a query to perform.
@@ -398,8 +475,8 @@ namespace Tins {
* \param ttl The time-to-live of this answer.
* \param ip The ip address of the resolved name.
*/
void add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, IPv4Address ip);
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, address_type ip);
/**
* \brief Add a query response.
@@ -410,8 +487,8 @@ namespace Tins {
* \param ttl The time-to-live of this answer.
* \param dname The domain of the resolved name.
*/
void add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const std::string &dname);
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, const std::string &dname);
/**
* \brief Add a query response.
@@ -423,8 +500,8 @@ namespace Tins {
* \param data The data of this option.
* \param sz The size of the data.
*/
void add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const uint8_t *data, uint32_t sz);
void add_answer(const std::string &name,
const DNSResourceRecord::info &info, const uint8_t *data, uint32_t sz);
/**
* \brief Add an authority record.
@@ -436,8 +513,8 @@ namespace Tins {
* \param data The data of this option.
* \param sz The size of the data.
*/
void add_authority(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const uint8_t *data, uint32_t sz);
void add_authority(const std::string &name,
const DNSResourceRecord::info &info, const uint8_t *data, uint32_t sz);
/**
* \brief Add an additional record.
@@ -448,8 +525,8 @@ namespace Tins {
* \param ttl The time-to-live of this record.
* \param ip The ip address of the resolved name.
*/
void add_additional(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, uint32_t ip);
void add_additional(const std::string &name,
const DNSResourceRecord::info &info, uint32_t ip);
/**
@@ -457,14 +534,14 @@ namespace Tins {
* \return std::list<Query> containing the queries in this
* record.
*/
queries_type dns_queries() const;
queries_type queries() const;
/**
* \brief Getter for this PDU's DNS answers
* \return std::list<Resource> containing the answers in this
* record.
*/
resources_type dns_answers();
resources_type answers() const;
/**
* \sa PDU::clone
@@ -472,6 +549,17 @@ namespace Tins {
DNS *clone() const {
return new DNS(*this);
}
/**
* Helper function to create a resource record information
*
* \param type The type of the query.
* \param qclass The class of the query.
* \param ttl The time-to-live of the query.
*/
static DNSResourceRecord::info make_info(QueryType type, QueryClass qclass, uint32_t ttl) {
return DNSResourceRecord::info((uint16_t)type, (uint16_t)qclass, ttl);
}
private:
struct dnshdr {
uint16_t id;
@@ -516,23 +604,23 @@ namespace Tins {
void unparse_domain_name(const std::string &dn, std::string &out) const;
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint8_t *serialize_list(const ResourcesType &lst, uint8_t *buffer) const;
void compose_name(const uint8_t *ptr, uint32_t sz, std::string &out);
void convert_resources(const ResourcesType &lst, std::list<Resource> &res);
DNSResourceRecord make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip);
DNSResourceRecord make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, const std::string &dname);
DNSResourceRecord make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, const uint8_t *ptr, uint32_t len);
void add_suffix(uint32_t index, const uint8_t *data, uint32_t sz);
uint32_t build_suffix_map(uint32_t index, const ResourcesType &lst);
uint32_t build_suffix_map(uint32_t index, const QueriesType &lst);
void build_suffix_map();
bool contains_dname(uint16_t type);
void compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) const;
void convert_resources(const ResourcesType &lst, std::list<Resource> &res) const;
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, uint32_t ip);
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, const std::string &dname);
DNSResourceRecord make_record(const std::string &name, const DNSResourceRecord::info &info, const uint8_t *ptr, uint32_t len);
void add_suffix(uint32_t index, const uint8_t *data, uint32_t sz) const;
uint32_t build_suffix_map(uint32_t index, const ResourcesType &lst) const;
uint32_t build_suffix_map(uint32_t index, const QueriesType &lst) const;
void build_suffix_map() const ;
static bool contains_dname(uint16_t type);
dnshdr dns;
uint32_t extra_size;
std::list<Query> queries;
std::list<Query> queries_;
ResourcesType ans, arity, addit;
SuffixMap suffixes;
SuffixIndices suffix_indices;
mutable SuffixMap suffixes;
mutable SuffixIndices suffix_indices;
};
};

View File

@@ -37,9 +37,14 @@ public:
/**
* \brief The type used to store resource records' information.
*/
struct Info {
struct info {
uint16_t type, qclass;
uint32_t ttl;
info(uint16_t tp, uint16_t qc, uint32_t tm)
: type(tp), qclass(qc), ttl(tm) { }
info() : type(), qclass(), ttl() {}
} __attribute__((packed));
/**
@@ -143,14 +148,14 @@ public:
/**
* \brief Returns a reference to the info field.
*/
Info &info() {
info &information() {
return info_;
}
/**
* \brief Returns a const reference to the info field.
*/
const Info &info() const {
const info &information() const {
return info_;
}
@@ -165,7 +170,7 @@ private:
DNSRRImpl *clone_impl() const;
size_t impl_size() const;
Info info_;
info info_;
std::vector<uint8_t> data;
DNSRRImpl *impl;
};

View File

@@ -40,7 +40,7 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : PDU(255), extra_size(0) {
throw std::runtime_error("Not enough size for a DNS header in the buffer.");
std::memcpy(&dns, buffer, sizeof(dnshdr));
const uint8_t *end(buffer + total_sz);
uint16_t nquestions(questions());
uint16_t nquestions(questions_count());
buffer += sizeof(dnshdr);
total_sz -= sizeof(dnshdr);
for(uint16_t i(0); i < nquestions; ++i) {
@@ -50,19 +50,19 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : PDU(255), extra_size(0) {
Query query;
if((ptr + (sizeof(uint16_t) * 2)) >= end)
throw std::runtime_error("Not enough size for a given query.");
query.name = string(buffer, ptr);
query.dname(string(buffer, ptr));
ptr++;
const uint16_t *opt_ptr = reinterpret_cast<const uint16_t*>(ptr);
query.type = *(opt_ptr++);
query.qclass = *(opt_ptr++);
queries.push_back(query);
query.type((QueryType)*(opt_ptr++));
query.query_class((QueryClass)*(opt_ptr++));
queries_.push_back(query);
total_sz -= reinterpret_cast<const uint8_t*>(opt_ptr) - buffer;
extra_size += reinterpret_cast<const uint8_t*>(opt_ptr) - buffer;
buffer = reinterpret_cast<const uint8_t*>(opt_ptr);
}
buffer = build_resource_list(ans, buffer, total_sz, answers());
buffer = build_resource_list(arity, buffer, total_sz, authority());
build_resource_list(addit, buffer, total_sz, additional());
buffer = build_resource_list(ans, buffer, total_sz, answers_count());
buffer = build_resource_list(arity, buffer, total_sz, authority_count());
build_resource_list(addit, buffer, total_sz, additional_count());
}
const uint8_t *DNS::build_resource_list(ResourcesType &lst, const uint8_t *ptr, uint32_t &sz, uint16_t nrecs) {
@@ -135,68 +135,73 @@ bool DNS::contains_dname(uint16_t type) {
type == PTR || type == NS;
}
void DNS::add_query(const string &name, QueryType type, QueryClass qclass) {
void DNS::add_query(const Query &query) {
string new_str;
parse_domain_name(name, new_str);
parse_domain_name(query.dname(), new_str);
queries.push_back(
Query(new_str,
Endian::host_to_be<uint16_t>(type),
Endian::host_to_be<uint16_t>(qclass))
queries_.push_back(
Query(
new_str,
(QueryType)Endian::host_to_be<uint16_t>(query.type()),
(QueryClass)Endian::host_to_be<uint16_t>(query.query_class())
)
);
extra_size += new_str.size() + 1 + (sizeof(uint16_t) << 1);
dns.questions = Endian::host_to_be<uint16_t>(queries.size());
dns.questions = Endian::host_to_be<uint16_t>(queries_.size());
}
void DNS::add_query(const Query &query) {
add_query(
query.name,
static_cast<QueryType>(query.type),
static_cast<QueryClass>(query.qclass)
);
}
void DNS::add_answer(const string &name, QueryType type, QueryClass qclass, uint32_t ttl, IPv4Address ip) {
ans.push_back(make_record(name, type, qclass, ttl, Endian::host_to_be((uint32_t)ip)));
void DNS::add_answer(const string &name, const DNSResourceRecord::info &info,
address_type ip)
{
ans.push_back(make_record(name, info, Endian::host_to_be((uint32_t)ip)));
dns.answers = Endian::host_to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const std::string &dname) {
void DNS::add_answer(const std::string &name, const DNSResourceRecord::info &info,
const std::string &dname)
{
string new_str;
parse_domain_name(dname, new_str);
DNSResourceRecord res = make_record(name, type, qclass, ttl, new_str);
DNSResourceRecord res = make_record(name, info, new_str);
ans.push_back(res);
dns.answers = Endian::host_to_be<uint16_t>(ans.size());
}
void DNS::add_answer(const std::string &name, QueryType type, QueryClass qclass,
uint32_t ttl, const uint8_t *data, uint32_t sz) {
ans.push_back(make_record(name, type, qclass, ttl, data, sz));
void DNS::add_answer(const std::string &name, const DNSResourceRecord::info &info,
const uint8_t *data, uint32_t sz)
{
ans.push_back(make_record(name, info, data, sz));
dns.answers = Endian::host_to_be<uint16_t>(ans.size());
}
void DNS::add_authority(const string &name, QueryType type,
QueryClass qclass, uint32_t ttl, const uint8_t *data, uint32_t sz) {
arity.push_back(make_record(name, type, qclass, ttl, data, sz));
void DNS::add_authority(const string &name, const DNSResourceRecord::info &info,
const uint8_t *data, uint32_t sz)
{
arity.push_back(make_record(name, info, data, sz));
dns.authority = Endian::host_to_be<uint16_t>(arity.size());
}
void DNS::add_additional(const string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip) {
addit.push_back(make_record(name, type, qclass, ttl, ip));
void DNS::add_additional(const string &name, const DNSResourceRecord::info &info,
uint32_t ip)
{
addit.push_back(make_record(name, info, ip));
dns.additional = Endian::host_to_be<uint16_t>(addit.size());
}
DNSResourceRecord DNS::make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, uint32_t ip) {
DNSResourceRecord DNS::make_record(const std::string &name, const DNSResourceRecord::info &info, uint32_t ip) {
ip = Endian::host_to_be(ip);
return make_record(name, type, qclass, ttl, reinterpret_cast<uint8_t*>(&ip), sizeof(ip));
return make_record(name, info, reinterpret_cast<uint8_t*>(&ip), sizeof(ip));
}
DNSResourceRecord DNS::make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, const std::string &dname) {
return make_record(name, type, qclass, ttl, reinterpret_cast<const uint8_t*>(dname.c_str()), dname.size() + 1);
DNSResourceRecord DNS::make_record(const std::string &name,
const DNSResourceRecord::info &info, const std::string &dname)
{
return make_record(name, info, reinterpret_cast<const uint8_t*>(dname.c_str()), dname.size() + 1);
}
DNSResourceRecord DNS::make_record(const std::string &name, QueryType type, QueryClass qclass, uint32_t ttl, const uint8_t *ptr, uint32_t len) {
DNSResourceRecord DNS::make_record(const std::string &name,
const DNSResourceRecord::info &info, const uint8_t *ptr, uint32_t len)
{
string nm;
parse_domain_name(name, nm);
uint16_t index = find_domain_name(nm);
@@ -205,19 +210,19 @@ DNSResourceRecord DNS::make_record(const std::string &name, QueryType type, Quer
res = make_offseted_record(Endian::host_to_be(index), ptr, len);
else
res = make_named_record(nm, ptr, len);
res.info().type = Endian::host_to_be<uint16_t>(type);
res.info().qclass = Endian::host_to_be<uint16_t>(qclass);
res.info().ttl = Endian::host_to_be(ttl);
res.information().type = Endian::host_to_be<uint16_t>(info.type);
res.information().qclass = Endian::host_to_be<uint16_t>(info.qclass);
res.information().ttl = Endian::host_to_be(info.ttl);
extra_size += res.size();
return res;
}
uint32_t DNS::find_domain_name(const std::string &dname) {
uint16_t index(sizeof(dnshdr));
list<Query>::const_iterator it(queries.begin());
for(; it != queries.end() && it->name != dname; ++it)
index += it->name.size() + 1 + (sizeof(uint16_t) << 1);
if(it != queries.end() ||
list<Query>::const_iterator it(queries_.begin());
for(; it != queries_.end() && it->dname() != dname; ++it)
index += it->dname().size() + 1 + (sizeof(uint16_t) << 1);
if(it != queries_.end() ||
find_domain_name(dname, ans, index) ||
find_domain_name(dname, arity, index) ||
find_domain_name(dname, addit, index))
@@ -271,12 +276,13 @@ void DNS::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *par
assert(total_sz >= sizeof(dns) + extra_size);
std::memcpy(buffer, &dns, sizeof(dns));
buffer += sizeof(dns);
for(list<Query>::const_iterator it(queries.begin()); it != queries.end(); ++it) {
std::memcpy(buffer, it->name.c_str(), it->name.size() + 1);
buffer += it->name.size() + 1;
*((uint16_t*)buffer) = it->type;
for(list<Query>::const_iterator it(queries_.begin()); it != queries_.end(); ++it) {
std::copy(it->dname().begin(), it->dname().end(), buffer);
buffer += it->dname().size();
*buffer++ = 0;
*((uint16_t*)buffer) = it->type();
buffer += sizeof(uint16_t);
*((uint16_t*)buffer) = it->qclass;
*((uint16_t*)buffer) = it->query_class();
buffer += sizeof(uint16_t);
}
buffer = serialize_list(ans, buffer);
@@ -290,7 +296,7 @@ uint8_t *DNS::serialize_list(const ResourcesType &lst, uint8_t *buffer) const {
return buffer;
}
void DNS::add_suffix(uint32_t index, const uint8_t *data, uint32_t sz) {
void DNS::add_suffix(uint32_t index, const uint8_t *data, uint32_t sz) const {
uint32_t i(0), suff_sz(data[0]);
SuffixMap::iterator it;
while((i + suff_sz + 1 <= sz || (suff_sz == 0xc0 && i + 1 < sz)) && suff_sz) {
@@ -309,7 +315,7 @@ void DNS::add_suffix(uint32_t index, const uint8_t *data, uint32_t sz) {
}
}
uint32_t DNS::build_suffix_map(uint32_t index, const ResourcesType &lst) {
uint32_t DNS::build_suffix_map(uint32_t index, const ResourcesType &lst) const {
const string *str;
for(ResourcesType::const_iterator it(lst.begin()); it != lst.end(); ++it) {
str = it->dname();
@@ -319,38 +325,38 @@ uint32_t DNS::build_suffix_map(uint32_t index, const ResourcesType &lst) {
}
else
index += sizeof(uint16_t);
index += sizeof(DNSResourceRecord::Info) + sizeof(uint16_t);
index += sizeof(DNSResourceRecord::info) + sizeof(uint16_t);
uint32_t sz(it->data_size());
const uint8_t *ptr = it->data_ptr();
if(Endian::be_to_host(it->info().type) == MX) {
if(Endian::be_to_host(it->information().type) == MX) {
ptr += 2;
sz -= 2;
index += 2;
}
if(contains_dname(it->info().type))
if(contains_dname(it->information().type))
add_suffix(index, ptr, sz);
index += sz;
}
return index;
}
uint32_t DNS::build_suffix_map(uint32_t index, const list<Query> &lst) {
uint32_t DNS::build_suffix_map(uint32_t index, const list<Query> &lst) const {
for(list<Query>::const_iterator it(lst.begin()); it != lst.end(); ++it) {
add_suffix(index, (uint8_t*)it->name.c_str(), it->name.size());
index += it->name.size() + 1 + (sizeof(uint16_t) << 1);
add_suffix(index, (uint8_t*)it->dname().c_str(), it->dname().size());
index += it->dname().size() + 1 + (sizeof(uint16_t) << 1);
}
return index;
}
void DNS::build_suffix_map() {
void DNS::build_suffix_map() const {
uint32_t index(sizeof(dnshdr));
index = build_suffix_map(index, queries);
index = build_suffix_map(index, queries_);
index = build_suffix_map(index, ans);
index = build_suffix_map(index, arity);
build_suffix_map(index, addit);
}
void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) const {
uint32_t i(0);
while(i < sz) {
if(i && ptr[i])
@@ -360,7 +366,6 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
index &= 0x3fff;
SuffixMap::iterator it(suffixes.find(index));
SuffixIndices::iterator suff_it(suffix_indices.find(index));
//assert(it != suffixes.end() && suff_it == suffix_indices.end());
if(it == suffixes.end() || suff_it == suffix_indices.end())
throw std::runtime_error("Malformed DNS packet");
bool first(true);
@@ -391,7 +396,7 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) {
}
}
void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res) {
void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res) const {
if(!suffixes.size())
build_suffix_map();
const string *str_ptr;
@@ -410,31 +415,38 @@ void DNS::convert_resources(const ResourcesType &lst, std::list<Resource> &res)
if(sz == 4)
addr = IPv4Address(*(uint32_t*)ptr).to_string();
else {
if(Endian::be_to_host(it->info().type) == MX) {
if(Endian::be_to_host(it->information().type) == MX) {
ptr += 2;
sz -= 2;
}
compose_name(ptr, sz, addr);
}
res.push_back(
Resource(dname, addr, Endian::be_to_host(it->info().type),
Endian::host_to_be(it->info().qclass), Endian::be_to_host(it->info().ttl)
Resource(dname, addr, Endian::be_to_host(it->information().type),
Endian::host_to_be(it->information().qclass),
Endian::be_to_host(it->information().ttl)
)
);
}
}
DNS::queries_type DNS::dns_queries() const {
DNS::queries_type DNS::queries() const {
queries_type output;
for(std::list<Query>::const_iterator it(queries.begin()); it != queries.end(); ++it) {
for(std::list<Query>::const_iterator it(queries_.begin()); it != queries_.end(); ++it) {
string dn;
unparse_domain_name(it->name, dn);
output.push_back(Query(dn, Endian::be_to_host(it->type), Endian::be_to_host(it->qclass)));
unparse_domain_name(it->dname(), dn);
output.push_back(
Query(
dn,
(QueryType)Endian::be_to_host<uint16_t>(it->type()),
(QueryClass)Endian::be_to_host<uint16_t>(it->query_class())
)
);
}
return output;
}
DNS::resources_type DNS::dns_answers() {
DNS::resources_type DNS::answers() const {
resources_type res;
convert_resources(ans, res);
return res;

View File

@@ -104,7 +104,7 @@ uint32_t DNSResourceRecord::write(uint8_t *buffer) const {
buffer += sz;
std::memcpy(buffer, &info_, sizeof(info_));
buffer += sizeof(info_);
*((uint16_t*)buffer) = Endian::host_to_be(data.size());
*((uint16_t*)buffer) = Endian::host_to_be<uint16_t>(data.size());
buffer += sizeof(uint16_t);
std::copy(data.begin(), data.end(), buffer);
return sz + sizeof(info_) + sizeof(uint16_t) + data.size();