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

PowerDNS / pdns / 19741624072

27 Nov 2025 03:45PM UTC coverage: 73.086% (+0.02%) from 73.065%
19741624072

Pull #16570

github

web-flow
Merge 08a2cdb1d into f94a3f63f
Pull Request #16570: rec: rewrite all unwrap calls in web.rs

38523 of 63408 branches covered (60.75%)

Branch coverage included in aggregate %.

128044 of 164496 relevant lines covered (77.84%)

6531485.83 hits per line

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

87.85
/pdns/dnsdistdist/dnsdist-lua-bindings-dnsquestion.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
 * MERCHANTABILITY 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
#include "dnsdist.hh"
23
#include "dnsdist-async.hh"
24
#include "dnsdist-dnsparser.hh"
25
#include "dnsdist-ecs.hh"
26
#include "dnsdist-internal-queries.hh"
27
#include "dnsdist-lua.hh"
28
#include "dnsdist-self-answers.hh"
29
#include "dnsdist-snmp.hh"
30
#include "dnsparser.hh"
31

32
#include "protozero.hh"
33
#include <string>
34

35
static void addMetaKeyAndValuesToProtobufContent([[maybe_unused]] DNSQuestion& dnsQuestion, [[maybe_unused]] const std::string& key, [[maybe_unused]] const LuaArray<boost::variant<int64_t, std::string>>& values)
36
{
2✔
37
#if !defined(DISABLE_PROTOBUF)
2✔
38
  protozero::pbf_writer pbfWriter{dnsQuestion.ids.d_rawProtobufContent};
2✔
39
  protozero::pbf_writer pbfMetaWriter{pbfWriter, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::Field::meta)};
2✔
40
  pbfMetaWriter.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::MetaField::key), key);
2✔
41
  protozero::pbf_writer pbfMetaValueWriter{pbfMetaWriter, static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::MetaField::value)};
2✔
42
  for (const auto& value : values) {
6✔
43
    if (value.second.type() == typeid(std::string)) {
6✔
44
      pbfMetaValueWriter.add_string(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::MetaValueField::stringVal), boost::get<std::string>(value.second));
4✔
45
    }
4✔
46
    else {
2✔
47
      pbfMetaValueWriter.add_uint64(static_cast<protozero::pbf_tag_type>(pdns::ProtoZero::Message::MetaValueField::intVal), boost::get<int64_t>(value.second));
2✔
48
    }
2✔
49
  }
6✔
50
  pbfMetaValueWriter.commit();
2✔
51
  pbfMetaWriter.commit();
2✔
52
#endif /* DISABLE_PROTOBUF */
2✔
53
}
2✔
54

55
// NOLINTNEXTLINE(readability-function-cognitive-complexity): this function declares Lua bindings, even with a good refactoring it will likely blow up the threshold
56
void setupLuaBindingsDNSQuestion([[maybe_unused]] LuaContext& luaCtx)
57
{
818✔
58
#ifndef DISABLE_NON_FFI_DQ_BINDINGS
818✔
59
  /* DNSQuestion */
60
  /* PowerDNS DNSQuestion compat */
61
  luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
818✔
62
    "localaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSQuestion& dnsQuestion, const ComboAddress newLocal) { (void)dnsQuestion; (void)newLocal; });
818✔
63
  luaCtx.registerMember<const DNSName(DNSQuestion::*)>(
818✔
64
    "qname", [](const DNSQuestion& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSQuestion& dnsQuestion, const DNSName& newName) { (void)dnsQuestion; (void)newName; });
818✔
65
  luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
818✔
66
    "qtype", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSQuestion& dnsQuestion, uint16_t newType) { (void)dnsQuestion; (void)newType; });
818✔
67
  luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
818✔
68
    "qclass", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSQuestion& dnsQuestion, uint16_t newClass) { (void)dnsQuestion;  (void)newClass; });
818✔
69
  luaCtx.registerMember<int(DNSQuestion::*)>(
818✔
70
    "rcode",
818✔
71
    [](const DNSQuestion& dnsQuestion) -> int {
818✔
72
      return static_cast<int>(dnsQuestion.getHeader()->rcode);
73
    },
74
    [](DNSQuestion& dnsQuestion, int newRCode) {
818✔
75
      dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [newRCode](dnsheader& header) {
76
        header.rcode = static_cast<decltype(header.rcode)>(newRCode);
77
        return true;
78
      });
79
    });
80
  luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
818✔
81
    "remoteaddr", [](const DNSQuestion& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSQuestion& dnsQuestion, const ComboAddress newRemote) { (void)dnsQuestion; (void)newRemote; });
818✔
82
  /* DNSDist DNSQuestion */
83
  luaCtx.registerMember<dnsheader*(DNSQuestion::*)>(
818✔
84
    "dh",
818✔
85
    [](const DNSQuestion& dnsQuestion) -> dnsheader* {
818✔
86
      return dnsQuestion.getMutableHeader();
119✔
87
    },
119✔
88
    [](DNSQuestion& dnsQuestion, const dnsheader* dnsHeader) {
818✔
89
      dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [&dnsHeader](dnsheader& header) {
90
        header = *dnsHeader;
91
        return true;
92
      });
93
    });
94
  luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
818✔
95
    "len", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.getData().size(); }, [](DNSQuestion& dnsQuestion, uint16_t newlen) { dnsQuestion.getMutableData().resize(newlen); });
818✔
96
  luaCtx.registerMember<uint8_t(DNSQuestion::*)>(
818✔
97
    "opcode", [](const DNSQuestion& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSQuestion& dnsQuestion, uint8_t newOpcode) { (void)dnsQuestion; (void)newOpcode; });
818✔
98
  luaCtx.registerMember<bool(DNSQuestion::*)>(
818✔
99
    "tcp", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSQuestion& dnsQuestion, bool newTcp) { (void)dnsQuestion; (void)newTcp; });
818✔
100
  luaCtx.registerMember<bool(DNSQuestion::*)>(
818✔
101
    "skipCache", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.ids.skipCache; }, [](DNSQuestion& dnsQuestion, bool newSkipCache) { dnsQuestion.ids.skipCache = newSkipCache; });
818✔
102
  luaCtx.registerMember<std::string(DNSQuestion::*)>(
818✔
103
    "pool", [](const DNSQuestion& dnsQuestion) -> std::string { return dnsQuestion.ids.poolName; }, [](DNSQuestion& dnsQuestion, const std::string& newPoolName) { dnsQuestion.ids.poolName = newPoolName; });
818✔
104
  luaCtx.registerMember<bool(DNSQuestion::*)>(
818✔
105
    "useECS", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.useECS; }, [](DNSQuestion& dnsQuestion, bool useECS) { dnsQuestion.useECS = useECS; });
818✔
106
  luaCtx.registerMember<bool(DNSQuestion::*)>(
818✔
107
    "ecsOverride", [](const DNSQuestion& dnsQuestion) -> bool { return dnsQuestion.ecsOverride; }, [](DNSQuestion& dnsQuestion, bool ecsOverride) { dnsQuestion.ecsOverride = ecsOverride; });
818✔
108
  luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
818✔
109
    "ecsPrefixLength", [](const DNSQuestion& dnsQuestion) -> uint16_t { return dnsQuestion.ecsPrefixLength; }, [](DNSQuestion& dnsQuestion, uint16_t newPrefixLength) { dnsQuestion.ecsPrefixLength = newPrefixLength; });
818✔
110
  luaCtx.registerMember<boost::optional<uint32_t>(DNSQuestion::*)>(
818✔
111
    "tempFailureTTL",
818✔
112
    [](const DNSQuestion& dnsQuestion) -> boost::optional<uint32_t> {
818✔
113
      return dnsQuestion.ids.tempFailureTTL;
6✔
114
    },
6✔
115
    [](DNSQuestion& dnsQuestion, boost::optional<uint32_t> newValue) {
818✔
116
      dnsQuestion.ids.tempFailureTTL = newValue;
4✔
117
    });
4✔
118
  luaCtx.registerMember<std::string(DNSQuestion::*)>(
818✔
119
    "deviceID", [](const DNSQuestion& dnsQuestion) -> std::string {
818✔
120
    if (dnsQuestion.ids.d_protoBufData) {
×
121
      return dnsQuestion.ids.d_protoBufData->d_deviceID;
122
    }
123
    return {}; }, [](DNSQuestion& dnsQuestion, const std::string& newValue) {
124
    if (!dnsQuestion.ids.d_protoBufData) {
×
125
      dnsQuestion.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
126
    }
127
    dnsQuestion.ids.d_protoBufData->d_deviceID = newValue; });
128
  luaCtx.registerMember<std::string(DNSQuestion::*)>(
818✔
129
    "deviceName", [](const DNSQuestion& dnsQuestion) -> std::string {
818✔
130
    if (dnsQuestion.ids.d_protoBufData) {
×
131
      return dnsQuestion.ids.d_protoBufData->d_deviceName;
132
    }
133
    return {}; }, [](DNSQuestion& dnsQuestion, const std::string& newValue) {
134
    if (!dnsQuestion.ids.d_protoBufData) {
×
135
      dnsQuestion.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
136
    }
137
    dnsQuestion.ids.d_protoBufData->d_deviceName = newValue; });
138
  luaCtx.registerMember<std::string(DNSQuestion::*)>(
818✔
139
    "requestorID", [](const DNSQuestion& dnsQuestion) -> std::string {
818✔
140
    if (dnsQuestion.ids.d_protoBufData) {
×
141
      return dnsQuestion.ids.d_protoBufData->d_requestorID;
142
    }
143
    return {}; }, [](DNSQuestion& dnsQuestion, const std::string& newValue) {
144
    if (!dnsQuestion.ids.d_protoBufData) {
×
145
      dnsQuestion.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
146
    }
147
    dnsQuestion.ids.d_protoBufData->d_requestorID = newValue; });
148
  luaCtx.registerFunction<bool (DNSQuestion::*)() const>("getDO", [](const DNSQuestion& dnsQuestion) {
818✔
149
    return dnsdist::getEDNSZ(dnsQuestion) & EDNS_HEADER_FLAG_DO;
4✔
150
  });
4✔
151
  luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getContent", [](const DNSQuestion& dnsQuestion) {
818✔
152
    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
153
    return std::string(reinterpret_cast<const char*>(dnsQuestion.getData().data()), dnsQuestion.getData().size());
105✔
154
  });
105✔
155
  luaCtx.registerFunction<void (DNSQuestion::*)(const std::string&)>("setContent", [](DNSQuestion& dnsQuestion, const std::string& raw) {
818✔
156
    uint16_t oldID = dnsQuestion.getHeader()->id;
18✔
157
    auto& buffer = dnsQuestion.getMutableData();
18✔
158
    buffer.clear();
18✔
159
    buffer.insert(buffer.begin(), raw.begin(), raw.end());
18✔
160

161
    dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [oldID](dnsheader& header) {
18✔
162
      header.id = oldID;
18✔
163
      return true;
18✔
164
    });
18✔
165
  });
18✔
166
  luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView> (DNSQuestion::*)() const>("getEDNSOptions", [](const DNSQuestion& dnsQuestion) {
818✔
167
    if (dnsQuestion.ednsOptions == nullptr) {
24!
168
      parseEDNSOptions(dnsQuestion);
24✔
169
      if (dnsQuestion.ednsOptions == nullptr) {
24!
170
        throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
171
      }
172
    }
24✔
173

174
    return *dnsQuestion.ednsOptions;
24✔
175
  });
24✔
176
  luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getTrailingData", [](const DNSQuestion& dnsQuestion) {
818✔
177
    return dnsQuestion.getTrailingData();
8✔
178
  });
8✔
179
  luaCtx.registerFunction<bool (DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dnsQuestion, const std::string& tail) {
818✔
180
    return dnsQuestion.setTrailingData(tail);
12✔
181
  });
12✔
182

183
  luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getServerNameIndication", [](const DNSQuestion& dnsQuestion) {
818✔
184
    return dnsQuestion.sni;
9✔
185
  });
9✔
186

187
  luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getIncomingInterface", [](const DNSQuestion& dnsQuestion) -> std::string {
818✔
188
    if (dnsQuestion.ids.cs != nullptr) {
4!
189
      return dnsQuestion.ids.cs->interface;
4✔
190
    }
4✔
191
    return {};
192
  });
4✔
193

194
  luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getProtocol", [](const DNSQuestion& dnsQuestion) -> std::string {
818✔
195
    // coverity[auto_causes_copy]
196
    return dnsQuestion.getProtocol().toPrettyString();
9✔
197
  });
9✔
198

199
  luaCtx.registerFunction<timespec (DNSQuestion::*)() const>("getQueryTime", [](const DNSQuestion& dnsQuestion) {
818✔
200
    return dnsQuestion.ids.queryRealTime.getStartTime();
2✔
201
  });
2✔
202

203
  luaCtx.registerFunction<double (DNSQuestion::*)() const>("getElapsedUs", [](const DNSQuestion& dnsQuestion) {
818✔
204
    return dnsQuestion.ids.queryRealTime.udiff();
205
  });
206

207
  luaCtx.registerFunction<void (DNSQuestion::*)(std::string)>("sendTrap", []([[maybe_unused]] const DNSQuestion& dnsQuestion, [[maybe_unused]] boost::optional<std::string> reason) {
818✔
208
#ifdef HAVE_NET_SNMP
209
    if (g_snmpAgent != nullptr && dnsdist::configuration::getImmutableConfiguration().d_snmpTrapsEnabled) {
×
210
      g_snmpAgent->sendDNSTrap(dnsQuestion, reason ? *reason : "");
×
211
    }
212
#endif /* HAVE_NET_SNMP */
213
  });
214

215
  luaCtx.registerFunction<void (DNSQuestion::*)(std::string, std::string)>("setTag", [](DNSQuestion& dnsQuestion, const std::string& strLabel, const std::string& strValue) {
818✔
216
    dnsQuestion.setTag(strLabel, strValue);
116✔
217
  });
116✔
218
  luaCtx.registerFunction<void (DNSQuestion::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSQuestion& dnsQuestion, const LuaAssociativeTable<std::string>& tags) {
818✔
219
    for (const auto& tag : tags) {
8✔
220
      dnsQuestion.setTag(tag.first, tag.second);
8✔
221
    }
8✔
222
  });
4✔
223
  luaCtx.registerFunction<string (DNSQuestion::*)(std::string) const>("getTag", [](const DNSQuestion& dnsQuestion, const std::string& strLabel) {
818✔
224
    if (!dnsQuestion.ids.qTag) {
4!
225
      return string();
226
    }
227

228
    std::string strValue;
4✔
229
    const auto tagIt = dnsQuestion.ids.qTag->find(strLabel);
4✔
230
    if (tagIt == dnsQuestion.ids.qTag->cend()) {
4!
231
      return string();
232
    }
233
    return tagIt->second;
4✔
234
  });
4✔
235
  luaCtx.registerFunction<QTag (DNSQuestion::*)(void) const>("getTagArray", [](const DNSQuestion& dnsQuestion) -> QTag {
818✔
236
    if (!dnsQuestion.ids.qTag) {
2!
237
      QTag empty;
238
      return empty;
239
    }
240

241
    // coverity[auto_causes_copy]
242
    return *dnsQuestion.ids.qTag;
2✔
243
  });
2✔
244

245
  luaCtx.registerFunction<void (DNSQuestion::*)(std::string, LuaArray<boost::variant<int64_t, std::string>>)>("setMetaKey", [](DNSQuestion& dnsQuestion, const std::string& key, const LuaArray<boost::variant<int64_t, std::string>>& values) {
818✔
246
    addMetaKeyAndValuesToProtobufContent(dnsQuestion, key, values);
1✔
247
  });
1✔
248

249
  luaCtx.registerFunction<void (DNSQuestion::*)(LuaArray<std::string>)>("setProxyProtocolValues", [](DNSQuestion& dnsQuestion, const LuaArray<std::string>& values) {
818✔
250
    if (!dnsQuestion.proxyProtocolValues) {
2!
251
      dnsQuestion.proxyProtocolValues = make_unique<std::vector<ProxyProtocolValue>>();
2✔
252
    }
2✔
253

254
    dnsQuestion.proxyProtocolValues->clear();
2✔
255
    dnsQuestion.proxyProtocolValues->reserve(values.size());
2✔
256
    for (const auto& value : values) {
4✔
257
      checkParameterBound("setProxyProtocolValues", value.first, std::numeric_limits<uint8_t>::max());
4✔
258
      dnsQuestion.proxyProtocolValues->push_back({value.second, static_cast<uint8_t>(value.first)});
4✔
259
    }
4✔
260
  });
2✔
261

262
  luaCtx.registerFunction<void (DNSQuestion::*)(uint64_t, std::string)>("addProxyProtocolValue", [](DNSQuestion& dnsQuestion, uint64_t type, std::string value) {
818✔
263
    checkParameterBound("addProxyProtocolValue", type, std::numeric_limits<uint8_t>::max());
76✔
264
    if (!dnsQuestion.proxyProtocolValues) {
76✔
265
      dnsQuestion.proxyProtocolValues = make_unique<std::vector<ProxyProtocolValue>>();
10✔
266
    }
10✔
267

268
    dnsQuestion.proxyProtocolValues->push_back({std::move(value), static_cast<uint8_t>(type)});
76✔
269
  });
76✔
270

271
  luaCtx.registerFunction<LuaArray<std::string> (DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dnsQuestion) {
818✔
272
    LuaArray<std::string> result;
2✔
273
    if (!dnsQuestion.proxyProtocolValues) {
2!
274
      return result;
275
    }
276

277
    result.resize(dnsQuestion.proxyProtocolValues->size());
2✔
278
    for (const auto& value : *dnsQuestion.proxyProtocolValues) {
4✔
279
      result.emplace_back(value.type, value.content);
4✔
280
    }
4✔
281

282
    return result;
2✔
283
  });
2✔
284

285
  luaCtx.registerFunction<bool (DNSQuestion::*)(const DNSName& newName)>("changeName", [](DNSQuestion& dnsQuestion, const DNSName& newName) -> bool {
818✔
286
    if (!dnsdist::changeNameInDNSPacket(dnsQuestion.getMutableData(), dnsQuestion.ids.qname, newName)) {
2!
287
      return false;
288
    }
289
    dnsQuestion.ids.qname = newName;
2✔
290
    return true;
2✔
291
  });
2✔
292

293
  luaCtx.registerFunction<void (DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, boost::optional<uint16_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, boost::optional<uint16_t> typeForAny) {
818✔
294
    dnsdist::ResponseConfig responseConfig;
10✔
295
    if (response.type() == typeid(LuaArray<ComboAddress>)) {
10✔
296
      std::vector<ComboAddress> data;
4✔
297
      auto responses = boost::get<LuaArray<ComboAddress>>(response);
4✔
298
      data.reserve(responses.size());
4✔
299
      for (const auto& resp : responses) {
8✔
300
        data.push_back(resp.second);
8✔
301
      }
8✔
302
      dnsdist::self_answers::generateAnswerFromIPAddresses(dnsQuestion, data, responseConfig);
4✔
303
      return;
4✔
304
    }
4✔
305
    if (response.type() == typeid(LuaArray<std::string>)) {
6!
306
      std::vector<std::string> data;
6✔
307
      auto responses = boost::get<LuaArray<std::string>>(response);
6✔
308
      data.reserve(responses.size());
6✔
309
      for (const auto& resp : responses) {
12✔
310
        data.push_back(resp.second);
12✔
311
      }
12✔
312
      dnsdist::self_answers::generateAnswerFromRDataEntries(dnsQuestion, data, typeForAny ? *typeForAny : std::optional<uint16_t>(), responseConfig);
6!
313
      return;
6✔
314
    }
6✔
315
  });
6✔
316

317
  luaCtx.registerFunction<void (DNSQuestion::*)(uint16_t code, const std::string&)>("setEDNSOption", [](DNSQuestion& dnsQuestion, uint16_t code, const std::string& data) {
818✔
318
    setEDNSOption(dnsQuestion, code, data);
319
  });
320

321
  luaCtx.registerFunction<void (DNSQuestion::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSQuestion& dnsQuestion, uint16_t infoCode, const boost::optional<std::string>& extraText) {
818✔
322
    EDNSExtendedError ede;
323
    ede.infoCode = infoCode;
324
    if (extraText) {
×
325
      ede.extraText = *extraText;
326
    }
327
    dnsQuestion.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
328
  });
329

330
  luaCtx.registerFunction<bool (DNSQuestion::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSQuestion& dnsQuestion, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
818✔
331
    dnsQuestion.asynchronous = true;
101✔
332
    return dnsdist::suspendQuery(dnsQuestion, asyncID, queryID, timeoutMs);
101✔
333
  });
101✔
334

335
  luaCtx.registerFunction<bool (DNSQuestion::*)()>("setRestartable", [](DNSQuestion& dnsQuestion) {
818✔
336
    dnsQuestion.ids.d_packet = std::make_unique<PacketBuffer>(dnsQuestion.getData());
522✔
337
    return true;
522✔
338
  });
522✔
339

340
  luaCtx.registerFunction<std::optional<std::string> (DNSQuestion::*)()>(
818✔
341
    "getTraceID",
818✔
342
    []([[maybe_unused]] const DNSQuestion& dnsQuestion) -> std::optional<std::string> {
818✔
343
#ifdef DISABLE_PROTOBUF
344
      return std::nullopt;
345
#else
346
      if (auto tracer = dnsQuestion.ids.getTracer(); tracer != nullptr && dnsQuestion.ids.tracingEnabled) {
×
347
        auto traceID = tracer->getTraceID();
348
        return std::string(traceID.begin(), traceID.end());
349
      }
350
      return std::nullopt;
351
#endif
352
    });
353

354
  luaCtx.registerFunction<std::optional<std::string> (DNSQuestion::*)()>(
818✔
355
    "getSpanID",
818✔
356
    []([[maybe_unused]] const DNSQuestion& dnsQuestion) -> std::optional<std::string> {
818✔
357
#ifdef DISABLE_PROTOBUF
358
      return std::nullopt;
359
#else
360
      if (auto tracer = dnsQuestion.ids.getTracer(); tracer != nullptr && dnsQuestion.ids.tracingEnabled) {
×
361
        auto spanID = tracer->getLastSpanID();
362
        return std::string(spanID.begin(), spanID.end());
363
      }
364
      return std::nullopt;
365
#endif
366
    });
367

368
  class AsynchronousObject
818✔
369
  {
818✔
370
  public:
818✔
371
    AsynchronousObject(std::unique_ptr<CrossProtocolQuery>&& obj_) :
818✔
372
      object(std::move(obj_))
818✔
373
    {
818✔
374
    }
158✔
375

376
    [[nodiscard]] DNSQuestion getDQ() const
818✔
377
    {
818✔
378
      return object->getDQ();
140✔
379
    }
140✔
380

381
    [[nodiscard]] DNSResponse getDR() const
818✔
382
    {
818✔
383
      return object->getDR();
384
    }
385

386
    bool resume()
818✔
387
    {
818✔
388
      return dnsdist::queueQueryResumptionEvent(std::move(object));
140✔
389
    }
140✔
390

391
    bool drop()
818✔
392
    {
818✔
393
      auto sender = object->getTCPQuerySender();
18✔
394
      if (!sender) {
18!
395
        return false;
396
      }
397

398
      timeval now{};
18✔
399
      gettimeofday(&now, nullptr);
18✔
400
      sender->notifyIOError(now, TCPResponse(std::move(object->query)));
18✔
401
      return true;
18✔
402
    }
18✔
403

404
    bool setRCode(uint8_t rcode, bool clearAnswers)
818✔
405
    {
818✔
406
      return dnsdist::setInternalQueryRCode(object->query.d_idstate, object->query.d_buffer, rcode, clearAnswers);
18✔
407
    }
18✔
408

409
  private:
818✔
410
    std::unique_ptr<CrossProtocolQuery> object;
818✔
411
  };
818✔
412

413
  luaCtx.registerFunction<DNSQuestion (AsynchronousObject::*)(void) const>("getDQ", [](const AsynchronousObject& obj) {
818✔
414
    return obj.getDQ();
140✔
415
  });
140✔
416

417
  luaCtx.registerFunction<DNSQuestion (AsynchronousObject::*)(void) const>("getDR", [](const AsynchronousObject& obj) {
818✔
418
    return obj.getDR();
419
  });
420

421
  luaCtx.registerFunction<bool (AsynchronousObject::*)(void)>("resume", [](AsynchronousObject& obj) {
818✔
422
    return obj.resume();
140✔
423
  });
140✔
424

425
  luaCtx.registerFunction<bool (AsynchronousObject::*)(void)>("drop", [](AsynchronousObject& obj) {
818✔
426
    return obj.drop();
18✔
427
  });
18✔
428

429
  luaCtx.registerFunction<bool (AsynchronousObject::*)(uint8_t, bool)>("setRCode", [](AsynchronousObject& obj, uint8_t rcode, bool clearAnswers) {
818✔
430
    return obj.setRCode(rcode, clearAnswers);
18✔
431
  });
18✔
432

433
  luaCtx.writeFunction("getAsynchronousObject", [](uint16_t asyncID, uint16_t queryID) -> AsynchronousObject {
818✔
434
    if (!dnsdist::g_asyncHolder) {
158!
435
      throw std::runtime_error("Unable to resume, no asynchronous holder");
436
    }
437
    auto query = dnsdist::g_asyncHolder->get(asyncID, queryID);
158✔
438
    if (!query) {
158!
439
      throw std::runtime_error("Unable to find asynchronous object");
440
    }
441
    return {std::move(query)};
158✔
442
  });
158✔
443

444
  /* LuaWrapper doesn't support inheritance */
445
  luaCtx.registerMember<const ComboAddress(DNSResponse::*)>(
818✔
446
    "localaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origDest; }, [](DNSResponse& dnsQuestion, const ComboAddress newLocal) { (void)dnsQuestion; (void)newLocal; });
818✔
447
  luaCtx.registerMember<const DNSName(DNSResponse::*)>(
818✔
448
    "qname", [](const DNSResponse& dnsQuestion) -> DNSName { return dnsQuestion.ids.qname; }, [](DNSResponse& dnsQuestion, const DNSName& newName) { (void)dnsQuestion; (void)newName; });
818✔
449
  luaCtx.registerMember<uint16_t(DNSResponse::*)>(
818✔
450
    "qtype", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qtype; }, [](DNSResponse& dnsQuestion, uint16_t newType) { (void)dnsQuestion; (void)newType; });
818✔
451
  luaCtx.registerMember<uint16_t(DNSResponse::*)>(
818✔
452
    "qclass", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.ids.qclass; }, [](DNSResponse& dnsQuestion, uint16_t newClass) { (void)dnsQuestion; (void)newClass; });
818✔
453
  luaCtx.registerMember<int(DNSResponse::*)>(
818✔
454
    "rcode",
818✔
455
    [](const DNSResponse& dnsQuestion) -> int {
818✔
456
      return static_cast<int>(dnsQuestion.getHeader()->rcode);
6✔
457
    },
6✔
458
    [](DNSResponse& dnsQuestion, int newRCode) {
818✔
459
      dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [newRCode](dnsheader& header) {
2✔
460
        header.rcode = static_cast<decltype(header.rcode)>(newRCode);
2✔
461
        return true;
2✔
462
      });
2✔
463
    });
2✔
464
  luaCtx.registerMember<ComboAddress(DNSResponse::*)>(
818✔
465
    "remoteaddr", [](const DNSResponse& dnsQuestion) -> ComboAddress { return dnsQuestion.ids.origRemote; }, [](DNSResponse& dnsQuestion, const ComboAddress newRemote) { (void)dnsQuestion; (void)newRemote; });
818✔
466
  luaCtx.registerMember<dnsheader*(DNSResponse::*)>(
818✔
467
    "dh",
818✔
468
    [](const DNSResponse& dnsResponse) -> dnsheader* {
818✔
469
      return dnsResponse.getMutableHeader();
87✔
470
    },
87✔
471
    [](DNSResponse& dnsResponse, const dnsheader* dnsHeader) {
818✔
472
      dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsResponse.getMutableData(), [&dnsHeader](dnsheader& header) {
473
        header = *dnsHeader;
474
        return true;
475
      });
476
    });
477
  luaCtx.registerMember<uint16_t(DNSResponse::*)>(
818✔
478
    "len", [](const DNSResponse& dnsQuestion) -> uint16_t { return dnsQuestion.getData().size(); }, [](DNSResponse& dnsQuestion, uint16_t newlen) { dnsQuestion.getMutableData().resize(newlen); });
818✔
479
  luaCtx.registerMember<uint8_t(DNSResponse::*)>(
818✔
480
    "opcode", [](const DNSResponse& dnsQuestion) -> uint8_t { return dnsQuestion.getHeader()->opcode; }, [](DNSResponse& dnsQuestion, uint8_t newOpcode) { (void)dnsQuestion; (void)newOpcode; });
818✔
481
  luaCtx.registerMember<bool(DNSResponse::*)>(
818✔
482
    "tcp", [](const DNSResponse& dnsQuestion) -> bool { return dnsQuestion.overTCP(); }, [](DNSResponse& dnsQuestion, bool newTcp) { (void)dnsQuestion; (void)newTcp; });
818✔
483
  luaCtx.registerMember<bool(DNSResponse::*)>(
818✔
484
    "skipCache", [](const DNSResponse& dnsQuestion) -> bool { return dnsQuestion.ids.skipCache; }, [](DNSResponse& dnsQuestion, bool newSkipCache) { dnsQuestion.ids.skipCache = newSkipCache; });
818✔
485
  luaCtx.registerMember<std::string(DNSResponse::*)>(
818✔
486
    "pool", [](const DNSResponse& dnsQuestion) -> std::string { return dnsQuestion.ids.poolName; }, [](DNSResponse& dnsQuestion, const std::string& newPoolName) { dnsQuestion.ids.poolName = newPoolName; });
818✔
487
  luaCtx.registerFunction<void (DNSResponse::*)(std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc)>("editTTLs", [](DNSResponse& dnsResponse, const std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)>& editFunc) {
818✔
488
    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
489
    editDNSPacketTTL(reinterpret_cast<char*>(dnsResponse.getMutableData().data()), dnsResponse.getData().size(), editFunc);
2✔
490
  });
2✔
491
  luaCtx.registerFunction<bool (DNSResponse::*)() const>("getDO", [](const DNSResponse& dnsQuestion) {
818✔
492
    return dnsdist::getEDNSZ(dnsQuestion) & EDNS_HEADER_FLAG_DO;
493
  });
494
  luaCtx.registerFunction<std::string (DNSResponse::*)() const>("getContent", [](const DNSResponse& dnsQuestion) {
818✔
495
    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
496
    return std::string(reinterpret_cast<const char*>(dnsQuestion.getData().data()), dnsQuestion.getData().size());
87✔
497
  });
87✔
498
  luaCtx.registerFunction<void (DNSResponse::*)(const std::string&)>("setContent", [](DNSResponse& dnsResponse, const std::string& raw) {
818✔
499
    uint16_t oldID = dnsResponse.getHeader()->id;
500
    auto& buffer = dnsResponse.getMutableData();
501
    buffer.clear();
502
    buffer.insert(buffer.begin(), raw.begin(), raw.end());
503
    dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [oldID](dnsheader& header) {
504
      header.id = oldID;
505
      return true;
506
    });
507
  });
508

509
  luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView> (DNSResponse::*)() const>("getEDNSOptions", [](const DNSResponse& dnsQuestion) {
818✔
510
    if (dnsQuestion.ednsOptions == nullptr) {
10!
511
      parseEDNSOptions(dnsQuestion);
10✔
512
      if (dnsQuestion.ednsOptions == nullptr) {
10!
513
        throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
514
      }
515
    }
10✔
516

517
    return *dnsQuestion.ednsOptions;
10✔
518
  });
10✔
519
  luaCtx.registerFunction<std::string (DNSResponse::*)(void) const>("getTrailingData", [](const DNSResponse& dnsQuestion) {
818✔
520
    return dnsQuestion.getTrailingData();
521
  });
522
  luaCtx.registerFunction<bool (DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dnsQuestion, const std::string& tail) {
818✔
523
    return dnsQuestion.setTrailingData(tail);
524
  });
525

526
  luaCtx.registerFunction<void (DNSResponse::*)(std::string, std::string)>("setTag", [](DNSResponse& dnsResponse, const std::string& strLabel, const std::string& strValue) {
818✔
527
    dnsResponse.setTag(strLabel, strValue);
100✔
528
  });
100✔
529

530
  luaCtx.registerFunction<void (DNSResponse::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSResponse& dnsResponse, const LuaAssociativeTable<string>& tags) {
818✔
531
    for (const auto& tag : tags) {
×
532
      dnsResponse.setTag(tag.first, tag.second);
533
    }
534
  });
535
  luaCtx.registerFunction<string (DNSResponse::*)(std::string) const>("getTag", [](const DNSResponse& dnsResponse, const std::string& strLabel) {
818✔
536
    if (!dnsResponse.ids.qTag) {
2!
537
      return string();
538
    }
539

540
    std::string strValue;
2✔
541
    const auto tagIt = dnsResponse.ids.qTag->find(strLabel);
2✔
542
    if (tagIt == dnsResponse.ids.qTag->cend()) {
2!
543
      return string();
544
    }
545
    return tagIt->second;
2✔
546
  });
2✔
547
  luaCtx.registerFunction<QTag (DNSResponse::*)(void) const>("getTagArray", [](const DNSResponse& dnsResponse) {
818✔
548
    if (!dnsResponse.ids.qTag) {
×
549
      QTag empty;
550
      return empty;
551
    }
552

553
    return *dnsResponse.ids.qTag;
554
  });
555

556
  luaCtx.registerFunction<std::string (DNSResponse::*)() const>("getProtocol", [](const DNSResponse& dnsResponse) {
818✔
557
    return dnsResponse.getProtocol().toPrettyString();
558
  });
559

560
  luaCtx.registerFunction<timespec (DNSResponse::*)() const>("getQueryTime", [](const DNSResponse& dnsResponse) {
818✔
561
    return dnsResponse.ids.queryRealTime.getStartTime();
2✔
562
  });
2✔
563

564
  luaCtx.registerFunction<double (DNSResponse::*)() const>("getElapsedUs", [](const DNSResponse& dnsResponse) {
818✔
565
    return dnsResponse.ids.queryRealTime.udiff();
566
  });
567

568
  luaCtx.registerFunction<std::string (DNSResponse::*)() const>("getIncomingInterface", [](const DNSResponse& dnsResponse) -> std::string {
818✔
569
    if (dnsResponse.ids.cs != nullptr) {
2!
570
      return dnsResponse.ids.cs->interface;
2✔
571
    }
2✔
572
    return {};
573
  });
2✔
574

575
  luaCtx.registerFunction<void (DNSResponse::*)(std::string)>("sendTrap", []([[maybe_unused]] const DNSResponse& dnsResponse, [[maybe_unused]] boost::optional<std::string> reason) {
818✔
576
#ifdef HAVE_NET_SNMP
577
    if (g_snmpAgent != nullptr && dnsdist::configuration::getImmutableConfiguration().d_snmpTrapsEnabled) {
×
578
      g_snmpAgent->sendDNSTrap(dnsResponse, reason ? *reason : "");
×
579
    }
580
#endif /* HAVE_NET_SNMP */
581
  });
582

583
#if defined(HAVE_DNS_OVER_HTTPS) || defined(HAVE_DNS_OVER_HTTP3)
818✔
584
  luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPPath", [](const DNSQuestion& dnsQuestion) {
818✔
585
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
586
    if (dnsQuestion.ids.du) {
4✔
587
      return dnsQuestion.ids.du->getHTTPPath();
3✔
588
    }
3✔
589
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
590
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
591
    if (dnsQuestion.ids.doh3u) {
1!
592
      return dnsQuestion.ids.doh3u->getHTTPPath();
1✔
593
    }
1✔
594
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
595
    return std::string();
596
  });
1✔
597

598
  luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPQueryString", [](const DNSQuestion& dnsQuestion) {
818✔
599
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
600
    if (dnsQuestion.ids.du) {
4✔
601
      return dnsQuestion.ids.du->getHTTPQueryString();
3✔
602
    }
3✔
603
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
604
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
605
    if (dnsQuestion.ids.doh3u) {
1!
606
      return dnsQuestion.ids.doh3u->getHTTPQueryString();
1✔
607
    }
1✔
608
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
609
    return std::string();
610
  });
1✔
611

612
  luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPHost", [](const DNSQuestion& dnsQuestion) {
818✔
613
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
614
    if (dnsQuestion.ids.du) {
4✔
615
      return dnsQuestion.ids.du->getHTTPHost();
3✔
616
    }
3✔
617
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
618
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
619
    if (dnsQuestion.ids.doh3u) {
1!
620
      return dnsQuestion.ids.doh3u->getHTTPHost();
1✔
621
    }
1✔
622
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
623
    return std::string();
624
  });
1✔
625

626
  luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPScheme", [](const DNSQuestion& dnsQuestion) {
818✔
627
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
628
    if (dnsQuestion.ids.du) {
4✔
629
      return dnsQuestion.ids.du->getHTTPScheme();
3✔
630
    }
3✔
631
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
632
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
633
    if (dnsQuestion.ids.doh3u) {
1!
634
      return dnsQuestion.ids.doh3u->getHTTPScheme();
1✔
635
    }
1✔
636
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
637
    return std::string();
638
  });
1✔
639

640
  luaCtx.registerFunction<LuaAssociativeTable<std::string> (DNSQuestion::*)(void) const>("getHTTPHeaders", [](const DNSQuestion& dnsQuestion) -> LuaAssociativeTable<std::string> {
818✔
641
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
642
    if (dnsQuestion.ids.du) {
4✔
643
      // coverity[auto_causes_copy]
644
      return dnsQuestion.ids.du->getHTTPHeaders();
3✔
645
    }
3✔
646
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
647
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
648
    if (dnsQuestion.ids.doh3u) {
1!
649
      // coverity[auto_causes_copy]
650
      return dnsQuestion.ids.doh3u->getHTTPHeaders();
1✔
651
    }
1✔
652
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
653
    return LuaAssociativeTable<std::string>();
654
  });
1✔
655

656
  luaCtx.registerFunction<void (DNSQuestion::*)(uint64_t statusCode, const std::string& body, const boost::optional<std::string> contentType)>("setHTTPResponse", [](DNSQuestion& dnsQuestion, uint64_t statusCode, const std::string& body, [[maybe_unused]] const boost::optional<std::string>& contentType) {
818✔
657
    if (dnsQuestion.ids.du == nullptr && dnsQuestion.ids.doh3u == nullptr) {
4!
658
      return;
659
    }
660
    checkParameterBound("DNSQuestion::setHTTPResponse", statusCode, std::numeric_limits<uint16_t>::max());
4✔
661
    PacketBuffer vect(body.begin(), body.end());
4✔
662
#if defined(HAVE_DNS_OVER_HTTPS)
4✔
663
    if (dnsQuestion.ids.du) {
4✔
664
      dnsQuestion.ids.du->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : "");
3!
665
      return;
3✔
666
    }
3✔
667
#endif /* defined(HAVE_DNS_OVER_HTTPS) */
1✔
668
#if defined(HAVE_DNS_OVER_HTTP3)
1✔
669
    dnsQuestion.ids.doh3u->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : "");
1!
670
#endif /* defined(HAVE_DNS_OVER_HTTP3) */
1✔
671
  });
1✔
672
#endif /* HAVE_DNS_OVER_HTTPS HAVE_DNS_OVER_HTTP3 */
818✔
673

674
  luaCtx.registerFunction<bool (DNSQuestion::*)(bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum)>("setNegativeAndAdditionalSOA", [](DNSQuestion& dnsQuestion, bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum) {
818✔
675
    checkParameterBound("setNegativeAndAdditionalSOA", ttl, std::numeric_limits<uint32_t>::max());
676
    checkParameterBound("setNegativeAndAdditionalSOA", serial, std::numeric_limits<uint32_t>::max());
677
    checkParameterBound("setNegativeAndAdditionalSOA", refresh, std::numeric_limits<uint32_t>::max());
678
    checkParameterBound("setNegativeAndAdditionalSOA", retry, std::numeric_limits<uint32_t>::max());
679
    checkParameterBound("setNegativeAndAdditionalSOA", expire, std::numeric_limits<uint32_t>::max());
680
    checkParameterBound("setNegativeAndAdditionalSOA", minimum, std::numeric_limits<uint32_t>::max());
681

682
    return setNegativeAndAdditionalSOA(dnsQuestion, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum, false);
683
  });
684

685
  luaCtx.registerFunction<void (DNSResponse::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSResponse& dnsResponse, uint16_t infoCode, const boost::optional<std::string>& extraText) {
818✔
686
    EDNSExtendedError ede;
687
    ede.infoCode = infoCode;
688
    if (extraText) {
×
689
      ede.extraText = *extraText;
690
    }
691
    dnsResponse.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
692
  });
693

694
  luaCtx.registerFunction<bool (DNSResponse::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSResponse& dnsResponse, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
818✔
695
    dnsResponse.asynchronous = true;
83✔
696
    return dnsdist::suspendResponse(dnsResponse, asyncID, queryID, timeoutMs);
83✔
697
  });
83✔
698

699
  luaCtx.registerFunction<bool (DNSResponse::*)(const DNSName& newName)>("changeName", [](DNSResponse& dnsResponse, const DNSName& newName) -> bool {
818✔
700
    if (!dnsdist::changeNameInDNSPacket(dnsResponse.getMutableData(), dnsResponse.ids.qname, newName)) {
2!
701
      return false;
702
    }
703
    dnsResponse.ids.qname = newName;
2✔
704
    return true;
2✔
705
  });
2✔
706

707
  luaCtx.registerFunction<bool (DNSResponse::*)()>("restart", [](DNSResponse& dnsResponse) {
818✔
708
    if (!dnsResponse.ids.d_packet || dnsResponse.ids.d_packet->size() < sizeof(struct dnsheader)) {
322!
709
      return false;
710
    }
711
    dnsResponse.asynchronous = true;
322✔
712
    dnsResponse.getMutableData() = *dnsResponse.ids.d_packet;
322✔
713
    dnsResponse.ids.d_proxyProtocolPayloadSize = 0;
322✔
714
    dnsResponse.ids.restartCount++;
322✔
715
    auto query = dnsdist::getInternalQueryFromDQ(dnsResponse, false);
322✔
716
    return dnsdist::queueQueryResumptionEvent(std::move(query));
322✔
717
  });
322✔
718

719
  luaCtx.registerFunction<boost::optional<std::shared_ptr<DownstreamState>> (DNSResponse::*)(void) const>("getSelectedBackend", [](const DNSResponse& dnsResponse) {
818✔
720
    return dnsResponse.d_downstream ? dnsResponse.d_downstream : boost::optional<std::shared_ptr<DownstreamState>>();
102✔
721
  });
102✔
722

723
  luaCtx.registerFunction<bool (DNSResponse::*)()>("getStaleCacheHit", [](DNSResponse& dnsResponse) {
818✔
724
    return dnsResponse.ids.staleCacheHit;
2✔
725
  });
2✔
726

727
  luaCtx.registerFunction<uint8_t (DNSResponse::*)()>("getRestartCount", [](DNSResponse& dnsResponse) {
818✔
728
    return dnsResponse.ids.restartCount;
500✔
729
  });
500✔
730

731
  luaCtx.registerFunction<void (DNSResponse::*)(std::string, LuaArray<boost::variant<int64_t, std::string>>)>("setMetaKey", [](DNSResponse& dnsResponse, const std::string& key, const LuaArray<boost::variant<int64_t, std::string>>& values) {
818✔
732
    addMetaKeyAndValuesToProtobufContent(dnsResponse, key, values);
1✔
733
  });
1✔
734

735
#endif /* DISABLE_NON_FFI_DQ_BINDINGS */
818✔
736
}
818✔
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

© 2025 Coveralls, Inc