* member `setRD(bool)`: set recursion desired flag
* member `setTC(bool)`: set truncation flag (TC)
* member `setQR(bool)`: set Query Response flag (setQR(true) indicates an *answer* packet)
+ * member `getCD()`: get checking disabled flag
+ * member `setCD(bool)`: set checking disabled flag
* NetmaskGroup related
* nothing yet
* QPSLimiter related:
unsigned arcount :16; /* number of resource entries */
};
+inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh)
+{
+ return (uint16_t*) (((char *) dh) + sizeof(uint16_t));
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define FLAGS_RD_OFFSET (8)
+#define FLAGS_CD_OFFSET (12)
+#elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+#define FLAGS_RD_OFFSET (0)
+#define FLAGS_CD_OFFSET (12)
+#endif
#define L theL()
extern time_t s_starttime;
return (bool)dh.rd;
});
+ g_lua.registerFunction<void(dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) {
+ dh.cd=v;
+ });
+
+ g_lua.registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) {
+ return (bool)dh.cd;
+ });
+
g_lua.registerFunction<void(dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) {
dh.tc=v;
uint16_t qlen, rlen;
string pool;
+ const uint16_t rdMask = 1 << FLAGS_RD_OFFSET;
+ const uint16_t cdMask = 1 << FLAGS_CD_OFFSET;
+ const uint16_t restoreFlagsMask = UINT16_MAX & ~(rdMask | cdMask);
shared_ptr<DownstreamState> ds;
if (!setNonBlocking(ci.fd))
DNSName qname(query, qlen, 12, false, &qtype);
string ruleresult;
struct dnsheader* dh =(dnsheader*)query;
+ const uint16_t * flags = getFlagsFromDNSHeader(dh);
+ uint16_t origFlags = *flags;
if(blockFilter) {
std::lock_guard<std::mutex> lock(g_luamutex);
char answerbuffer[rlen];
readn2WithTimeout(dsock, answerbuffer, rlen, ds->tcpRecvTimeout);
-
+ struct dnsheader* responseHeaders = (struct dnsheader*)answerbuffer;
+ uint16_t * responseFlags = getFlagsFromDNSHeader(responseHeaders);
+ /* clear the flags we are about to restore */
+ *responseFlags &= restoreFlagsMask;
+ /* only keep the flags we want to restore */
+ origFlags &= ~restoreFlagsMask;
+ /* set the saved flags as they were */
+ *responseFlags |= origFlags;
+
if (putNonBlockingMsgLen(ci.fd, rlen, ds->tcpSendTimeout))
writen2WithTimeout(ci.fd, answerbuffer, rlen, ds->tcpSendTimeout);
}
void* responderThread(std::shared_ptr<DownstreamState> state)
{
char packet[4096];
+ const uint16_t rdMask = 1 << FLAGS_RD_OFFSET;
+ const uint16_t cdMask = 1 << FLAGS_CD_OFFSET;
+ const uint16_t restoreFlagsMask = UINT16_MAX & ~(rdMask | cdMask);
struct dnsheader* dh = (struct dnsheader*)packet;
int len;
truncateTC(packet, (unsigned int*)&len);
}
+ uint16_t * flags = getFlagsFromDNSHeader(dh);
+ uint16_t origFlags = ids->origFlags;
+ /* clear the flags we are about to restore */
+ *flags &= restoreFlagsMask;
+ /* only keep the flags we want to restore */
+ origFlags &= ~restoreFlagsMask;
+ /* set the saved flags as they were */
+ *flags |= origFlags;
+
dh->id = ids->origID;
g_stats.responses++;
if(dh->qr) // don't respond to responses
continue;
+ const uint16_t * flags = getFlagsFromDNSHeader(dh);
+ const uint16_t origFlags = *flags;
DNSName qname(packet, len, 12, false, &qtype);
g_rings.queryRing.push_back(qname);
ids->qtype = qtype;
ids->origDest.sin4.sin_family=0;
ids->delayMsec = delayMsec;
+ ids->origFlags = origFlags;
HarvestDestinationAddress(&msgh, &ids->origDest);
dh->id = idOffset;
std::atomic<uint16_t> age; // 4
uint16_t qtype; // 2
uint16_t origID; // 2
+ uint16_t origFlags; // 2
int delayMsec;
};