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));
+ 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);
{
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);
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;
}
try {
- dnsheader* dh = (dnsheader*)&data[0];
+ const dnsheader_aligned headerdata(data.data());
+ const dnsheader* dh = headerdata.get();
if (dh->qr) {
g_stats.ignoredCount++;
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;