From: Otto Date: Tue, 6 Apr 2021 13:19:58 +0000 (+0200) Subject: Log client IP in dnstap messages X-Git-Tag: dnsdist-1.6.0-rc1~22^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82c0899caaf9b97a8bcec1b19d9387feec86c9e9;p=thirdparty%2Fpdns.git Log client IP in dnstap messages Also make sure we log only if we actually sent a message, i.e. we did not chain our request to an existing one. --- diff --git a/pdns/lwres.cc b/pdns/lwres.cc index 40da2f36c3..483efd42fc 100644 --- a/pdns/lwres.cc +++ b/pdns/lwres.cc @@ -72,8 +72,7 @@ static bool isEnabledForQueries(const std::shared_ptr>>& fstreamLoggers, const struct timeval &queryTime, const ComboAddress& ip, bool doTCP, - boost::optional auth, const vector& packet) +static void logFstreamQuery(const std::shared_ptr>>& fstreamLoggers, const struct timeval &queryTime, const ComboAddress& localip, const ComboAddress& ip, bool doTCP, boost::optional auth, const vector& packet) { if (fstreamLoggers == nullptr) return; @@ -81,7 +80,7 @@ static void logFstreamQuery(const std::shared_ptr(&*packet.begin()), packet.size(), &ts, nullptr, auth); + DnstapMessage message(str, DnstapMessage::MessageType::resolver_query, SyncRes::s_serverID, &localip, &ip, doTCP, reinterpret_cast(&*packet.begin()), packet.size(), &ts, nullptr, auth); for (auto& logger : *fstreamLoggers) { logger->queueData(str); @@ -101,8 +100,7 @@ static bool isEnabledForResponses(const std::shared_ptr>>& fstreamLoggers, const ComboAddress& ip, bool doTCP, - boost::optional auth, const std::string& packet, const struct timeval& queryTime, const struct timeval& replyTime) +static void logFstreamResponse(const std::shared_ptr>>& fstreamLoggers, const ComboAddress&localip, const ComboAddress& ip, bool doTCP, boost::optional auth, const std::string& packet, const struct timeval& queryTime, const struct timeval& replyTime) { if (fstreamLoggers == nullptr) return; @@ -111,7 +109,7 @@ static void logFstreamResponse(const std::shared_ptr(&*packet.begin()), packet.size(), &ts1, &ts2, auth); + DnstapMessage message(str, DnstapMessage::MessageType::resolver_response, SyncRes::s_serverID, &localip, &ip, doTCP, static_cast(&*packet.begin()), packet.size(), &ts1, &ts2, auth); for (auto& logger : *fstreamLoggers) { logger->queueData(str); @@ -293,13 +291,20 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int logOutgoingQuery(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, vpacket.size(), srcmask); } + srcmask = boost::none; // this is also our return value, even if EDNS0Level == 0 + + // We only store the localip if needed for fstrm logging + ComboAddress localip; + bool fstrmQEnabled = false; + bool fstrmREnabled = false; #ifdef HAVE_FSTRM if (isEnabledForQueries(fstrmLoggers)) { - logFstreamQuery(fstrmLoggers, queryTime, ip, doTCP, context ? context->d_auth : boost::none, vpacket); + fstrmQEnabled = true; } -#endif /* HAVE_FSTRM */ - - srcmask = boost::none; // this is also our return value, even if EDNS0Level == 0 + if (isEnabledForResponses(fstrmLoggers)) { + fstrmREnabled = true; + } +#endif if(!doTCP) { int queryfd; @@ -307,8 +312,7 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int g_stats.ipv6queries++; } - ret = asendto((const char*)&*vpacket.begin(), vpacket.size(), 0, ip, qid, - domain, type, &queryfd); + ret = asendto((const char*)&*vpacket.begin(), vpacket.size(), 0, ip, qid, domain, type, &queryfd); if (ret != LWResult::Result::Success) { return ret; @@ -318,9 +322,21 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int *chained = true; } +#ifdef HAVE_FSTRM + if (!*chained) { + if (fstrmQEnabled || fstrmREnabled) { + localip.sin4.sin_family = ip.sin4.sin_family; + socklen_t slen = ip.getSocklen(); + getsockname(queryfd, reinterpret_cast(&localip), &slen); + } + if (fstrmQEnabled) { + logFstreamQuery(fstrmLoggers, queryTime, localip, ip, doTCP, context ? context->d_auth : boost::none, vpacket); + } + } +#endif /* HAVE_FSTRM */ + // sleep until we see an answer to this, interface to mtasker - ret = arecvfrom(buf, 0, ip, &len, qid, - domain, type, queryfd, now); + ret = arecvfrom(buf, 0, ip, &len, qid, domain, type, queryfd, now); } else { try { @@ -336,8 +352,8 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int } } - ComboAddress local = pdns::getQueryLocalAddress(ip.sin4.sin_family, 0); - s.bind(local); + localip = pdns::getQueryLocalAddress(ip.sin4.sin_family, 0); + s.bind(localip); s.connect(ip); @@ -350,6 +366,12 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int return ret; } +#ifdef HAVE_FSTRM + if (fstrmQEnabled) { + logFstreamQuery(fstrmLoggers, queryTime, localip, ip, doTCP, context ? context->d_auth : boost::none, vpacket); + } +#endif /* HAVE_FSTRM */ + packet.clear(); ret = arecvtcp(packet, 2, &s, false); if (ret != LWResult::Result::Success) { @@ -374,7 +396,6 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int } } - lwr->d_usec=dt.udiff(); *now=dt.getTimeval(); @@ -388,8 +409,8 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int buf.resize(len); #ifdef HAVE_FSTRM - if (isEnabledForResponses(fstrmLoggers)) { - logFstreamResponse(fstrmLoggers, ip, doTCP, context ? context->d_auth : boost::none, buf, queryTime, *now); + if (fstrmREnabled && (!*chained || doTCP)) { + logFstreamResponse(fstrmLoggers, localip, ip, doTCP, context ? context->d_auth : boost::none, buf, queryTime, *now); } #endif /* HAVE_FSTRM */