• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 25191990251

29 Apr 2026 04:54PM UTC coverage: 57.956% (-13.1%) from 71.038%
25191990251

push

github

web-flow
Merge pull request #17257 from omoerbeek/dnsdist-test-signedness

dnsdist: fix a few signed vs unsigned compare warnings in tests

65689 of 176110 branches covered (37.3%)

Branch coverage included in aggregate %.

140865 of 180289 relevant lines covered (78.13%)

5404297.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.23
/modules/lua2backend/lua2api2.hh
1
/*
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTAPILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
#pragma once
23
#include "boost/algorithm/string/join.hpp"
24
#include "pdns/arguments.hh"
25

26
#include "pdns/dnsbackend.hh"
27
#include "pdns/lua-auth4.hh"
28

29
class Lua2BackendAPIv2 : public DNSBackend, AuthLua4
30
{
31
private:
32
  typedef std::function<void()> init_call_t;
33
  typedef std::function<void()> deinit_call_t;
34

35
  typedef std::vector<std::pair<string, string>> lookup_context_t;
36

37
  typedef std::vector<std::pair<int, std::vector<std::pair<string, boost::variant<bool, int, DNSName, string, QType>>>>> lookup_result_t;
38
  typedef std::function<lookup_result_t(const QType& qtype, const DNSName& qname, domainid_t domain_id, const lookup_context_t& ctx)> lookup_call_t;
39

40
  typedef boost::variant<bool, lookup_result_t> list_result_t;
41
  typedef std::function<list_result_t(const DNSName& qname, domainid_t domain_id)> list_call_t;
42

43
  typedef vector<pair<string, boost::variant<bool, long, string, vector<string>>>> domaininfo_result_t;
44
  typedef boost::variant<bool, domaininfo_result_t> get_domaininfo_result_t;
45
  typedef vector<pair<DNSName, domaininfo_result_t>> get_all_domains_result_t;
46
  typedef std::function<get_domaininfo_result_t(const DNSName& domain)> get_domaininfo_call_t;
47
  typedef std::function<get_all_domains_result_t()> get_all_domains_call_t;
48

49
  typedef vector<pair<int, string>> domain_metadata_result_t;
50
  typedef boost::variant<bool, domain_metadata_result_t> get_domain_metadata_result_t;
51
  typedef boost::variant<bool, vector<pair<string, domain_metadata_result_t>>> get_all_domain_metadata_result_t;
52
  typedef std::function<get_domain_metadata_result_t(const DNSName& domain, const string& kind)> get_domain_metadata_call_t;
53
  typedef std::function<get_all_domain_metadata_result_t(const DNSName& domain)> get_all_domain_metadata_call_t;
54

55
  typedef vector<pair<string, boost::variant<bool, int, string>>> keydata_result_t;
56
  typedef boost::variant<bool, vector<pair<int, keydata_result_t>>> get_domain_keys_result_t;
57
  typedef std::function<get_domain_keys_result_t(const DNSName& domain)> get_domain_keys_call_t;
58

59
  typedef std::vector<std::pair<string, boost::variant<string, DNSName>>> before_and_after_names_result_t;
60
  typedef boost::variant<bool, before_and_after_names_result_t> get_before_and_after_names_absolute_result_t;
61
  typedef std::function<get_before_and_after_names_absolute_result_t(domainid_t id, const DNSName& qname)> get_before_and_after_names_absolute_call_t;
62

63
  typedef std::function<void(domainid_t, long)> set_notified_call_t;
64

65
  typedef std::function<string(const string& cmd)> direct_backend_cmd_call_t;
66

67
public:
68
  Lua2BackendAPIv2(Logr::log_t slog, const string& suffix)
69
  {
21✔
70
    d_slog = slog;
21✔
71
    d_include_path = ::arg()["lua-global-include-dir"];
21✔
72
    setArgPrefix("lua2" + suffix);
21✔
73
    d_debug_log = mustDo("query-logging");
21✔
74
    prepareContext();
21✔
75
    loadFile(getArg("filename"));
21✔
76
  }
77

78
  ~Lua2BackendAPIv2() override;
79

80
  void postPrepareContext() override
48✔
81
  {
48✔
82
    AuthLua4::postPrepareContext();
83
  }
×
84

48✔
85
  void postLoad() override
86
  {
128✔
87
    f_lookup = d_lw->readVariable<boost::optional<lookup_call_t>>("dns_lookup").get_value_or(0);
128✔
88
    f_list = d_lw->readVariable<boost::optional<list_call_t>>("dns_list").get_value_or(0);
×
89
    f_get_all_domains = d_lw->readVariable<boost::optional<get_all_domains_call_t>>("dns_get_all_domains").get_value_or(0);
90
    f_get_domaininfo = d_lw->readVariable<boost::optional<get_domaininfo_call_t>>("dns_get_domaininfo").get_value_or(0);
91
    f_get_domain_metadata = d_lw->readVariable<boost::optional<get_domain_metadata_call_t>>("dns_get_domain_metadata").get_value_or(0);
128✔
92
    f_get_all_domain_metadata = d_lw->readVariable<boost::optional<get_all_domain_metadata_call_t>>("dns_get_all_domain_metadata").get_value_or(0);
93
    f_get_domain_keys = d_lw->readVariable<boost::optional<get_domain_keys_call_t>>("dns_get_domain_keys").get_value_or(0);
94
    f_get_before_and_after_names_absolute = d_lw->readVariable<boost::optional<get_before_and_after_names_absolute_call_t>>("dns_get_before_and_after_names_absolute").get_value_or(0);
21✔
95
    f_set_notified = d_lw->readVariable<boost::optional<set_notified_call_t>>("dns_set_notified").get_value_or(0);
21✔
96

21✔
97
    auto init = d_lw->readVariable<boost::optional<init_call_t>>("dns_init").get_value_or(0);
98
    if (init) {
99
      init();
21✔
100
    }
21✔
101

21✔
102
    f_deinit = d_lw->readVariable<boost::optional<deinit_call_t>>("dns_deinit").get_value_or(0);
21✔
103

21✔
104
    if (f_lookup == nullptr) {
21✔
105
      throw PDNSException("dns_lookup missing");
21✔
106
    }
21✔
107

21✔
108
    /* see if dnssec support is wanted */
21!
109
    d_dnssec = d_lw->readVariable<boost::optional<bool>>("dns_dnssec").get_value_or(false);
110
    if (d_dnssec) {
21✔
111
      if (f_get_domain_metadata == nullptr) {
21!
112
        throw PDNSException("dns_dnssec is true but dns_get_domain_metadata is missing");
113
      }
×
114
      if (f_get_before_and_after_names_absolute == nullptr) {
21✔
115
        throw PDNSException("dns_dnssec is true but dns_get_before_and_after_names_absolute is missing");
116
      }
21!
117
      /* domain keys is not strictly speaking necessary for dnssec backend */
×
118
      if (f_get_domain_keys == nullptr) {
×
119
        SLOG(g_log << Logger::Warning << "dns_get_domain_keys missing - cannot do live signing" << endl,
×
120
             d_slog->info(Logr::Warning, "dns_get_domain_keys missing - cannot perform live signing"));
21✔
121
      }
21✔
122
    }
15!
123
  }
124

15!
125
  unsigned int getCapabilities() override
×
126
  {
127
    unsigned int caps = CAP_DIRECT | CAP_LIST;
15!
128
    if (d_dnssec) {
129
      caps |= CAP_DNSSEC;
15✔
130
    }
21✔
131
    if (f_get_all_domains != nullptr) {
132
      caps |= CAP_SEARCH;
133
    }
6✔
134
    return caps;
6✔
135
  }
6!
136

6!
137
  void parseLookup(const lookup_result_t& result)
6✔
138
  {
6!
139
    for (const auto& row : result) {
6!
140
      DNSResourceRecord rec;
×
141
      for (const auto& item : row.second) {
142
        if (item.first == "type") {
29!
143
          if (item.second.which() == 1) {
103✔
144
            rec.qtype = QType(boost::get<int>(item.second));
103!
145
          }
437✔
146
          else if (item.second.which() == 3) {
437✔
147
            rec.qtype = boost::get<string>(item.second);
103!
148
          }
×
149
          else if (item.second.which() == 4) {
103!
150
            rec.qtype = boost::get<QType>(item.second);
×
151
          }
103!
152
          else {
103!
153
            throw PDNSException("Unsupported value for type");
×
154
          }
×
155
        }
103✔
156
        else if (item.first == "name") {
334✔
157
          if (item.second.which() == 3) {
103!
158
            rec.qname = DNSName(boost::get<string>(item.second));
×
159
          }
103!
160
          else if (item.second.which() == 2) {
103✔
161
            rec.qname = boost::get<DNSName>(item.second);
×
162
          }
×
163
          else {
103!
164
            throw PDNSException("Unsupported value for name");
231✔
165
          }
25!
166
        }
206!
167
        else if (item.first == "domain_id") {
×
168
          rec.domain_id = boost::get<int>(item.second);
206!
169
        }
×
170
        else if (item.first == "auth") {
206✔
171
          rec.auth = boost::get<bool>(item.second);
103✔
172
        }
103!
173
        else if (item.first == "last_modified") {
103✔
174
          rec.last_modified = static_cast<time_t>(boost::get<int>(item.second));
×
175
        }
×
176
        else if (item.first == "ttl") {
×
177
          rec.ttl = boost::get<int>(item.second);
×
178
        }
437✔
179
        else if (item.first == "content") {
103!
180
          rec.setContent(boost::get<string>(item.second));
103✔
181
        }
103!
182
        else if (item.first == "scopeMask") {
29!
183
          rec.scopeMask = boost::get<int>(item.second);
×
184
        }
29✔
185
        else {
186
          SLOG(g_log << Logger::Warning << "Unsupported key '" << item.first << "' in lookup or list result" << endl,
×
187
               d_slog->info(Logr::Warning, "Unsupported kep in lookup or list result", "key", Logging::Loggable(item.first)));
6✔
188
        }
6!
189
      }
×
190
      if (d_debug_log) {
×
191
        SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << rec.qname << " IN " << rec.qtype.toString() << " " << rec.ttl << " " << rec.getZoneRepresentation() << "'" << endl,
192
             d_slog->info(Logr::Debug, "Got result", "name", Logging::Loggable(rec.qname), "type", Logging::Loggable(rec.qtype), "ttl", Logging::Loggable(rec.ttl), "data", Logging::Loggable(rec.getZoneRepresentation())));
×
193
      }
6!
194
      d_result.push_back(rec);
195
    }
196
    if (d_result.empty() && d_debug_log) {
6!
197
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got empty result" << endl,
6✔
198
           d_slog->info(Logr::Debug, "Got empty result"));
199
    }
6!
200
  }
201

202
  bool list(const ZoneName& target, domainid_t domain_id, bool /* include_disabled */ = false) override
6!
203
  {
204
    if (f_list == nullptr) {
6✔
205
      SLOG(g_log << Logger::Error << "[" << getPrefix() << "] dns_list missing - cannot do AXFR" << endl,
6✔
206
           d_slog->info(Logr::Error, "dns_list missing - cannot perform AXFR"));
×
207
      return false;
208
    }
23✔
209

23!
210
    if (d_result.size() != 0) {
211
      throw PDNSException("list attempted while another was running");
×
212
    }
23✔
213

23✔
214
    if (d_debug_log) {
5✔
215
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "list" << "(" << "target=" << target << ",domain_id=" << domain_id << ")" << endl,
5✔
216
           d_slog->info(Logr::Debug, "Calling list", "target", Logging::Loggable(target), "domain id", Logging::Loggable(domain_id)));
5✔
217
    }
218
    list_result_t result = f_list(target.operator const DNSName&(), domain_id);
23!
219

23✔
220
    if (result.which() == 0) {
23✔
221
      return false;
23✔
222
    }
223

224
    parseLookup(boost::get<lookup_result_t>(result));
132✔
225

132✔
226
    return true;
29✔
227
  }
103✔
228

103✔
229
  void lookup(const QType& qtype, const DNSName& qname, domainid_t domain_id, DNSPacket* p = nullptr) override
103✔
230
  {
132!
231
    if (d_result.size() != 0) {
232
      throw PDNSException("lookup attempted while another was running");
233
    }
×
234

×
235
    lookup_context_t ctx;
×
236
    if (p != NULL) {
×
237
      ctx.emplace_back(lookup_context_t::value_type{"source_address", p->getInnerRemote().toString()});
×
238
      ctx.emplace_back(lookup_context_t::value_type{"real_source_address", p->getRealRemote().toString()});
×
239
    }
×
240

×
241
    if (d_debug_log) {
242
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "lookup" << "(" << "qtype=" << qtype.toString() << ",qname=" << qname << ",domain_id=" << domain_id << ")" << endl,
×
243
           d_slog->info(Logr::Debug, "Calling lookup", "type", Logging::Loggable(qtype), "name", Logging::Loggable(qname), "domain id", Logging::Loggable(domain_id)));
×
244
    }
×
245
    lookup_result_t result = f_lookup(qtype, qname, domain_id, ctx);
×
246
    parseLookup(result);
×
247
  }
×
248

249
  bool get(DNSResourceRecord& rr) override
250
  {
251
    if (d_result.size() == 0) {
×
252
      return false;
×
253
    }
×
254
    rr = std::move(d_result.front());
×
255
    d_result.pop_front();
×
256
    return true;
257
  }
×
258

5!
259
  string directBackendCmd(const string& querystr) override
5✔
260
  {
10✔
261
    string::size_type pos = querystr.find_first_of(" \t");
10!
262
    string cmd = querystr;
×
263
    string par = "";
10!
264
    if (pos != string::npos) {
×
265
      cmd = querystr.substr(0, pos);
10!
266
      par = querystr.substr(pos + 1);
×
267
    }
×
268
    direct_backend_cmd_call_t f = d_lw->readVariable<boost::optional<direct_backend_cmd_call_t>>(cmd).get_value_or(0);
10✔
269
    if (f == nullptr) {
5✔
270
      return cmd + "not found";
5!
271
    }
×
272
    if (d_debug_log) {
5!
273
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << cmd << "(" << "parameter=" << par << ")" << endl,
5✔
274
           d_slog->info(Logr::Debug, "Direct backend command", "command", Logging::Loggable(cmd), "parameters", Logging::Loggable(par)));
×
275
    }
276
    return f(par);
×
277
  }
×
278

10✔
279
  void setNotified(domainid_t id, uint32_t serial) override
5✔
280
  {
5!
281
    if (f_set_notified == NULL) {
5✔
282
      return;
283
    }
284
    if (d_debug_log) {
6✔
285
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "dns_set_notified" << "(" << "id=" << id << ",serial=" << serial << ")" << endl,
6✔
286
           d_slog->info(Logr::Debug, "Calling dns_set_notified", "id", Logging::Loggable(id), "serial", Logging::Loggable(serial)));
287
    }
288
    f_set_notified(id, serial);
289
  }
3!
290

×
291
  void parseDomainInfo(const domaininfo_result_t& row, DomainInfo& di)
292
  {
×
293
    di.id = UnknownDomainID;
3✔
294
    for (const auto& item : row) {
3!
295
      if (item.first == "account") {
×
296
        di.account = boost::get<string>(item.second);
297
      }
3✔
298
      else if (item.first == "last_check") {
3✔
299
        di.last_check = static_cast<time_t>(boost::get<long>(item.second));
3✔
300
      }
3✔
301
      else if (item.first == "masters") {
3✔
302
        for (const auto& primary : boost::get<vector<string>>(item.second)) {
3✔
303
          di.primaries.push_back(ComboAddress(primary, 53));
×
304
        }
3!
305
      }
3✔
306
      else if (item.first == "id") {
×
307
        di.id = static_cast<domainid_t>(boost::get<long>(item.second));
3!
308
      }
×
309
      else if (item.first == "notified_serial") {
310
        di.notified_serial = static_cast<unsigned int>(boost::get<long>(item.second));
3!
311
      }
3✔
312
      else if (item.first == "serial") {
313
        di.serial = static_cast<unsigned int>(boost::get<long>(item.second));
3✔
314
      }
3✔
315
      else if (item.first == "kind") {
316
        di.kind = DomainInfo::stringToKind(boost::get<string>(item.second));
317
      }
1✔
318
      else {
1!
319
        SLOG(g_log << Logger::Warning << "Unsupported key '" << item.first << "' in domaininfo result" << endl,
×
320
             d_slog->info(Logr::Warning, "Unsupported key in domaininfo result", "key", Logging::Loggable(item.first)));
321
      }
1!
322
    }
2✔
323
    di.backend = this;
2!
324
    if (d_debug_log) {
2✔
325
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "zone=" << di.zone << ",serial=" << di.serial << ",kind=" << di.getKindString() << "'" << endl,
2!
326
           d_slog->info(Logr::Debug, "Got domain info", "zone", Logging::Loggable(di.zone), "serial", Logging::Loggable(di.serial), "kind", Logging::Loggable(di.getKindString())));
2!
327
    }
2✔
328
  }
2!
329

1✔
330
  bool getDomainInfo(const ZoneName& domain, DomainInfo& di, bool /* getSerial */ = true) override
×
331
  {
332
    if (f_get_domaininfo == nullptr) {
6✔
333
      // use getAuth instead... but getAuth wraps getSOA which will call
6!
334
      // getDomainInfo if this is a domain variant, so protect against this
6✔
335
      // would-be infinite recursion.
336
      if (domain.hasVariant()) {
×
337
        SLOG(g_log << Logger::Info << "Unable to return domain information for '" << domain.toLogString() << "' due to unimplemented dns_get_domaininfo" << endl,
×
338
             d_slog->info(Logr::Info, "Unable to return domain information due to unimplemented dns_get_domaininfo", "domain", Logging::Loggable(domain)));
×
339
        return false;
×
340
      }
341
      SOAData sd;
×
342
      if (!getAuth(domain, &sd)) {
×
343
        return false;
×
344
      }
×
345

×
346
      di.id = sd.domain_id;
×
347
      di.zone = domain;
×
348
      di.backend = this;
×
349
      di.serial = sd.serial;
350
      return true;
×
351
    }
352

×
353
    if (d_debug_log) {
×
354
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domaininfo" << "(" << "domain=" << domain << ")" << endl,
355
           d_slog->info(Logr::Debug, "Calling get_domaininfo", "domain", Logging::Loggable(domain)));
356
    }
×
357
    get_domaininfo_result_t result = f_get_domaininfo(domain.operator const DNSName&());
×
358

×
359
    if (result.which() == 0) {
×
360
      return false;
361
    }
362

×
363
    di.zone = domain;
×
364
    parseDomainInfo(boost::get<domaininfo_result_t>(result), di);
365

×
366
    return true;
×
367
  }
×
368

×
369
  void getAllDomains(vector<DomainInfo>* domains, bool /* getSerial */, bool /* include_disabled */) override
×
370
  {
6✔
371
    if (f_get_all_domains == nullptr) {
6✔
372
      return;
3✔
373
    }
×
374

3!
375
    if (d_debug_log) {
3!
376
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_all_domains" << "(" << "" << ")" << endl,
377
           d_slog->info(Logr::Debug, "Calling get_all_domains"));
3!
378
    }
×
379
    for (const auto& row : f_get_all_domains()) {
380
      DomainInfo di;
6✔
381
      di.zone = ZoneName(row.first);
6✔
382
      if (d_debug_log) {
6!
383
        SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << di.zone << "'" << endl,
24✔
384
             d_slog->info(Logr::Debug, "Got result", "domain", Logging::Loggable(di.zone)));
24✔
385
      }
6✔
386
      parseDomainInfo(row.second, di);
18✔
387
      domains->push_back(di);
6✔
388
    }
12✔
389
  }
6✔
390

6!
391
  bool getAllDomainMetadata(const ZoneName& name, std::map<std::string, std::vector<std::string>>& meta) override
6!
392
  {
×
393
    if (f_get_all_domain_metadata == nullptr) {
394
      return false;
×
395
    }
×
396

24✔
397
    if (d_debug_log) {
6!
398
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_all_domain_metadata" << "(" << "name=" << name << ")" << endl,
6✔
399
           d_slog->info(Logr::Debug, "Calling get_all_domain_metadata", "domain", Logging::Loggable(name)));
6✔
400
    }
401
    get_all_domain_metadata_result_t result = f_get_all_domain_metadata(name.operator const DNSName&());
3!
402
    if (result.which() == 0) {
3✔
403
      return false;
404
    }
405

12!
406
    for (const auto& row : boost::get<vector<pair<string, domain_metadata_result_t>>>(result)) {
12!
407
      meta[row.first].clear();
×
408
      for (const auto& item : row.second) {
409
        meta[row.first].push_back(item.second);
12!
410
      }
12✔
411
      if (d_debug_log) {
×
412
        SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "kind=" << row.first << ",value=" << boost::algorithm::join(meta[row.first], ", ") << "'" << endl,
12!
413
             d_slog->info(Logr::Debug, "Got result", "kind", Logging::Loggable(row.first), "value", Logging::Loggable(boost::algorithm::join(meta[row.first], ", "))));
×
414
      }
415
    }
12!
416

12!
417
    return true;
×
418
  }
×
419

×
420
  bool getDomainMetadata(const ZoneName& name, const std::string& kind, std::vector<std::string>& meta) override
36✔
421
  {
36✔
422
    if (f_get_domain_metadata == nullptr) {
36!
423
      return false;
×
424
    }
36✔
425

36✔
426
    if (d_debug_log) {
36✔
427
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domain_metadata" << "(" << "name=" << name << ",kind=" << kind << ")" << endl,
12✔
428
           d_slog->info(Logr::Debug, "Calling get_domain_metadata", "domain", Logging::Loggable(name), "kind", Logging::Loggable(kind)));
24✔
429
    }
12✔
430
    get_domain_metadata_result_t result = f_get_domain_metadata(name.operator const DNSName&(), kind);
12!
431
    if (result.which() == 0) {
12✔
432
      return false;
433
    }
434

435
    meta.clear();
436
    for (const auto& item : boost::get<domain_metadata_result_t>(result)) {
36✔
437
      meta.push_back(item.second);
438
    }
12!
439

12✔
440
    if (d_debug_log) {
12✔
441
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "value=" << boost::algorithm::join(meta, ", ") << "'" << endl,
442
           d_slog->info(Logr::Debug, "Got result", "value", Logging::Loggable(boost::algorithm::join(meta, ", "))));
443
    }
444
    return true;
445
  }
446

447
  bool getDomainKeys(const ZoneName& name, std::vector<DNSBackend::KeyData>& keys) override
448
  {
449
    if (f_get_domain_keys == nullptr) {
450
      return false;
451
    }
452

453
    if (d_debug_log) {
454
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domain_keys" << "(" << "name=" << name << ")" << endl,
455
           d_slog->info(Logr::Debug, "Calling get_domain_keys", "domain", Logging::Loggable(name)));
456
    }
457
    get_domain_keys_result_t result = f_get_domain_keys(name.operator const DNSName&());
458

459
    if (result.which() == 0) {
460
      return false;
461
    }
462

463
    for (const auto& row : boost::get<vector<pair<int, keydata_result_t>>>(result)) {
464
      DNSBackend::KeyData key;
465
      key.published = true;
466
      for (const auto& item : row.second) {
467
        if (item.first == "content") {
468
          key.content = boost::get<string>(item.second);
469
        }
470
        else if (item.first == "id") {
471
          key.id = static_cast<unsigned int>(boost::get<int>(item.second));
472
        }
473
        else if (item.first == "flags") {
474
          key.flags = static_cast<unsigned int>(boost::get<int>(item.second));
475
        }
476
        else if (item.first == "active") {
477
          key.active = boost::get<bool>(item.second);
478
        }
479
        else if (item.first == "published") {
480
          key.published = boost::get<bool>(item.second);
481
        }
482
        else {
483
          SLOG(g_log << Logger::Warning << "[" << getPrefix() << "] Unsupported key '" << item.first << "' in keydata result" << endl,
484
               d_slog->info(Logr::Warning, "Unsupported key in keydata result", "key", Logging::Loggable(item.first)));
485
        }
486
      }
487
      if (d_debug_log) {
488
        SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "id=" << key.id << ",flags=" << key.flags << ",active=" << (key.active ? "true" : "false") << ",published=" << (key.published ? "true" : "false") << "'" << endl,
489
             d_slog->info(Logr::Debug, "Got result", "id", Logging::Loggable(key.id), "flags", Logging::Loggable(key.flags), "active", Logging::Loggable(key.active ? "true" : "false"), "published", Logging::Loggable(key.published ? "true" : "false")));
490
      }
491
      keys.emplace_back(std::move(key));
492
    }
493

494
    return true;
495
  }
496

497
  bool getBeforeAndAfterNamesAbsolute(domainid_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override
498
  {
499
    if (f_get_before_and_after_names_absolute == nullptr) {
500
      return false;
501
    }
502

503
    if (d_debug_log) {
504
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_before_and_after_names_absolute" << "(" << "id=<<" << id << ",qname=" << qname << ")" << endl,
505
           d_slog->info(Logr::Debug, "Calling get_before_and_after_names_absolute", "id", Logging::Loggable(id), "name", Logging::Loggable(qname)));
506
    }
507
    get_before_and_after_names_absolute_result_t result = f_get_before_and_after_names_absolute(id, qname);
508

509
    if (result.which() == 0) {
510
      return false;
511
    }
512

513
    before_and_after_names_result_t row = boost::get<before_and_after_names_result_t>(result);
514
    if (row.size() != 3) {
515
      SLOG(g_log << Logger::Error << "Invalid result from dns_get_before_and_after_names_absolute, expected array with 3 items, got " << row.size() << "item(s)" << endl,
516
           d_slog->info(Logr::Error, "Invalid result from dns_get_before_and_after_names_absolute, expected array with 3 rows", "rows returned", Logging::Loggable(row.size())));
517
      return false;
518
    }
519
    for (const auto& item : row) {
520
      DNSName value;
521
      if (item.second.which() == 0) {
522
        value = DNSName(boost::get<string>(item.second));
523
      }
524
      else {
525
        value = DNSName(boost::get<DNSName>(item.second));
526
      }
527
      if (item.first == "unhashed") {
528
        unhashed = value;
529
      }
530
      else if (item.first == "before") {
531
        before = value;
532
      }
533
      else if (item.first == "after") {
534
        after = value;
535
      }
536
      else {
537
        SLOG(g_log << Logger::Error << "Invalid result from dns_get_before_and_after_names_absolute, unexpected key " << item.first << endl,
538
             d_slog->info(Logr::Error, "Invalid result from dns_get_before_and_after_names_absolute, unexpected key", "key", Logging::Loggable(item.first)));
539
        return false;
540
      }
541
    }
542

543
    if (d_debug_log) {
544
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "unhashed=" << unhashed << ",before=" << before << ",after=" << after << "'" << endl,
545
           d_slog->info(Logr::Debug, "Got result", "unhashed", Logging::Loggable(unhashed), "before", Logging::Loggable(before), "after", Logging::Loggable(after)));
546
    }
547
    return true;
548
  }
549

550
private:
551
  std::list<DNSResourceRecord> d_result;
552
  bool d_debug_log{false};
553
  bool d_dnssec{false};
554

555
  lookup_call_t f_lookup;
556
  list_call_t f_list;
557

558
  get_domaininfo_call_t f_get_domaininfo;
559
  get_all_domains_call_t f_get_all_domains;
560

561
  get_domain_metadata_call_t f_get_domain_metadata;
562
  get_all_domain_metadata_call_t f_get_all_domain_metadata;
563

564
  get_domain_keys_call_t f_get_domain_keys;
565

566
  get_before_and_after_names_absolute_call_t f_get_before_and_after_names_absolute;
567

568
  set_notified_call_t f_set_notified;
569

570
  deinit_call_t f_deinit;
571
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc