Line data Source code
1 : // NOLINT(namespace-envoy) 2 : #pragma once 3 : 4 : // Note that this file is included in emscripten and NullVM environments and thus depends on 5 : // the context in which it is included, hence we need to disable clang-tidy warnings. 6 : 7 : extern "C" WasmResult envoy_resolve_dns(const char* dns_address, size_t dns_address_size, 8 : uint32_t* token); 9 : 10 : class EnvoyContextBase { 11 : public: 12 : virtual ~EnvoyContextBase() = default; 13 : }; 14 : 15 : class EnvoyRootContext : public RootContext, public EnvoyContextBase { 16 : public: 17 0 : EnvoyRootContext(uint32_t id, std::string_view root_id) : RootContext(id, root_id) {} 18 : ~EnvoyRootContext() override = default; 19 : 20 0 : virtual void onResolveDns(uint32_t /* token */, uint32_t /* result_size */) {} 21 0 : virtual void onStatsUpdate(uint32_t /* result_size */) {} 22 : }; 23 : 24 : class EnvoyContext : public Context, public EnvoyContextBase { 25 : public: 26 0 : EnvoyContext(uint32_t id, RootContext* root) : Context(id, root) {} 27 : ~EnvoyContext() override = default; 28 : }; 29 : 30 : struct DnsResult { 31 : uint32_t ttl_seconds; 32 : std::string address; 33 : }; 34 : 35 : struct CounterResult { 36 : uint64_t delta; 37 : std::string_view name; 38 : uint64_t value; 39 : }; 40 : 41 : struct GaugeResult { 42 : uint64_t value; 43 : std::string_view name; 44 : }; 45 : 46 : struct StatResult { 47 : std::vector<CounterResult> counters; 48 : std::vector<GaugeResult> gauges; 49 : }; 50 : 51 : enum class StatType : uint32_t { 52 : Counter = 1, 53 : Gauge = 2, 54 : }; 55 : 56 0 : inline std::vector<DnsResult> parseDnsResults(std::string_view data) { 57 0 : if (data.size() < 4) { 58 0 : return {}; 59 0 : } 60 0 : const uint32_t* pn = reinterpret_cast<const uint32_t*>(data.data()); 61 0 : uint32_t n = *pn++; 62 0 : std::vector<DnsResult> results; 63 0 : results.resize(n); 64 0 : const char* pa = data.data() + (1 + n) * sizeof(uint32_t); // skip n + n TTLs 65 0 : for (uint32_t i = 0; i < n; i++) { 66 0 : auto& e = results[i]; 67 0 : e.ttl_seconds = *pn++; 68 0 : auto alen = strlen(pa); 69 0 : e.address.assign(pa, alen); 70 0 : pa += alen + 1; 71 0 : } 72 0 : return results; 73 0 : } 74 : 75 0 : template <typename I> inline uint32_t align(uint32_t i) { 76 0 : return (i + sizeof(I) - 1) & ~(sizeof(I) - 1); 77 0 : } 78 : 79 0 : inline StatResult parseStatResults(std::string_view data) { 80 0 : StatResult results; 81 0 : uint32_t data_len = 0; 82 0 : while (data_len < data.length()) { 83 0 : const uint32_t* n = reinterpret_cast<const uint32_t*>(data.data() + data_len); 84 0 : uint32_t block_size = *n++; 85 0 : uint32_t block_type = *n++; 86 0 : uint32_t num_stats = *n++; 87 0 : if (static_cast<StatType>(block_type) == StatType::Counter) { // counter 88 0 : std::vector<CounterResult> counters(num_stats); 89 0 : uint32_t stat_index = data_len + 3 * sizeof(uint32_t); 90 0 : for (uint32_t i = 0; i < num_stats; i++) { 91 0 : const uint32_t* stat_name = reinterpret_cast<const uint32_t*>(data.data() + stat_index); 92 0 : uint32_t name_len = *stat_name; 93 0 : stat_index += sizeof(uint32_t); 94 0 : 95 0 : auto& e = counters[i]; 96 0 : e.name = {data.data() + stat_index, name_len}; 97 0 : stat_index = align<uint64_t>(stat_index + name_len); 98 0 : 99 0 : const uint64_t* stat_vals = reinterpret_cast<const uint64_t*>(data.data() + stat_index); 100 0 : e.value = *stat_vals++; 101 0 : e.delta = *stat_vals++; 102 0 : 103 0 : stat_index += 2 * sizeof(uint64_t); 104 0 : } 105 0 : results.counters = counters; 106 0 : } else if (static_cast<StatType>(block_type) == StatType::Gauge) { // gauge 107 0 : std::vector<GaugeResult> gauges(num_stats); 108 0 : uint32_t stat_index = data_len + 3 * sizeof(uint32_t); 109 0 : for (uint32_t i = 0; i < num_stats; i++) { 110 0 : const uint32_t* stat_name = reinterpret_cast<const uint32_t*>(data.data() + stat_index); 111 0 : uint32_t name_len = *stat_name; 112 0 : stat_index += sizeof(uint32_t); 113 0 : 114 0 : auto& e = gauges[i]; 115 0 : e.name = {data.data() + stat_index, name_len}; 116 0 : stat_index = align<uint64_t>(stat_index + name_len); 117 0 : 118 0 : const uint64_t* stat_vals = reinterpret_cast<const uint64_t*>(data.data() + stat_index); 119 0 : e.value = *stat_vals++; 120 0 : 121 0 : stat_index += sizeof(uint64_t); 122 0 : } 123 0 : results.gauges = gauges; 124 0 : } 125 0 : data_len += block_size; 126 0 : } 127 0 : 128 0 : return results; 129 0 : } 130 : 131 : extern "C" WasmResult envoy_resolve_dns(const char* address, size_t address_size, uint32_t* token);