--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include <protozero/pbf_builder.hpp>
+#include <protozero/pbf_message.hpp>
+
+#include "iputils.hh"
+
+enum class PBComboAddress : protozero::pbf_tag_type
+{
+ required_uint32_port = 1,
+ required_bytes_address = 2, // family implicit
+};
+
+template <typename T>
+void encodeComboAddress(protozero::pbf_builder<T>& writer, T type, const ComboAddress& address)
+{
+ protozero::pbf_builder<PBComboAddress> message(writer, type);
+
+ // Skip all parts except address and port
+ message.add_uint32(PBComboAddress::required_uint32_port, address.getPort());
+ if (address.sin4.sin_family == AF_INET) {
+ message.add_bytes(PBComboAddress::required_bytes_address, reinterpret_cast<const char*>(&address.sin4.sin_addr.s_addr), sizeof(address.sin4.sin_addr.s_addr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
+ }
+ else if (address.sin4.sin_family == AF_INET6) {
+ message.add_bytes(PBComboAddress::required_bytes_address, reinterpret_cast<const char*>(&address.sin6.sin6_addr.s6_addr), sizeof(address.sin6.sin6_addr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
+ }
+}
+
+template <typename T>
+void decodeComboAddress(protozero::pbf_message<T>& reader, ComboAddress& address)
+{
+ address.reset();
+ protozero::pbf_message<PBComboAddress> message(reader.get_message());
+
+ // Skip all parts except address and port
+ if (message.next(PBComboAddress::required_uint32_port)) {
+ address.setPort(message.get_uint32());
+ }
+ else {
+ throw std::runtime_error("expected port in protobuf data");
+ }
+ constexpr auto inet4size = sizeof(address.sin4.sin_addr);
+ constexpr auto inet6size = sizeof(address.sin6.sin6_addr);
+ if (message.next(PBComboAddress::required_bytes_address)) {
+ auto data = message.get_bytes();
+ address.sin4.sin_family = data.size() == inet4size ? AF_INET : AF_INET6;
+ if (data.size() == inet4size) {
+ address.sin4.sin_family = AF_INET;
+ memcpy(&address.sin4.sin_addr, data.data(), data.size());
+ }
+ else if (data.size() == inet6size) {
+ address.sin6.sin6_family = AF_INET6;
+ memcpy(&address.sin6.sin6_addr, data.data(), data.size());
+ }
+ else {
+ throw std::runtime_error("unexpected address family in protobuf data");
+ }
+ }
+ else {
+ throw std::runtime_error("expected address bytes in protobuf data");
+ }
+}
+
+template <typename T>
+void encodeNetmask(protozero::pbf_builder<T>& writer, T type, const Netmask& subnet)
+{
+ if (!subnet.empty()) {
+ writer.add_bytes(type, reinterpret_cast<const char*>(&subnet), sizeof(Netmask)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
+ }
+}
+
+template <typename T>
+void decodeNetmask(protozero::pbf_message<T>& message, Netmask& subnet)
+{
+ auto data = message.get_bytes();
+ memcpy(&subnet, data.data(), data.size());
+}
+
#include "cachecleaner.hh"
#include "rec-taskqueue.hh"
#include "version.hh"
+#include "protozero-helpers.hh"
/*
* SERVE-STALE: the general approach
required_bool_tooBig = 16,
};
-enum class PBComboAddress : protozero::pbf_tag_type
-{
- required_uint32_port = 1,
- required_bytes_address = 2, // family implicit
-};
-
enum class PBAuthRecord : protozero::pbf_tag_type
{
required_bytes_name = 1,
required_uint32_clen = 7,
};
-template <typename T>
-static void encodeComboAddress(protozero::pbf_builder<T>& writer, T type, const ComboAddress& address)
-{
- protozero::pbf_builder<PBComboAddress> message(writer, type);
-
- // Skip all parts except address and port
- message.add_uint32(PBComboAddress::required_uint32_port, address.getPort());
- if (address.sin4.sin_family == AF_INET) {
- message.add_bytes(PBComboAddress::required_bytes_address, reinterpret_cast<const char*>(&address.sin4.sin_addr.s_addr), sizeof(address.sin4.sin_addr.s_addr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
- }
- else if (address.sin4.sin_family == AF_INET6) {
- message.add_bytes(PBComboAddress::required_bytes_address, reinterpret_cast<const char*>(&address.sin6.sin6_addr.s6_addr), sizeof(address.sin6.sin6_addr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
- }
-}
-
-template <typename T>
-static void decodeComboAddress(protozero::pbf_message<T>& reader, ComboAddress& address)
-{
- address.reset();
- protozero::pbf_message<PBComboAddress> message(reader.get_message());
-
- // Skip all parts except address and port
- if (message.next(PBComboAddress::required_uint32_port)) {
- address.setPort(message.get_uint32());
- }
- else {
- throw std::runtime_error("expected port in protobuf data");
- }
- constexpr auto inet4size = sizeof(address.sin4.sin_addr);
- constexpr auto inet6size = sizeof(address.sin6.sin6_addr);
- if (message.next(PBComboAddress::required_bytes_address)) {
- auto data = message.get_bytes();
- address.sin4.sin_family = data.size() == inet4size ? AF_INET : AF_INET6;
- if (data.size() == inet4size) {
- address.sin4.sin_family = AF_INET;
- memcpy(&address.sin4.sin_addr, data.data(), data.size());
- }
- else if (data.size() == inet6size) {
- address.sin6.sin6_family = AF_INET6;
- memcpy(&address.sin6.sin6_addr, data.data(), data.size());
- }
- else {
- throw std::runtime_error("unexpected address family in protobuf data");
- }
- }
- else {
- throw std::runtime_error("expected address bytes in protobuf data");
- }
-}
-
-template <typename T>
-static void encodeNetmask(protozero::pbf_builder<T>& writer, T type, const Netmask& subnet)
-{
- if (!subnet.empty()) {
- writer.add_bytes(type, reinterpret_cast<const char*>(&subnet), sizeof(Netmask)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): it's the API
- }
-}
-
-template <typename T>
-static void decodeNetmask(protozero::pbf_message<T>& message, Netmask& subnet)
-{
- auto data = message.get_bytes();
- memcpy(&subnet, data.data(), data.size());
-}
template <typename T, typename U>
void MemRecursorCache::getRecordSet(T& message, U recordSet)
#include "rec-taskqueue.hh"
#include "shuffle.hh"
+#include "version.hh"
+#include <protozero/pbf_builder.hpp>
+#include <protozero/pbf_message.hpp>
+#include "protozero-helpers.hh"
+
rec::GlobalCounters g_Counters;
thread_local rec::TCounters t_Counters(g_Counters);
ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; });
return ret;
}
+
+ enum class PBNSSpeedDump : protozero::pbf_tag_type
+ {
+ required_string_version = 1,
+ required_string_identity = 2,
+ required_uint64_protocolVersion = 3,
+ required_int64_time = 4,
+ required_string_type = 5,
+ repeated_message_nsspeedEntry = 6,
+ };
+
+ enum class PBNSSpeedEntry : protozero::pbf_tag_type
+ {
+ required_bytes_name = 1,
+ required_int64_lastgets = 2,
+ required_int64_lastgetus = 3,
+ repeated_message_map = 4,
+ };
+
+ enum class PBNSSpeedMap : protozero::pbf_tag_type
+ {
+ required_bytes_address = 1,
+ required_float_val = 2,
+ required_int32_last = 3,
+ };
+
+ template <typename T, typename U>
+ void getEntry(T& message, U entry)
+ {
+ message.add_bytes(PBNSSpeedEntry::required_bytes_name, entry->d_name.toString());
+ message.add_int64(PBNSSpeedEntry::required_int64_lastgets, entry->d_lastget.tv_sec);
+ message.add_int64(PBNSSpeedEntry::required_int64_lastgetus, entry->d_lastget.tv_usec);
+ for (const auto& [address, collection] : entry->d_collection) {
+ protozero::pbf_builder<PBNSSpeedMap> map(message, PBNSSpeedEntry::repeated_message_map);
+ encodeComboAddress(map, PBNSSpeedMap::required_bytes_address, address);
+ map.add_float(PBNSSpeedMap::required_float_val, collection.d_val);
+ map.add_int32(PBNSSpeedMap::required_int32_last, collection.d_last);
+ }
+ }
+
+ size_t getPB(std::string& ret)
+ {
+ protozero::pbf_builder<PBNSSpeedDump> full(ret);
+ full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion());
+ full.add_string(PBNSSpeedDump::required_string_identity, SyncRes::s_serverID);
+ full.add_uint64(PBNSSpeedDump::required_uint64_protocolVersion, 1);
+ full.add_int64(PBNSSpeedDump::required_int64_time, time(nullptr));
+ full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump");
+
+ size_t count = 0;
+ for (const auto& entry : *this) {
+ protozero::pbf_builder<PBNSSpeedEntry> message(full, PBNSSpeedDump::repeated_message_nsspeedEntry);
+ getEntry(message, &entry);
+ ++count;
+ }
+ return count;
+ }
+
};
static LockGuarded<nsspeeds_t> s_nsSpeeds;