]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Introduce dnsheader_aligned: a help class to access dnsheaders data 11364/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 24 Feb 2022 19:18:13 +0000 (20:18 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 24 Feb 2022 19:18:13 +0000 (20:18 +0100)
in a potentially unaligned buffer

pdns/dns.hh
pdns/packetcache.hh
pdns/pdns_recursor.cc
pdns/recursordist/rec-tcp.cc

index a82aeda351f2c4d394a85fe7c3e2513191133e0b..f0b204ee23d57d39cb380cacfb09f36553b920eb 100644 (file)
@@ -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<uintptr_t>(mem) % sizeof(uint32_t) == 0) {
+      d_p = reinterpret_cast<const dnsheader*>(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));
index 15f9d2de46428435afc3afdc6c6aefeba01d4c43..82f22ffcf1bdc29d0e3a8c250010d00ff458e72b 100644 (file)
@@ -44,7 +44,8 @@ public:
        + the OPT RR rdlen (2)
        = 15
     */
-    const struct dnsheader* dh = reinterpret_cast<const struct dnsheader*>(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<const unsigned char*>(&packet.at(pos)), packetSize - pos, currentHash);
index 2e7093995c51176035394286b4d3de49651df3c7..e82b2c26d04ae5ce4345c64108385bd2509f04f7 100644 (file)
@@ -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<const struct dnsheader*>(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++;
index 9e46bf7c1e5c61ab7fba1edf20e6480dd58c9124..0ad1cb672109b9aa101ab497f3ea5c8cd41dd91e 100644 (file)
@@ -433,7 +433,8 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
         dc->d_tag = g_paddingTag;
       }
 
-      const struct dnsheader* dh = reinterpret_cast<const struct dnsheader*>(&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;