|
20 | 20 |
|
21 | 21 | namespace visor::handler::dns { |
22 | 22 |
|
| 23 | +thread_local DnsStreamHandler::DnsCacheData DnsStreamHandler::_cached_dns_layer; |
| 24 | + |
23 | 25 | DnsStreamHandler::DnsStreamHandler(const std::string &name, InputStream *stream, const Configurable *window_config, StreamHandler *handler) |
24 | 26 | : visor::StreamMetricsHandler<DnsMetricsManager>(name, window_config) |
25 | 27 | { |
@@ -161,9 +163,14 @@ void DnsStreamHandler::process_udp_packet_cb(pcpp::Packet &payload, PacketDirect |
161 | 163 | metric_port = dst_port; |
162 | 164 | } |
163 | 165 | if (metric_port) { |
164 | | - DnsLayer dnsLayer(udpLayer, &payload); |
165 | | - if (!_filtering(dnsLayer, dir, l3, pcpp::UDP, metric_port, stamp)) { |
166 | | - _metrics->process_dns_layer(dnsLayer, dir, l3, pcpp::UDP, flowkey, metric_port, _static_suffix_size, stamp); |
| 166 | + if (flowkey != _cached_dns_layer.flowKey || stamp.tv_sec != _cached_dns_layer.timestamp.tv_sec || stamp.tv_nsec != _cached_dns_layer.timestamp.tv_nsec) { |
| 167 | + _cached_dns_layer.flowKey = flowkey; |
| 168 | + _cached_dns_layer.timestamp = stamp; |
| 169 | + _cached_dns_layer.dnsLayer = std::make_unique<DnsLayer>(udpLayer, &payload); |
| 170 | + } |
| 171 | + auto dnsLayer = _cached_dns_layer.dnsLayer.get(); |
| 172 | + if (!_filtering(*dnsLayer, dir, l3, pcpp::UDP, metric_port, stamp)) { |
| 173 | + _metrics->process_dns_layer(*dnsLayer, dir, l3, pcpp::UDP, flowkey, metric_port, _static_suffix_size, stamp); |
167 | 174 | _static_suffix_size = 0; |
168 | 175 | // signal for chained stream handlers, if we have any |
169 | 176 | udp_signal(payload, dir, l3, flowkey, stamp); |
@@ -317,10 +324,7 @@ bool DnsStreamHandler::_filtering(DnsLayer &payload, [[maybe_unused]] PacketDire |
317 | 324 | if (!payload.parseResources(true) || payload.getFirstQuery() == nullptr) { |
318 | 325 | goto will_filter; |
319 | 326 | } |
320 | | - // we need an all lower case version of this, we can't get away without making a copy |
321 | | - std::string qname_ci{payload.getFirstQuery()->getName()}; |
322 | | - std::transform(qname_ci.begin(), qname_ci.end(), qname_ci.begin(), |
323 | | - [](unsigned char c) { return std::tolower(c); }); |
| 327 | + std::string_view qname_ci = payload.getFirstQuery()->getNameLower(); |
324 | 328 | for (const auto &fqn : _f_qnames) { |
325 | 329 | // if it matched, we know we are not filtering |
326 | 330 | if (endsWith(qname_ci, fqn)) { |
@@ -604,9 +608,7 @@ void DnsMetricsBucket::process_dns_layer(bool deep, DnsLayer &payload, pcpp::Pro |
604 | 608 | auto query = payload.getFirstQuery(); |
605 | 609 | if (query) { |
606 | 610 |
|
607 | | - auto name = query->getName(); |
608 | | - std::transform(name.begin(), name.end(), name.begin(), |
609 | | - [](unsigned char c) { return std::tolower(c); }); |
| 611 | + auto name = query->getNameLower(); |
610 | 612 |
|
611 | 613 | if (group_enabled(group::DnsMetrics::Cardinality)) { |
612 | 614 | _dns_qnameCard.update(name); |
|
0 commit comments