From: Otto Moerbeek Date: Thu, 24 Feb 2022 19:18:13 +0000 (+0100) Subject: Introduce dnsheader_aligned: a help class to access dnsheaders data X-Git-Tag: rec-4.7.0-beta1~76^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F11364%2Fhead;p=thirdparty%2Fpdns.git Introduce dnsheader_aligned: a help class to access dnsheaders data in a potentially unaligned buffer --- diff --git a/pdns/dns.hh b/pdns/dns.hh index a82aeda351..f0b204ee23 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -207,6 +207,30 @@ struct dnsheader { static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12"); +class dnsheader_aligned +{ +public: + dnsheader_aligned(const void* mem) + { + if (reinterpret_cast(mem) % sizeof(uint32_t) == 0) { + d_p = reinterpret_cast(mem); + } + else { + memcpy(&d_h, mem, sizeof(dnsheader)); + d_p = &d_h; + } + } + + const dnsheader* get() const + { + return d_p; + } + +private: + dnsheader d_h; + const dnsheader *d_p; +}; + inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh) { return (uint16_t*) (((char *) dh) + sizeof(uint16_t)); diff --git a/pdns/packetcache.hh b/pdns/packetcache.hh index 15f9d2de46..82f22ffcf1 100644 --- a/pdns/packetcache.hh +++ b/pdns/packetcache.hh @@ -44,7 +44,8 @@ public: + the OPT RR rdlen (2) = 15 */ - const struct dnsheader* dh = reinterpret_cast(packet.data()); + const dnsheader_aligned dnsheaderdata(packet.data()); + const struct dnsheader *dh = dnsheaderdata.get(); if (ntohs(dh->qdcount) != 1 || ntohs(dh->ancount) != 0 || ntohs(dh->nscount) != 0 || ntohs(dh->arcount) != 1 || (pos + 15) >= packetSize) { if (packetSize > pos) { currentHash = burtle(reinterpret_cast(&packet.at(pos)), packetSize - pos, currentHash); diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 2e7093995c..e82b2c26d0 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1639,7 +1639,8 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* { const bool lookForXPF = xpfSource != nullptr && g_xpfRRCode != 0; const bool lookForECS = ednssubnet != nullptr; - const struct dnsheader* dh = reinterpret_cast(question.c_str()); + const dnsheader_aligned dnshead(question.data()); + const dnsheader* dh = dnshead.get(); size_t questionLen = question.length(); unsigned int consumed = 0; *dnsname = DNSName(question.c_str(), questionLen, sizeof(dnsheader), false, qtype, qclass, &consumed); @@ -1795,7 +1796,8 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr g_stats.ipv6qcounter++; string response; - const struct dnsheader* dh = (struct dnsheader*)question.c_str(); + const dnsheader_aligned headerdata(question.data()); + const dnsheader* dh = headerdata.get(); unsigned int ctag = 0; uint32_t qhash = 0; bool needECS = false; @@ -2149,7 +2151,8 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) } try { - dnsheader* dh = (dnsheader*)&data[0]; + const dnsheader_aligned headerdata(data.data()); + const dnsheader* dh = headerdata.get(); if (dh->qr) { g_stats.ignoredCount++; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 9e46bf7c1e..0ad1cb6721 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -433,7 +433,8 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) dc->d_tag = g_paddingTag; } - const struct dnsheader* dh = reinterpret_cast(&conn->data[0]); + const dnsheader_aligned headerdata(conn->data.data()); + const struct dnsheader* dh = headerdata.get(); if (t_protobufServers || t_outgoingProtobufServers) { dc->d_requestorId = requestorId;