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

PowerDNS / pdns / 29259985574

13 Jul 2026 02:54PM UTC coverage: 71.154%. First build
29259985574

Pull #17731

github

web-flow
Merge d1aa7008f into 4422d2aa1
Pull Request #17731: auth: Lua2 backend: more robust script results parsing

46759 of 82254 branches covered (56.85%)

Branch coverage included in aggregate %.

223 of 435 new or added lines in 1 file covered. (51.26%)

134146 of 171989 relevant lines covered (78.0%)

5711028.55 hits per line

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

46.84
/modules/lua2backend/lua2api2.cc
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
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
#include "lua2backend.hh"
26

27
Lua2BackendAPIv2::Lua2BackendAPIv2(Logr::log_t slog, const string& suffix)
28
{
20✔
29
  d_slog = slog;
20✔
30
  d_include_path = ::arg()["lua-global-include-dir"];
20✔
31
  setArgPrefix("lua2" + suffix);
20✔
32
  d_debug_log = mustDo("query-logging");
20✔
33
  prepareContext();
20✔
34
  loadFile(getArg("filename"));
20✔
35
}
20✔
36

37
Lua2BackendAPIv2::~Lua2BackendAPIv2()
38
{
16✔
39
  if (f_deinit) {
16!
40
    f_deinit();
×
NEW
41
  }
×
42
}
16✔
43

44
void Lua2BackendAPIv2::postPrepareContext()
45
{
20✔
46
  AuthLua4::postPrepareContext();
20✔
47
}
20✔
48

49
void Lua2BackendAPIv2::postLoad()
50
{
20✔
51
  f_lookup = d_lw->readVariable<boost::optional<lookup_call_t>>("dns_lookup").get_value_or(nullptr);
20✔
52
  f_list = d_lw->readVariable<boost::optional<list_call_t>>("dns_list").get_value_or(nullptr);
20✔
53
  f_get_all_domains = d_lw->readVariable<boost::optional<get_all_domains_call_t>>("dns_get_all_domains").get_value_or(nullptr);
20✔
54
  f_get_domaininfo = d_lw->readVariable<boost::optional<get_domaininfo_call_t>>("dns_get_domaininfo").get_value_or(nullptr);
20✔
55
  f_get_domain_metadata = d_lw->readVariable<boost::optional<get_domain_metadata_call_t>>("dns_get_domain_metadata").get_value_or(nullptr);
20✔
56
  f_get_all_domain_metadata = d_lw->readVariable<boost::optional<get_all_domain_metadata_call_t>>("dns_get_all_domain_metadata").get_value_or(nullptr);
20✔
57
  f_get_domain_keys = d_lw->readVariable<boost::optional<get_domain_keys_call_t>>("dns_get_domain_keys").get_value_or(nullptr);
20✔
58
  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(nullptr);
20✔
59
  f_set_notified = d_lw->readVariable<boost::optional<set_notified_call_t>>("dns_set_notified").get_value_or(nullptr);
20✔
60

61
  auto init = d_lw->readVariable<boost::optional<init_call_t>>("dns_init").get_value_or(nullptr);
20✔
62
  if (init) {
20!
NEW
63
    init();
×
NEW
64
  }
×
65

66
  f_deinit = d_lw->readVariable<boost::optional<deinit_call_t>>("dns_deinit").get_value_or(nullptr);
20✔
67

68
  if (f_lookup == nullptr) {
20!
NEW
69
    throw PDNSException("dns_lookup missing");
×
NEW
70
  }
×
71

72
  /* see if dnssec support is wanted */
73
  d_dnssec = d_lw->readVariable<boost::optional<bool>>("dns_dnssec").get_value_or(false);
20✔
74
  if (d_dnssec) {
20✔
75
    if (f_get_domain_metadata == nullptr) {
15!
NEW
76
      throw PDNSException("dns_dnssec is true but dns_get_domain_metadata is missing");
×
NEW
77
    }
×
78
    if (f_get_before_and_after_names_absolute == nullptr) {
15!
NEW
79
      throw PDNSException("dns_dnssec is true but dns_get_before_and_after_names_absolute is missing");
×
NEW
80
    }
×
81
    /* domain keys is not strictly speaking necessary for dnssec backend */
82
    if (f_get_domain_keys == nullptr) {
15!
NEW
83
      SLOG(g_log << Logger::Warning << "dns_get_domain_keys missing - cannot do live signing" << endl,
×
NEW
84
           d_slog->info(Logr::Warning, "dns_get_domain_keys missing - cannot perform live signing"));
×
NEW
85
    }
×
86
  }
15✔
87
}
20✔
88

89
unsigned int Lua2BackendAPIv2::getCapabilities()
90
{
6✔
91
  unsigned int caps = CAP_DIRECT | CAP_LIST;
6✔
92
  if (d_dnssec) {
6!
93
    caps |= CAP_DNSSEC;
6✔
94
  }
6✔
95
  if (f_get_all_domains != nullptr) {
6!
96
    caps |= CAP_SEARCH;
6✔
97
  }
6✔
98
  return caps;
6✔
99
}
6✔
100

101
void Lua2BackendAPIv2::parseLookup(const lookup_result_t& result)
102
{
29✔
103
  for (const auto& row : result) {
103✔
104
    DNSResourceRecord rec;
103✔
105
    for (const auto& item : row.second) {
437✔
106
      try {
437✔
107
        if (item.first == "type") {
437✔
108
          if (item.second.which() == 1) {
103!
NEW
109
            rec.qtype = QType(boost::get<int>(item.second));
×
NEW
110
          }
×
111
          else if (item.second.which() == 3) {
103!
NEW
112
            rec.qtype = boost::get<string>(item.second);
×
NEW
113
          }
×
114
          else if (item.second.which() == 4) {
103!
115
            rec.qtype = boost::get<QType>(item.second);
103✔
116
          }
103✔
NEW
117
          else {
×
NEW
118
            throw PDNSException("Unsupported value for type");
×
NEW
119
          }
×
120
        }
103✔
121
        else if (item.first == "name") {
334✔
122
          if (item.second.which() == 3) {
103!
NEW
123
            rec.qname = DNSName(boost::get<string>(item.second));
×
NEW
124
          }
×
125
          else { // assuming item.second.which() == 2 here
103✔
126
            rec.qname = boost::get<DNSName>(item.second);
103✔
127
          }
103✔
128
        }
103✔
129
        else if (item.first == "domain_id") {
231✔
130
          rec.domain_id = boost::get<int>(item.second);
25✔
131
        }
25✔
132
        else if (item.first == "auth") {
206!
NEW
133
          rec.auth = boost::get<bool>(item.second);
×
NEW
134
        }
×
135
        else if (item.first == "last_modified") {
206!
NEW
136
          rec.last_modified = static_cast<time_t>(boost::get<int>(item.second));
×
NEW
137
        }
×
138
        else if (item.first == "ttl") {
206✔
139
          rec.ttl = boost::get<int>(item.second);
103✔
140
        }
103✔
141
        else if (item.first == "content") {
103!
142
          if (item.second.which() == 1) {
103!
NEW
143
            rec.setContent(std::to_string(boost::get<int>(item.second)));
×
NEW
144
          }
×
145
          else { // assuming item.second.which() == 3 here
103✔
146
            rec.setContent(boost::get<string>(item.second));
103✔
147
          }
103✔
148
        }
103✔
NEW
149
        else if (item.first == "scopeMask") {
×
NEW
150
          rec.scopeMask = boost::get<int>(item.second);
×
NEW
151
        }
×
NEW
152
        else {
×
NEW
153
          SLOG(g_log << Logger::Warning << "Unsupported key '" << item.first << "' in lookup or list result" << endl,
×
NEW
154
               d_slog->info(Logr::Warning, "Unsupported key in lookup or list result", "key", Logging::Loggable(item.first)));
×
NEW
155
        }
×
156
      }
437✔
157
      catch (const std::exception& e) {
437✔
NEW
158
        throw PDNSException("Unable to parse " + item.first + " value in lookup or list result: " + e.what());
×
NEW
159
      }
×
160
    }
437✔
161
    if (d_debug_log) {
103!
NEW
162
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << rec.qname << " IN " << rec.qtype.toString() << " " << rec.ttl << " " << rec.getZoneRepresentation() << "'" << endl,
×
NEW
163
           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())));
×
NEW
164
    }
×
165
    d_result.push_back(std::move(rec));
103✔
166
  }
103✔
167
  if (d_result.empty() && d_debug_log) {
29!
NEW
168
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got empty result" << endl,
×
NEW
169
         d_slog->info(Logr::Debug, "Got empty result"));
×
NEW
170
  }
×
171
}
29✔
172

173
bool Lua2BackendAPIv2::list(const ZoneName& target, domainid_t domain_id, bool /* include_disabled */)
174
{
6✔
175
  if (f_list == nullptr) {
6!
NEW
176
    SLOG(g_log << Logger::Error << "[" << getPrefix() << "] dns_list missing - cannot do AXFR" << endl,
×
NEW
177
         d_slog->info(Logr::Error, "dns_list missing - cannot perform AXFR"));
×
NEW
178
    return false;
×
NEW
179
  }
×
180

181
  if (!d_result.empty()) {
6!
NEW
182
    throw PDNSException("list attempted while another was running");
×
NEW
183
  }
×
184

185
  if (d_debug_log) {
6!
NEW
186
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "list" << "(" << "target=" << target << ",domain_id=" << domain_id << ")" << endl,
×
NEW
187
         d_slog->info(Logr::Debug, "Calling list", "target", Logging::Loggable(target), "domain id", Logging::Loggable(domain_id)));
×
NEW
188
  }
×
189
  list_result_t result = f_list(target.operator const DNSName&(), domain_id);
6✔
190

191
  if (result.which() == 0) {
6!
NEW
192
    return false;
×
NEW
193
  }
×
194

195
  parseLookup(boost::get<lookup_result_t>(result));
6✔
196

197
  return true;
6✔
198
}
6✔
199

200
void Lua2BackendAPIv2::lookup(const QType& qtype, const DNSName& qname, domainid_t domain_id, DNSPacket* pkt)
201
{
23✔
202
  if (!d_result.empty()) {
23!
NEW
203
    throw PDNSException("lookup attempted while another was running");
×
NEW
204
  }
×
205

206
  lookup_context_t ctx;
23✔
207
  if (pkt != nullptr) {
23✔
208
    ctx.emplace_back(lookup_context_t::value_type{"source_address", pkt->getInnerRemote().toString()});
5✔
209
    ctx.emplace_back(lookup_context_t::value_type{"real_source_address", pkt->getRealRemote().toString()});
5✔
210
  }
5✔
211

212
  if (d_debug_log) {
23!
NEW
213
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "lookup" << "(" << "qtype=" << qtype.toString() << ",qname=" << qname << ",domain_id=" << domain_id << ")" << endl,
×
NEW
214
         d_slog->info(Logr::Debug, "Calling lookup", "type", Logging::Loggable(qtype), "name", Logging::Loggable(qname), "domain id", Logging::Loggable(domain_id)));
×
NEW
215
  }
×
216
  lookup_result_t result = f_lookup(qtype, qname, domain_id, ctx);
23✔
217
  parseLookup(result);
23✔
218
}
23✔
219

220
bool Lua2BackendAPIv2::get(DNSResourceRecord& drr)
221
{
132✔
222
  if (d_result.empty()) {
132✔
223
    return false;
29✔
224
  }
29✔
225
  drr = std::move(d_result.front());
103✔
226
  d_result.pop_front();
103✔
227
  return true;
103✔
228
}
132✔
229

230
string Lua2BackendAPIv2::directBackendCmd(const string& querystr)
NEW
231
{
×
NEW
232
  string::size_type pos = querystr.find_first_of(" \t");
×
NEW
233
  string cmd = querystr;
×
NEW
234
  string par{};
×
NEW
235
  if (pos != string::npos) {
×
NEW
236
    cmd = querystr.substr(0, pos);
×
NEW
237
    par = querystr.substr(pos + 1);
×
NEW
238
  }
×
NEW
239
  direct_backend_cmd_call_t dbc = d_lw->readVariable<boost::optional<direct_backend_cmd_call_t>>(cmd).get_value_or(nullptr);
×
NEW
240
  if (dbc == nullptr) {
×
NEW
241
    return cmd + "not found";
×
NEW
242
  }
×
NEW
243
  if (d_debug_log) {
×
NEW
244
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << cmd << "(" << "parameter=" << par << ")" << endl,
×
NEW
245
         d_slog->info(Logr::Debug, "Direct backend command", "command", Logging::Loggable(cmd), "parameters", Logging::Loggable(par)));
×
NEW
246
  }
×
NEW
247
  return dbc(par);
×
NEW
248
}
×
249

250
void Lua2BackendAPIv2::setNotified(domainid_t domain_id, uint32_t serial)
NEW
251
{
×
NEW
252
  if (f_set_notified == nullptr) {
×
NEW
253
    return;
×
NEW
254
  }
×
NEW
255
  if (d_debug_log) {
×
NEW
256
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "dns_set_notified" << "(" << "id=" << domain_id << ",serial=" << serial << ")" << endl,
×
NEW
257
         d_slog->info(Logr::Debug, "Calling dns_set_notified", "id", Logging::Loggable(domain_id), "serial", Logging::Loggable(serial)));
×
NEW
258
  }
×
NEW
259
  f_set_notified(domain_id, serial);
×
NEW
260
}
×
261

262
void Lua2BackendAPIv2::parseDomainInfo(const domaininfo_result_t& row, DomainInfo& info)
263
{
5✔
264
  info.id = UnknownDomainID;
5✔
265
  for (const auto& item : row) {
10✔
266
    try {
10✔
267
      if (item.first == "account") {
10!
NEW
268
        if (item.second.which() == 1) { // should the account name be all-digits...
×
NEW
269
          info.account = std::to_string(boost::get<long>(item.second));
×
NEW
270
        }
×
NEW
271
        else { // assuming item.second.which() == 2 here
×
NEW
272
          info.account = boost::get<string>(item.second);
×
NEW
273
        }
×
NEW
274
      }
×
275
      else if (item.first == "last_check") {
10!
NEW
276
        info.last_check = static_cast<time_t>(boost::get<long>(item.second));
×
NEW
277
      }
×
278
      else if (item.first == "masters") {
10!
NEW
279
        for (const auto& primary : boost::get<vector<string>>(item.second)) {
×
NEW
280
          info.primaries.emplace_back(ComboAddress(primary, 53));
×
NEW
281
        }
×
NEW
282
      }
×
283
      else if (item.first == "id") {
10✔
284
        info.id = static_cast<domainid_t>(boost::get<long>(item.second));
5✔
285
      }
5✔
286
      else if (item.first == "notified_serial") {
5!
NEW
287
        info.notified_serial = static_cast<unsigned int>(boost::get<long>(item.second));
×
NEW
288
      }
×
289
      else if (item.first == "serial") {
5!
290
        info.serial = static_cast<unsigned int>(boost::get<long>(item.second));
5✔
291
      }
5✔
NEW
292
      else if (item.first == "kind") {
×
NEW
293
        info.kind = DomainInfo::stringToKind(boost::get<string>(item.second));
×
NEW
294
      }
×
NEW
295
      else {
×
NEW
296
        SLOG(g_log << Logger::Warning << "Unsupported key '" << item.first << "' in domaininfo result" << endl,
×
NEW
297
             d_slog->info(Logr::Warning, "Unsupported key in domaininfo result", "key", Logging::Loggable(item.first)));
×
NEW
298
      }
×
299
    }
10✔
300
    catch (const std::exception& e) {
10✔
NEW
301
      throw PDNSException("Unable to parse " + item.first + " value in domaininfo result: " + e.what());
×
NEW
302
    }
×
303
  }
10✔
304
  info.backend = this;
5✔
305
  if (d_debug_log) {
5!
NEW
306
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "zone=" << info.zone << ",serial=" << info.serial << ",kind=" << info.getKindString() << "'" << endl,
×
NEW
307
         d_slog->info(Logr::Debug, "Got domain info", "zone", Logging::Loggable(info.zone), "serial", Logging::Loggable(info.serial), "kind", Logging::Loggable(info.getKindString())));
×
NEW
308
  }
×
309
}
5✔
310

311
bool Lua2BackendAPIv2::getDomainInfo(const ZoneName& domain, DomainInfo& info, bool /* getSerial */)
312
{
6✔
313
  if (f_get_domaininfo == nullptr) {
6✔
314
    // use getAuth instead... but getAuth wraps getSOA which will call
315
    // getDomainInfo if this is a domain variant, so protect against this
316
    // would-be infinite recursion.
317
    if (domain.hasVariant()) {
3!
NEW
318
      SLOG(g_log << Logger::Info << "Unable to return domain information for '" << domain.toLogString() << "' due to unimplemented dns_get_domaininfo" << endl,
×
NEW
319
           d_slog->info(Logr::Info, "Unable to return domain information due to unimplemented dns_get_domaininfo", "domain", Logging::Loggable(domain)));
×
NEW
320
      return false;
×
NEW
321
    }
×
322
    SOAData soa;
3✔
323
    if (!getAuth(domain, &soa)) {
3!
NEW
324
      return false;
×
NEW
325
    }
×
326

327
    info.id = soa.domain_id;
3✔
328
    info.zone = domain;
3✔
329
    info.backend = this;
3✔
330
    info.serial = soa.serial;
3✔
331
    return true;
3✔
332
  }
3✔
333

334
  if (d_debug_log) {
3!
NEW
335
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domaininfo" << "(" << "domain=" << domain << ")" << endl,
×
NEW
336
         d_slog->info(Logr::Debug, "Calling get_domaininfo", "domain", Logging::Loggable(domain)));
×
NEW
337
  }
×
338
  get_domaininfo_result_t result = f_get_domaininfo(domain.operator const DNSName&());
3✔
339

340
  if (result.which() == 0) {
3!
NEW
341
    return false;
×
NEW
342
  }
×
343

344
  info.zone = domain;
3✔
345
  parseDomainInfo(boost::get<domaininfo_result_t>(result), info);
3✔
346

347
  return true;
3✔
348
}
3✔
349

350
void Lua2BackendAPIv2::getAllDomains(vector<DomainInfo>* domains, bool /* getSerial */, bool /* include_disabled */)
351
{
1✔
352
  if (f_get_all_domains == nullptr) {
1!
NEW
353
    return;
×
NEW
354
  }
×
355

356
  if (d_debug_log) {
1!
NEW
357
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_all_domains" << "(" << "" << ")" << endl,
×
NEW
358
         d_slog->info(Logr::Debug, "Calling get_all_domains"));
×
NEW
359
  }
×
360
  for (const auto& row : f_get_all_domains()) {
2✔
361
    DomainInfo info;
2✔
362
    info.zone = ZoneName(row.first);
2✔
363
    if (d_debug_log) {
2!
NEW
364
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << info.zone << "'" << endl,
×
NEW
365
           d_slog->info(Logr::Debug, "Got result", "domain", Logging::Loggable(info.zone)));
×
NEW
366
    }
×
367
    parseDomainInfo(row.second, info);
2✔
368
    domains->push_back(std::move(info));
2✔
369
  }
2✔
370
}
1✔
371

372
bool Lua2BackendAPIv2::getAllDomainMetadata(const ZoneName& name, std::map<std::string, std::vector<std::string>>& meta)
373
{
6✔
374
  if (f_get_all_domain_metadata == nullptr) {
6!
375
    return false;
6✔
376
  }
6✔
377

NEW
378
  if (d_debug_log) {
×
NEW
379
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_all_domain_metadata" << "(" << "name=" << name << ")" << endl,
×
NEW
380
         d_slog->info(Logr::Debug, "Calling get_all_domain_metadata", "domain", Logging::Loggable(name)));
×
NEW
381
  }
×
NEW
382
  get_all_domain_metadata_result_t result = f_get_all_domain_metadata(name.operator const DNSName&());
×
NEW
383
  if (result.which() == 0) {
×
NEW
384
    return false;
×
NEW
385
  }
×
386

NEW
387
  for (const auto& row : boost::get<vector<pair<string, domain_metadata_result_t>>>(result)) {
×
NEW
388
    meta[row.first].clear();
×
NEW
389
    for (const auto& item : row.second) {
×
NEW
390
      meta[row.first].push_back(item.second);
×
NEW
391
    }
×
NEW
392
    if (d_debug_log) {
×
NEW
393
      SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "kind=" << row.first << ",value=" << boost::algorithm::join(meta[row.first], ", ") << "'" << endl,
×
NEW
394
           d_slog->info(Logr::Debug, "Got result", "kind", Logging::Loggable(row.first), "value", Logging::Loggable(boost::algorithm::join(meta[row.first], ", "))));
×
NEW
395
    }
×
NEW
396
  }
×
397

NEW
398
  return true;
×
NEW
399
}
×
400

401
bool Lua2BackendAPIv2::getDomainMetadata(const ZoneName& name, const std::string& kind, std::vector<std::string>& meta)
NEW
402
{
×
NEW
403
  if (f_get_domain_metadata == nullptr) {
×
NEW
404
    return false;
×
NEW
405
  }
×
406

NEW
407
  if (d_debug_log) {
×
NEW
408
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domain_metadata" << "(" << "name=" << name << ",kind=" << kind << ")" << endl,
×
NEW
409
         d_slog->info(Logr::Debug, "Calling get_domain_metadata", "domain", Logging::Loggable(name), "kind", Logging::Loggable(kind)));
×
NEW
410
  }
×
NEW
411
  get_domain_metadata_result_t result = f_get_domain_metadata(name.operator const DNSName&(), kind);
×
NEW
412
  if (result.which() == 0) {
×
NEW
413
    return false;
×
NEW
414
  }
×
415

NEW
416
  meta.clear();
×
NEW
417
  for (const auto& item : boost::get<domain_metadata_result_t>(result)) {
×
NEW
418
    meta.push_back(item.second);
×
NEW
419
  }
×
420

NEW
421
  if (d_debug_log) {
×
NEW
422
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "value=" << boost::algorithm::join(meta, ", ") << "'" << endl,
×
NEW
423
         d_slog->info(Logr::Debug, "Got result", "value", Logging::Loggable(boost::algorithm::join(meta, ", "))));
×
NEW
424
  }
×
NEW
425
  return true;
×
NEW
426
}
×
427

428
bool Lua2BackendAPIv2::getDomainKeys(const ZoneName& name, std::vector<DNSBackend::KeyData>& keys)
429
{
6✔
430
  if (f_get_domain_keys == nullptr) {
6✔
431
    return false;
3✔
432
  }
3✔
433

434
  if (d_debug_log) {
3!
NEW
435
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_domain_keys" << "(" << "name=" << name << ")" << endl,
×
NEW
436
         d_slog->info(Logr::Debug, "Calling get_domain_keys", "domain", Logging::Loggable(name)));
×
NEW
437
  }
×
438
  get_domain_keys_result_t result = f_get_domain_keys(name.operator const DNSName&());
3✔
439

440
  if (result.which() == 0) {
3!
NEW
441
    return false;
×
NEW
442
  }
×
443

444
  for (const auto& row : boost::get<vector<pair<int, keydata_result_t>>>(result)) {
6✔
445
    DNSBackend::KeyData key;
6✔
446
    key.published = true;
6✔
447
    for (const auto& item : row.second) {
24✔
448
      try {
24✔
449
        if (item.first == "content") {
24✔
450
          key.content = boost::get<string>(item.second);
6✔
451
        }
6✔
452
        else if (item.first == "id") {
18✔
453
          key.id = static_cast<unsigned int>(boost::get<int>(item.second));
6✔
454
        }
6✔
455
        else if (item.first == "flags") {
12✔
456
          key.flags = static_cast<unsigned int>(boost::get<int>(item.second));
6✔
457
        }
6✔
458
        else if (item.first == "active") {
6!
459
          key.active = boost::get<bool>(item.second);
6✔
460
        }
6✔
NEW
461
        else if (item.first == "published") {
×
NEW
462
          key.published = boost::get<bool>(item.second);
×
NEW
463
        }
×
NEW
464
        else {
×
NEW
465
          SLOG(g_log << Logger::Warning << "[" << getPrefix() << "] Unsupported key '" << item.first << "' in keydata result" << endl,
×
NEW
466
               d_slog->info(Logr::Warning, "Unsupported key in keydata result", "key", Logging::Loggable(item.first)));
×
NEW
467
        }
×
468
      }
24✔
469
      catch (const std::exception& e) {
24✔
NEW
470
        throw PDNSException("Unable to parse " + item.first + " value in keydata result: " + e.what());
×
NEW
471
      }
×
472
    }
24✔
473
    if (d_debug_log) {
6!
NEW
474
      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,
×
NEW
475
           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")));
×
NEW
476
    }
×
477
    keys.emplace_back(std::move(key));
6✔
478
  }
6✔
479

480
  return true;
3✔
481
}
3✔
482

483
bool Lua2BackendAPIv2::getBeforeAndAfterNamesAbsolute(domainid_t domain_id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
484
{
12✔
485
  if (f_get_before_and_after_names_absolute == nullptr) {
12!
NEW
486
    return false;
×
NEW
487
  }
×
488

489
  if (d_debug_log) {
12!
NEW
490
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Calling " << "get_before_and_after_names_absolute" << "(" << "id=<<" << domain_id << ",qname=" << qname << ")" << endl,
×
NEW
491
         d_slog->info(Logr::Debug, "Calling get_before_and_after_names_absolute", "id", Logging::Loggable(domain_id), "name", Logging::Loggable(qname)));
×
NEW
492
  }
×
493
  get_before_and_after_names_absolute_result_t result = f_get_before_and_after_names_absolute(domain_id, qname);
12✔
494

495
  if (result.which() == 0) {
12!
NEW
496
    return false;
×
NEW
497
  }
×
498

499
  before_and_after_names_result_t row = boost::get<before_and_after_names_result_t>(result);
12✔
500
  if (row.size() != 3) {
12!
NEW
501
    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,
×
NEW
502
         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())));
×
NEW
503
    return false;
×
NEW
504
  }
×
505
  for (const auto& item : row) {
36✔
506
    DNSName value;
36✔
507
    if (item.second.which() == 0) {
36!
NEW
508
      value = DNSName(boost::get<string>(item.second));
×
NEW
509
    }
×
510
    else {
36✔
511
      value = DNSName(boost::get<DNSName>(item.second));
36✔
512
    }
36✔
513
    if (item.first == "unhashed") {
36✔
514
      unhashed = std::move(value);
12✔
515
    }
12✔
516
    else if (item.first == "before") {
24✔
517
      before = std::move(value);
12✔
518
    }
12✔
519
    else if (item.first == "after") {
12!
520
      after = std::move(value);
12✔
521
    }
12✔
NEW
522
    else {
×
NEW
523
      SLOG(g_log << Logger::Error << "Invalid result from dns_get_before_and_after_names_absolute, unexpected key " << item.first << endl,
×
NEW
524
           d_slog->info(Logr::Error, "Invalid result from dns_get_before_and_after_names_absolute, unexpected key", "key", Logging::Loggable(item.first)));
×
NEW
525
      return false;
×
NEW
526
    }
×
527
  }
36✔
528

529
  if (d_debug_log) {
12!
NEW
530
    SLOG(g_log << Logger::Debug << "[" << getPrefix() << "] Got result " << "'" << "unhashed=" << unhashed << ",before=" << before << ",after=" << after << "'" << endl,
×
NEW
531
         d_slog->info(Logr::Debug, "Got result", "unhashed", Logging::Loggable(unhashed), "before", Logging::Loggable(before), "after", Logging::Loggable(after)));
×
NEW
532
  }
×
533
  return true;
12✔
534
}
12✔
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