});
luaCtx.registerFunction<std::string (DNSQuestion::*)()const>("getProtocol", [](const DNSQuestion& dq) {
- return dnsdist::ProtocolToString(dq.getProtocol());
+ return dq.getProtocol().toPrettyString();
});
luaCtx.registerFunction<void(DNSQuestion::*)(std::string)>("sendTrap", [](const DNSQuestion& dq, boost::optional<std::string> reason) {
});
luaCtx.registerFunction<std::string (DNSResponse::*)()const>("getProtocol", [](const DNSResponse& dr) {
- return dnsdist::ProtocolToString(dr.getProtocol());
+ return dr.getProtocol().toString();
});
luaCtx.registerFunction<void(DNSResponse::*)(std::string)>("sendTrap", [](const DNSResponse& dr, boost::optional<std::string> reason) {
std::multimap<struct timespec, string> out;
- boost::format fmt("%-7.1f %-47s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
- g_outputBuffer+= (fmt % "Time" % "Client" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
+ g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
if(msec==-1) {
for(const auto& c : qr) {
if (c.dh.opcode != 0) {
extra = " (" + Opcode::to_s(c.dh.opcode) + ")";
}
- out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % ("Question" + extra)).str() )) ;
+ out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % ("Question" + extra)).str() )) ;
if(limit && *limit==++num)
break;
}
if (c.usec != std::numeric_limits<decltype(c.usec)>::max()) {
- out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec/1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ;
+ out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec/1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ;
}
else {
- out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ;
+ out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ;
}
if (limit && *limit == ++num) {
namespace dnsdist
{
-enum class Protocol : uint8_t
+class Protocol
{
- DoUDP,
- DoTCP,
- DNSCryptUDP,
- DNSCryptTCP,
- DoT,
- DoH
-};
+public:
+ Protocol(uint8_t protocol = 0);
+ Protocol& operator=(const char*);
+ Protocol& operator=(const std::string&);
+ operator uint8_t() const;
+ const std::string& toString() const;
+ const std::string& toPrettyString() const;
+
+ enum typeenum : uint8_t
+ {
+ DoUDP,
+ DoTCP,
+ DNSCryptUDP,
+ DNSCryptTCP,
+ DoT,
+ DoH
+ };
-const std::string& ProtocolToString(Protocol proto);
+private:
+ static uint8_t fromString(const std::string& s);
+ uint8_t d_protocol;
+};
}
vector<string> parts;
stringtok(parts, line, " \t,");
- if (parts.size() == 7) {
+ if (parts.size() == 8) {
}
- else if (parts.size() >= 10 && parts.size() <= 12) {
+ else if (parts.size() >= 11 && parts.size() <= 13) {
isResponse = true;
}
else {
ComboAddress from(parts.at(idx++));
ComboAddress to;
+ dnsdist::Protocol protocol;
+ protocol = parts.at(idx++);
if (isResponse) {
to = ComboAddress(parts.at(idx++));
}
QType qtype(QType::chartocode(parts.at(idx++).c_str()));
if (isResponse) {
- insertResponse(when, from, qname, qtype.getCode(), 0, 0, dh, to);
+ insertResponse(when, from, qname, qtype.getCode(), 0, 0, dh, to, protocol);
}
else {
- insertQuery(when, from, qname, qtype.getCode(), 0, dh);
+ insertQuery(when, from, qname, qtype.getCode(), 0, dh, protocol);
}
++inserted;
}
#include "iputils.hh"
#include "lock.hh"
#include "stat_t.hh"
-
+#include "dnsdist-protocols.hh"
struct Rings {
struct Query
struct dnsheader dh;
uint16_t size;
uint16_t qtype;
+ // incoming protocol
+ uint8_t protocol;
};
struct Response
{
unsigned int usec;
unsigned int size;
uint16_t qtype;
+ // outgoing protocol
+ uint8_t protocol;
};
struct Shard
return d_nbResponseEntries;
}
- void insertQuery(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh)
+ void insertQuery(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh, uint8_t protocol)
{
for (size_t idx = 0; idx < d_nbLockTries; idx++) {
auto& shard = getOneShard();
auto lock = shard->queryRing.try_lock();
if (lock.owns_lock()) {
- insertQueryLocked(*lock, when, requestor, name, qtype, size, dh);
+ insertQueryLocked(*lock, when, requestor, name, qtype, size, dh, protocol);
return;
}
if (d_keepLockingStats) {
}
auto& shard = getOneShard();
auto lock = shard->queryRing.lock();
- insertQueryLocked(*lock, when, requestor, name, qtype, size, dh);
+ insertQueryLocked(*lock, when, requestor, name, qtype, size, dh, protocol);
}
- void insertResponse(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend)
+ void insertResponse(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend, uint8_t protocol)
{
for (size_t idx = 0; idx < d_nbLockTries; idx++) {
auto& shard = getOneShard();
auto lock = shard->respRing.try_lock();
if (lock.owns_lock()) {
- insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend);
+ insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend, protocol);
return;
}
if (d_keepLockingStats) {
}
auto& shard = getOneShard();
auto lock = shard->respRing.lock();
- insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend);
+ insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend, protocol);
}
void clear()
return d_shards[getShardId()];
}
- void insertQueryLocked(boost::circular_buffer<Query>& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh)
+ void insertQueryLocked(boost::circular_buffer<Query>& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh, uint8_t protocol)
{
if (!ring.full()) {
d_nbQueryEntries++;
}
- ring.push_back({requestor, name, when, dh, size, qtype});
+ ring.push_back({requestor, name, when, dh, size, qtype, protocol});
}
- void insertResponseLocked(boost::circular_buffer<Response>& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend)
+ void insertResponseLocked(boost::circular_buffer<Response>& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend, uint8_t protocol)
{
if (!ring.full()) {
d_nbResponseEntries++;
}
- ring.push_back({requestor, backend, name, when, dh, usec, size, qtype});
+ ring.push_back({requestor, backend, name, when, dh, usec, size, qtype, protocol});
}
std::atomic<size_t> d_nbQueryEntries;
double udiff = ids.sentTime.udiff();
vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff);
- ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->remote, static_cast<unsigned int>(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH);
+ ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->remote, static_cast<unsigned int>(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ds->getProtocol());
updateTCPLatency(ds, udiff);
}
(*state->mplexer.lock())->getAvailableFDs(ready, 1000);
}
-void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH)
+void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol)
{
struct timespec ts;
gettime(&ts);
- g_rings.insertResponse(ts, client, ids.qname, ids.qtype, static_cast<unsigned int>(udiff), size, cleartextDH, backend);
+ g_rings.insertResponse(ts, client, ids.qname, ids.qtype, static_cast<unsigned int>(udiff), size, cleartextDH, backend, protocol);
switch (cleartextDH.rcode) {
case RCode::NXDomain:
double udiff = ids->sentTime.udiff();
vinfolog("Got answer from %s, relayed to %s, took %f usec", dss->remote.toStringWithPort(), ids->origRemote.toStringWithPort(), udiff);
- handleResponseSent(*ids, udiff, *dr.remote, dss->remote, static_cast<unsigned int>(got), cleartextDH);
+ handleResponseSent(*ids, udiff, *dr.remote, dss->remote, static_cast<unsigned int>(got), cleartextDH, dss->getProtocol());
dss->latencyUsec = (127.0 * dss->latencyUsec / 128.0) + udiff/128.0;
static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const struct timespec& now)
{
- g_rings.insertQuery(now, *dq.remote, *dq.qname, dq.qtype, dq.getData().size(), *dq.getHeader());
+ g_rings.insertQuery(now, *dq.remote, *dq.qname, dq.qtype, dq.getData().size(), *dq.getHeader(), dq.getProtocol());
if (g_qcount.enabled) {
string qname = (*dq.qname).toLogString();
double udiff = ids.sentTime.udiff();
vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", d_ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
- handleResponseSent(ids, udiff, *dr.remote, d_ds->remote, response.d_buffer.size(), cleartextDH);
+ handleResponseSent(ids, udiff, *dr.remote, d_ds->remote, response.d_buffer.size(), cleartextDH, d_ds->getProtocol());
d_ds->latencyUsec = (127.0 * d_ds->latencyUsec / 128.0) + udiff/128.0;
memset(&fake, 0, sizeof(fake));
fake.id = ids.origID;
- g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits<unsigned int>::max(), 0, fake, dss->remote);
+ g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits<unsigned int>::max(), 0, fake, dss->remote, dss->getProtocol());
}
}
}
}
bool passCrossProtocolQuery(std::unique_ptr<CrossProtocolQuery>&& cpq);
-
+ dnsdist::Protocol getProtocol() const
+ {
+ if (isDoH()) {
+ return dnsdist::Protocol::DoH;
+ }
+ if (d_tlsCtx != nullptr) {
+ return dnsdist::Protocol::DoT;
+ }
+ if (isTCPOnly()) {
+ return dnsdist::Protocol::DoTCP;
+ }
+ return dnsdist::Protocol::DoUDP;
+ }
private:
std::string name;
std::string nameWithAddr;
int pickBackendSocketForSending(std::shared_ptr<DownstreamState>& state);
ssize_t udpClientSendRequestToBackend(const std::shared_ptr<DownstreamState>& ss, const int sd, const PacketBuffer& request, bool healthCheck = false);
-void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH);
+void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol);
void carbonDumpThread();
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+
+#include <algorithm>
+
#include "dnsdist-protocols.hh"
namespace dnsdist
{
-const std::string& ProtocolToString(Protocol proto)
+static const std::vector<std::string> names = {
+ "DoUDP",
+ "DoTCP",
+ "DNSCryptUDP",
+ "DNSCryptTCP",
+ "DoT",
+ "DoH"};
+
+static const std::vector<std::string> prettyNames = {
+ "Do53 UDP",
+ "Do53 TCP",
+ "DNSCrypt UDP",
+ "DNSCrypt TCP",
+ "DNS over TLS",
+ "DNS over HTTPS"};
+
+Protocol::Protocol(uint8_t protocol) :
+ d_protocol(protocol)
+{
+}
+Protocol& Protocol::operator=(const char* s)
{
- static const std::vector<std::string> values = {"Do53 UDP", "Do53 TCP", "DNSCrypt UDP", "DNSCrypt TCP", "DNS over TLS", "DNS over HTTPS"};
- return values.at(static_cast<int>(proto));
+ std::string str(s);
+ d_protocol = Protocol::fromString(str);
+
+ return *this;
+}
+Protocol& Protocol::operator=(const std::string& s)
+{
+ d_protocol = Protocol::fromString(s);
+
+ return *this;
+}
+Protocol::operator uint8_t() const
+{
+ return d_protocol;
+}
+const std::string& Protocol::toString() const
+{
+ return names.at(static_cast<int>(d_protocol));
+}
+const std::string& Protocol::toPrettyString() const
+{
+ return prettyNames.at(static_cast<int>(d_protocol));
+}
+uint8_t Protocol::fromString(const std::string& s)
+{
+ const auto& it = std::find(names.begin(), names.end(), s);
+ if (it != names.end()) {
+ return std::distance(names.begin(), it);
+ }
+
+ return 0;
}
}
double udiff = du->ids.sentTime.udiff();
vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff);
- handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH);
+ handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH, du->downstream->getProtocol());
++g_stats.responses;
if (du->ids.cs) {
double udiff = ids.sentTime.udiff();
vinfolog("Got answer from %s, relayed to %s (https), took %f usec", downstream->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
- handleResponseSent(ids, udiff, *dr.remote, downstream->remote, response.size(), cleartextDH);
+ handleResponseSent(ids, udiff, *dr.remote, downstream->remote, response.size(), cleartextDH, downstream->getProtocol());
++g_stats.responses;
if (ids.cs) {
ComboAddress backend("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
unsigned int responseTime = 0;
struct timespec now;
gettime(&now);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
/* we do not care about the response during that test, but we want to make sure
these do not interfere with the computation */
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfQueries);
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
struct timespec when = now;
when.tv_sec -= (9 - timeIdx);
- g_rings.insertQuery(when, requestor1, qname, qtype, size, dh);
- g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertQuery(when, requestor1, qname, qtype, size, dh, protocol);
+ g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries * numberOfSeconds);
ComboAddress backend("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
unsigned int responseTime = 0;
struct timespec now;
gettime(&now);
struct timespec when = now;
when.tv_sec -= (99 - timeIdx);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(when, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(when, requestor1, qname, qtype, size, dh, protocol);
/* we do not care about the response during that test, but we want to make sure
these do not interfere with the computation */
- g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfQueries * 100);
ComboAddress requestor2("192.0.2.2");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
struct timespec now;
gettime(&now);
NetmaskTree<DynBlock> emptyNMG;
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, QType::A, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, QType::A, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
ComboAddress backend("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
unsigned int responseTime = 100 * 1000; /* 100ms */
struct timespec now;
gettime(&now);
dh.rcode = rcode;
for (size_t idx = 0; idx < numberOfResponses; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses);
dh.rcode = RCode::FormErr;
for (size_t idx = 0; idx < numberOfResponses; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses);
dh.rcode = rcode;
for (size_t idx = 0; idx < numberOfResponses; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses);
ComboAddress backend("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
unsigned int responseTime = 100 * 1000; /* 100ms */
struct timespec now;
gettime(&now);
dh.rcode = rcode;
for (size_t idx = 0; idx < 20; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
dh.rcode = RCode::NoError;
for (size_t idx = 0; idx < 80; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 100U);
dh.rcode = RCode::FormErr;
for (size_t idx = 0; idx < 50; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 50U);
dh.rcode = rcode;
for (size_t idx = 0; idx < 21; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
dh.rcode = RCode::NoError;
for (size_t idx = 0; idx < 79; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 100U);
dh.rcode = rcode;
for (size_t idx = 0; idx < 11; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
dh.rcode = RCode::NoError;
for (size_t idx = 0; idx < 39; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 50U);
ComboAddress backend("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 100;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
unsigned int responseTime = 100 * 1000; /* 100ms */
struct timespec now;
gettime(&now);
dh.rcode = rcode;
for (size_t idx = 0; idx < numberOfResponses; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses);
dh.rcode = rcode;
for (size_t idx = 0; idx < numberOfResponses; idx++) {
- g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend);
+ g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses);
ComboAddress requestor2("192.0.2.2");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
struct timespec now;
gettime(&now);
NetmaskTree<DynBlock> emptyNMG;
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), 0U);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), 0U);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries);
ComboAddress requestor2("192.0.2.42");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
struct timespec now;
gettime(&now);
NetmaskTree<DynBlock> emptyNMG;
g_dynblockNMG.setState(emptyNMG);
for (size_t idx = 0; idx < numberOfQueries; idx++) {
- g_rings.insertQuery(now, requestor1, qname, qtype, size, dh);
- g_rings.insertQuery(now, requestor2, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
+ g_rings.insertQuery(now, requestor2, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries * 2);
DNSName qname("rings.powerdns.com.");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
struct timespec now;
gettime(&now);
NetmaskTree<DynBlock> emptyNMG;
*/
for (size_t idx = 0; idx < 256; idx++) {
const ComboAddress requestor("192.0.2." + std::to_string(idx));
- g_rings.insertQuery(now, requestor, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor, qname, qtype, size, dh, protocol);
}
/* we apply the rules, all clients should be blocked */
/* insert one fake response for 255 DNS names */
const ComboAddress requestor("192.0.2.1");
for (size_t idx = 0; idx < 256; idx++) {
- g_rings.insertResponse(now, requestor, DNSName(std::to_string(idx)) + qname, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */);
+ g_rings.insertResponse(now, requestor, DNSName(std::to_string(idx)) + qname, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */, outgoingProtocol);
}
/* we apply the rules, all suffixes should be blocked */
for (size_t idxC = 0; !done && idxC < 256; idxC++) {
for (size_t idxD = 0; !done && idxD < 256; idxD++) {
const DNSName victim(std::to_string(idxB) + "." + std::to_string(idxC) + "." + std::to_string(idxD) + qname.toString());
- g_rings.insertResponse(now, requestor, victim, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */);
+ g_rings.insertResponse(now, requestor, victim, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */, outgoingProtocol);
if (g_rings.getNumberOfQueryEntries() == 1000000) {
done = true;
break;
for (size_t idxC = 0; !done && idxC < 256; idxC++) {
for (size_t idxD = 0; !done && idxD < 256; idxD++) {
const ComboAddress requestor("192." + std::to_string(idxB) + "." + std::to_string(idxC) + "." + std::to_string(idxD));
- g_rings.insertQuery(now, requestor, qname, qtype, size, dh);
+ g_rings.insertQuery(now, requestor, qname, qtype, size, dh, protocol);
if (g_rings.getNumberOfQueryEntries() == 1000000) {
done = true;
break;
ComboAddress requestor2("192.0.2.2");
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
struct timespec now;
gettime(&now);
/* fill the query ring */
for (size_t idx = 0; idx < maxEntries; idx++) {
- rings.insertQuery(now, requestor1, qname, qtype, size, dh);
+ rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries);
BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), 0U);
/* push enough queries to get rid of the existing ones */
for (size_t idx = 0; idx < maxEntries; idx++) {
- rings.insertQuery(now, requestor2, qname, qtype, size, dh);
+ rings.insertQuery(now, requestor2, qname, qtype, size, dh, protocol);
}
BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries);
BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), 0U);
/* fill the response ring */
for (size_t idx = 0; idx < maxEntries; idx++) {
- rings.insertResponse(now, requestor1, qname, qtype, latency, size, dh, server);
+ rings.insertResponse(now, requestor1, qname, qtype, latency, size, dh, server, outgoingProtocol);
}
BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries);
BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), maxEntries);
/* push enough responses to get rid of the existing ones */
for (size_t idx = 0; idx < maxEntries; idx++) {
- rings.insertResponse(now, requestor2, qname, qtype, latency, size, dh, server);
+ rings.insertResponse(now, requestor2, qname, qtype, latency, size, dh, server, outgoingProtocol);
}
BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries);
BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), maxEntries);
static void ringWriterThread(Rings& rings, size_t numberOfEntries, const Rings::Query& query, const Rings::Response& response)
{
for (size_t idx = 0; idx < numberOfEntries; idx++) {
- rings.insertQuery(query.when, query.requestor, query.name, query.qtype, query.size, query.dh);
- rings.insertResponse(response.when, response.requestor, response.name, response.qtype, response.usec, response.size, response.dh, response.ds);
+ rings.insertQuery(query.when, query.requestor, query.name, query.qtype, query.size, query.dh, query.protocol);
+ rings.insertResponse(response.when, response.requestor, response.name, response.qtype, response.usec, response.size, response.dh, response.ds, response.protocol);
}
}
unsigned int latency = 100;
uint16_t qtype = QType::AAAA;
uint16_t size = 42;
+ uint8_t protocol = dnsdist::Protocol::DoUDP;
+ uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP;
Rings rings(numberOfEntries, numberOfShards, lockAttempts, true);
- Rings::Query query({requestor, qname, now, dh, size, qtype});
- Rings::Response response({requestor, server, qname, now, dh, latency, size, qtype});
+ Rings::Query query({requestor, qname, now, dh, size, qtype, protocol});
+ Rings::Response response({requestor, server, qname, now, dh, latency, size, qtype, outgoingProtocol});
std::atomic<bool> done(false);
std::vector<std::thread> writerThreads;
return 0;
}
-void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH)
+void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol)
{
}