int matches=0;
ComboAddress dummy("127.0.0.1");
- DTime dt;
- dt.set();
+ StopWatch sw;
+ sw.start();
for(int n=0; n < times; ++n) {
const item& i = items[n % items.size()];
- DNSQuestion dq(&i.qname, i.qtype, i.qclass, &i.rem, &i.rem, (struct dnsheader*)&i.packet[0], i.packet.size(), i.packet.size(), false);
+ DNSQuestion dq(&i.qname, i.qtype, i.qclass, &i.rem, &i.rem, (struct dnsheader*)&i.packet[0], i.packet.size(), i.packet.size(), false, &sw.d_start);
if(rule->matches(&dq))
matches++;
}
- double udiff=dt.udiff();
+ double udiff=sw.udiff();
g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f usec\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str();
});
DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSQuestion& dq): DNSProtoBufMessage(Query, dq.uniqueId ? *dq.uniqueId : t_uuidGenerator(), dq.remote, dq.local, *dq.qname, dq.qtype, dq.qclass, dq.dh->id, dq.tcp, dq.len)
{
+ setQueryTime(dq.queryTime->tv_sec, dq.queryTime->tv_nsec / 1000);
};
DNSDistProtoBufMessage::DNSDistProtoBufMessage(const DNSResponse& dr, bool includeCNAME): DNSProtoBufMessage(Response, dr.uniqueId ? *dr.uniqueId : t_uuidGenerator(), dr.remote, dr.local, *dr.qname, dr.qtype, dr.qclass, dr.dh->id, dr.tcp, dr.len)
goto drop;
}
- const uint16_t* flags = getFlagsFromDNSHeader(dh);
- uint16_t origFlags = *flags;
- uint16_t qtype, qclass;
- unsigned int consumed = 0;
- DNSName qname(query, qlen, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
- DNSQuestion dq(&qname, qtype, qclass, &dest, &ci.remote, dh, queryBuffer.capacity(), qlen, true);
-
string poolname;
int delayMsec=0;
/* we need this one to be accurate ("real") for the protobuf message */
gettime(&now);
gettime(&queryRealTime, true);
+ const uint16_t* flags = getFlagsFromDNSHeader(dh);
+ uint16_t origFlags = *flags;
+ uint16_t qtype, qclass;
+ unsigned int consumed = 0;
+ DNSName qname(query, qlen, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
+ DNSQuestion dq(&qname, qtype, qclass, &dest, &ci.remote, dh, queryBuffer.capacity(), qlen, true, &queryRealTime);
+
if (!processQuery(holders, dq, poolname, &delayMsec, now)) {
goto drop;
}
return;
}
- const uint16_t * flags = getFlagsFromDNSHeader(dh);
- const uint16_t origFlags = *flags;
- uint16_t qtype, qclass;
- unsigned int consumed = 0;
- DNSName qname(query, len, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
- DNSQuestion dq(&qname, qtype, qclass, dest.sin4.sin_family != 0 ? &dest : &cs.local, &remote, dh, queryBufferSize, len, false);
-
string poolname;
int delayMsec = 0;
/* we need an accurate ("real") value for the response and
to store into the IDS, but not for insertion into the
rings for example */
- struct timespec realTime;
+ struct timespec queryRealTime;
struct timespec now;
gettime(&now);
- gettime(&realTime, true);
+ gettime(&queryRealTime, true);
+
+ const uint16_t * flags = getFlagsFromDNSHeader(dh);
+ const uint16_t origFlags = *flags;
+ uint16_t qtype, qclass;
+ unsigned int consumed = 0;
+ DNSName qname(query, len, sizeof(dnsheader), false, &qtype, &qclass, &consumed);
+ DNSQuestion dq(&qname, qtype, qclass, dest.sin4.sin_family != 0 ? &dest : &cs.local, &remote, dh, queryBufferSize, len, false, &queryRealTime);
if (!processQuery(holders, dq, poolname, &delayMsec, now))
{
char* response = query;
uint16_t responseLen = dq.len;
- DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(response), dq.size, responseLen, false, &realTime);
+ DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(response), dq.size, responseLen, false, &queryRealTime);
#ifdef HAVE_PROTOBUF
dr.uniqueId = dq.uniqueId;
#endif
uint16_t cachedResponseSize = dq.size;
uint32_t allowExpired = ss ? 0 : g_staleCacheEntriesTTL;
if (packetCache->get(dq, consumed, dh->id, query, &cachedResponseSize, &cacheKey, allowExpired)) {
- DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(query), dq.size, cachedResponseSize, false, &realTime);
+ DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(query), dq.size, cachedResponseSize, false, &queryRealTime);
#ifdef HAVE_PROTOBUF
dr.uniqueId = dq.uniqueId;
#endif
dq.dh->rcode = RCode::ServFail;
dq.dh->qr = true;
- DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(response), dq.size, responseLen, false, &realTime);
+ DNSResponse dr(dq.qname, dq.qtype, dq.qclass, dq.local, dq.remote, reinterpret_cast<dnsheader*>(response), dq.size, responseLen, false, &queryRealTime);
#ifdef HAVE_PROTOBUF
dr.uniqueId = dq.uniqueId;
#endif
ids->origFD = cs.udpFD;
ids->origID = dh->id;
ids->origRemote = remote;
- ids->sentTime.set(realTime);
+ ids->sentTime.set(queryRealTime);
ids->qname = qname;
ids->qtype = dq.qtype;
ids->qclass = dq.qclass;
struct DNSQuestion
{
- DNSQuestion(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, struct dnsheader* header, size_t bufferSize, uint16_t queryLen, bool isTcp): qname(name), qtype(type), qclass(class_), local(lc), remote(rem), dh(header), size(bufferSize), len(queryLen), ecsPrefixLength(rem->sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), tempFailureTTL(boost::none), tcp(isTcp), ecsOverride(g_ECSOverride) { }
+ DNSQuestion(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, struct dnsheader* header, size_t bufferSize, uint16_t queryLen, bool isTcp, const struct timespec* queryTime_):
+ qname(name), qtype(type), qclass(class_), local(lc), remote(rem), dh(header), size(bufferSize), len(queryLen), ecsPrefixLength(rem->sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), tempFailureTTL(boost::none), tcp(isTcp), queryTime(queryTime_), ecsOverride(g_ECSOverride) { }
#ifdef HAVE_PROTOBUF
boost::optional<boost::uuids::uuid> uniqueId;
uint16_t ecsPrefixLength;
boost::optional<uint32_t> tempFailureTTL;
const bool tcp;
+ const struct timespec* queryTime;
bool skipCache{false};
bool ecsOverride;
bool useECS{true};
struct DNSResponse : DNSQuestion
{
- DNSResponse(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, struct dnsheader* header, size_t bufferSize, uint16_t responseLen, bool isTcp, const struct timespec* queryTime_): DNSQuestion(name, type, class_, lc, rem, header, bufferSize, responseLen, isTcp), queryTime(queryTime_) { }
-
- const struct timespec* queryTime;
+ DNSResponse(const DNSName* name, uint16_t type, uint16_t class_, const ComboAddress* lc, const ComboAddress* rem, struct dnsheader* header, size_t bufferSize, uint16_t responseLen, bool isTcp, const struct timespec* queryTime_):
+ DNSQuestion(name, type, class_, lc, rem, header, bufferSize, responseLen, isTcp, queryTime_) { }
};
/* so what could you do:
#include "iputils.hh"
#include "dnswriter.hh"
#include "dnsdist-cache.hh"
+#include "gettime.hh"
BOOST_AUTO_TEST_SUITE(dnsdistpacketcache_cc)
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
BOOST_CHECK_EQUAL(PC.getSize(), 0);
+ struct timespec queryTime;
+ gettime(&queryTime); // does not have to be accurate ("realTime") in tests
size_t counter=0;
size_t skipped=0;
char responseBuf[4096];
uint16_t responseBufSize = sizeof(responseBuf);
uint32_t key = 0;
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false, &queryTime);
bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key);
BOOST_CHECK_EQUAL(found, false);
char responseBuf[4096];
uint16_t responseBufSize = sizeof(responseBuf);
uint32_t key = 0;
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false, &queryTime);
bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key);
if (found == true) {
PC.expungeByName(a);
uint32_t key = 0;
char response[4096];
uint16_t responseSize = sizeof(response);
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), len, query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), len, query.size(), false, &queryTime);
if(PC.get(dq, a.wirelength(), pwQ.getHeader()->id, response, &responseSize, &key)) {
matches++;
}
BOOST_AUTO_TEST_CASE(test_PacketCacheServFailTTL) {
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
+ struct timespec queryTime;
+ gettime(&queryTime); // does not have to be accurate ("realTime") in tests
ComboAddress remote;
try {
char responseBuf[4096];
uint16_t responseBufSize = sizeof(responseBuf);
uint32_t key = 0;
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false, &queryTime);
bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key);
BOOST_CHECK_EQUAL(found, false);
static void *threadMangler(void* off)
{
+ struct timespec queryTime;
+ gettime(&queryTime); // does not have to be accurate ("realTime") in tests
try {
ComboAddress remote;
unsigned int offset=(unsigned int)(unsigned long)off;
char responseBuf[4096];
uint16_t responseBufSize = sizeof(responseBuf);
uint32_t key = 0;
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false, &queryTime);
PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key);
PC.insert(key, a, QType::A, QClass::IN, (const char*) response.data(), responseLen, false, 0, boost::none);
static void *threadReader(void* off)
{
+ struct timespec queryTime;
+ gettime(&queryTime); // does not have to be accurate ("realTime") in tests
try
{
unsigned int offset=(unsigned int)(unsigned long)off;
char responseBuf[4096];
uint16_t responseBufSize = sizeof(responseBuf);
uint32_t key = 0;
- DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false);
+ DNSQuestion dq(&a, QType::A, QClass::IN, &remote, &remote, (struct dnsheader*) query.data(), query.size(), query.size(), false, &queryTime);
bool found = PC.get(dq, a.wirelength(), 0, responseBuf, &responseBufSize, &key);
if (!found) {
g_missing++;