]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdist-lua-bindings.cc
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
24 #include "dnsdist-lua.hh"
28 void setupLuaBindings(bool client
)
30 g_lua
.writeFunction("infolog", [](const string
& arg
) {
33 g_lua
.writeFunction("errlog", [](const string
& arg
) {
36 g_lua
.writeFunction("warnlog", [](const string
& arg
) {
39 g_lua
.writeFunction("show", [](const string
& arg
) {
45 g_lua
.registerFunction
<string(std::exception_ptr::*)()>("__tostring", [](const std::exception_ptr
& eptr
) {
48 std::rethrow_exception(eptr
);
50 } catch(const std::exception
& e
) {
51 return string(e
.what());
52 } catch(const PDNSException
& e
) {
55 return string("Unknown exception");
57 return string("No exception");
60 g_lua
.writeFunction("newServerPolicy", [](string name
, ServerPolicy::policyfunc_t policy
) { return std::make_shared
<ServerPolicy
>(name
, policy
, true);});
61 g_lua
.registerMember("name", &ServerPolicy::name
);
62 g_lua
.registerMember("policy", &ServerPolicy::policy
);
63 g_lua
.registerMember("ffipolicy", &ServerPolicy::ffipolicy
);
64 g_lua
.registerMember("isLua", &ServerPolicy::isLua
);
65 g_lua
.registerMember("isFFI", &ServerPolicy::isFFI
);
66 g_lua
.registerFunction("toString", &ServerPolicy::toString
);
68 g_lua
.writeVariable("firstAvailable", ServerPolicy
{"firstAvailable", firstAvailable
, false});
69 g_lua
.writeVariable("roundrobin", ServerPolicy
{"roundrobin", roundrobin
, false});
70 g_lua
.writeVariable("wrandom", ServerPolicy
{"wrandom", wrandom
, false});
71 g_lua
.writeVariable("whashed", ServerPolicy
{"whashed", whashed
, false});
72 g_lua
.writeVariable("chashed", ServerPolicy
{"chashed", chashed
, false});
73 g_lua
.writeVariable("leastOutstanding", ServerPolicy
{"leastOutstanding", leastOutstanding
, false});
76 g_lua
.registerFunction
<void(std::shared_ptr
<ServerPool
>::*)(std::shared_ptr
<DNSDistPacketCache
>)>("setCache", [](std::shared_ptr
<ServerPool
> pool
, std::shared_ptr
<DNSDistPacketCache
> cache
) {
78 pool
->packetCache
= cache
;
81 g_lua
.registerFunction("getCache", &ServerPool::getCache
);
82 g_lua
.registerFunction
<void(std::shared_ptr
<ServerPool
>::*)()>("unsetCache", [](std::shared_ptr
<ServerPool
> pool
) {
84 pool
->packetCache
= nullptr;
87 g_lua
.registerFunction("getECS", &ServerPool::getECS
);
88 g_lua
.registerFunction("setECS", &ServerPool::setECS
);
91 g_lua
.registerFunction
<void(DownstreamState::*)(int)>("setQPS", [](DownstreamState
& s
, int lim
) { s
.qps
= lim
? QPSLimiter(lim
, lim
) : QPSLimiter(); });
92 g_lua
.registerFunction
<void(std::shared_ptr
<DownstreamState
>::*)(string
)>("addPool", [](std::shared_ptr
<DownstreamState
> s
, string pool
) {
93 auto localPools
= g_pools
.getCopy();
94 addServerToPool(localPools
, pool
, s
);
95 g_pools
.setState(localPools
);
96 s
->pools
.insert(pool
);
98 g_lua
.registerFunction
<void(std::shared_ptr
<DownstreamState
>::*)(string
)>("rmPool", [](std::shared_ptr
<DownstreamState
> s
, string pool
) {
99 auto localPools
= g_pools
.getCopy();
100 removeServerFromPool(localPools
, pool
, s
);
101 g_pools
.setState(localPools
);
102 s
->pools
.erase(pool
);
104 g_lua
.registerFunction
<uint64_t(DownstreamState::*)()>("getOutstanding", [](const DownstreamState
& s
) { return s
.outstanding
.load(); });
105 g_lua
.registerFunction("isUp", &DownstreamState::isUp
);
106 g_lua
.registerFunction("setDown", &DownstreamState::setDown
);
107 g_lua
.registerFunction("setUp", &DownstreamState::setUp
);
108 g_lua
.registerFunction
<void(DownstreamState::*)(boost::optional
<bool> newStatus
)>("setAuto", [](DownstreamState
& s
, boost::optional
<bool> newStatus
) {
110 s
.upStatus
= *newStatus
;
114 g_lua
.registerFunction
<std::string(DownstreamState::*)()>("getName", [](const DownstreamState
& s
) { return s
.getName(); });
115 g_lua
.registerFunction
<std::string(DownstreamState::*)()>("getNameWithAddr", [](const DownstreamState
& s
) { return s
.getNameWithAddr(); });
116 g_lua
.registerMember("upStatus", &DownstreamState::upStatus
);
117 g_lua
.registerMember
<int (DownstreamState::*)>("weight",
118 [](const DownstreamState
& s
) -> int {return s
.weight
;},
119 [](DownstreamState
& s
, int newWeight
) {s
.setWeight(newWeight
);}
121 g_lua
.registerMember("order", &DownstreamState::order
);
122 g_lua
.registerMember
<const std::string(DownstreamState::*)>("name", [](const DownstreamState
& backend
) -> const std::string
{ return backend
.getName(); }, [](DownstreamState
& backend
, const std::string
& newName
) { backend
.setName(newName
); });
123 g_lua
.registerFunction
<std::string(DownstreamState::*)()>("getID", [](const DownstreamState
& s
) { return boost::uuids::to_string(s
.id
); });
126 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setRD", [](dnsheader
& dh
, bool v
) {
130 g_lua
.registerFunction
<bool(dnsheader::*)()>("getRD", [](dnsheader
& dh
) {
134 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setRA", [](dnsheader
& dh
, bool v
) {
138 g_lua
.registerFunction
<bool(dnsheader::*)()>("getRA", [](dnsheader
& dh
) {
142 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setAD", [](dnsheader
& dh
, bool v
) {
146 g_lua
.registerFunction
<bool(dnsheader::*)()>("getAD", [](dnsheader
& dh
) {
150 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setAA", [](dnsheader
& dh
, bool v
) {
154 g_lua
.registerFunction
<bool(dnsheader::*)()>("getAA", [](dnsheader
& dh
) {
158 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setCD", [](dnsheader
& dh
, bool v
) {
162 g_lua
.registerFunction
<bool(dnsheader::*)()>("getCD", [](dnsheader
& dh
) {
166 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setTC", [](dnsheader
& dh
, bool v
) {
168 if(v
) dh
.ra
= dh
.rd
; // you'll always need this, otherwise TC=1 gets ignored
171 g_lua
.registerFunction
<void(dnsheader::*)(bool)>("setQR", [](dnsheader
& dh
, bool v
) {
176 g_lua
.writeFunction("newCA", [](const std::string
& name
) { return ComboAddress(name
); });
177 g_lua
.writeFunction("newCAFromRaw", [](const std::string
& raw
, boost::optional
<uint16_t> port
) {
178 if (raw
.size() == 4) {
179 struct sockaddr_in sin4
;
180 memset(&sin4
, 0, sizeof(sin4
));
181 sin4
.sin_family
= AF_INET
;
182 memcpy(&sin4
.sin_addr
.s_addr
, raw
.c_str(), raw
.size());
184 sin4
.sin_port
= htons(*port
);
186 return ComboAddress(&sin4
);
188 else if (raw
.size() == 16) {
189 struct sockaddr_in6 sin6
;
190 memset(&sin6
, 0, sizeof(sin6
));
191 sin6
.sin6_family
= AF_INET6
;
192 memcpy(&sin6
.sin6_addr
.s6_addr
, raw
.c_str(), raw
.size());
194 sin6
.sin6_port
= htons(*port
);
196 return ComboAddress(&sin6
);
198 return ComboAddress();
200 g_lua
.registerFunction
<string(ComboAddress::*)()>("tostring", [](const ComboAddress
& ca
) { return ca
.toString(); });
201 g_lua
.registerFunction
<string(ComboAddress::*)()>("tostringWithPort", [](const ComboAddress
& ca
) { return ca
.toStringWithPort(); });
202 g_lua
.registerFunction
<string(ComboAddress::*)()>("toString", [](const ComboAddress
& ca
) { return ca
.toString(); });
203 g_lua
.registerFunction
<string(ComboAddress::*)()>("toStringWithPort", [](const ComboAddress
& ca
) { return ca
.toStringWithPort(); });
204 g_lua
.registerFunction
<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress
& ca
) { return ntohs(ca
.sin4
.sin_port
); } );
205 g_lua
.registerFunction
<void(ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress
& ca
, unsigned int bits
) { ca
.truncate(bits
); });
206 g_lua
.registerFunction
<bool(ComboAddress::*)()>("isIPv4", [](const ComboAddress
& ca
) { return ca
.sin4
.sin_family
== AF_INET
; });
207 g_lua
.registerFunction
<bool(ComboAddress::*)()>("isIPv6", [](const ComboAddress
& ca
) { return ca
.sin4
.sin_family
== AF_INET6
; });
208 g_lua
.registerFunction
<bool(ComboAddress::*)()>("isMappedIPv4", [](const ComboAddress
& ca
) { return ca
.isMappedIPv4(); });
209 g_lua
.registerFunction
<ComboAddress(ComboAddress::*)()>("mapToIPv4", [](const ComboAddress
& ca
) { return ca
.mapToIPv4(); });
210 g_lua
.registerFunction
<bool(nmts_t::*)(const ComboAddress
&)>("match", [](nmts_t
& s
, const ComboAddress
& ca
) { return s
.match(ca
); });
213 g_lua
.registerFunction("isPartOf", &DNSName::isPartOf
);
214 g_lua
.registerFunction
<bool(DNSName::*)()>("chopOff", [](DNSName
&dn
) { return dn
.chopOff(); });
215 g_lua
.registerFunction
<unsigned int(DNSName::*)()>("countLabels", [](const DNSName
& name
) { return name
.countLabels(); });
216 g_lua
.registerFunction
<size_t(DNSName::*)()>("hash", [](const DNSName
& name
) { return name
.hash(); });
217 g_lua
.registerFunction
<size_t(DNSName::*)()>("wirelength", [](const DNSName
& name
) { return name
.wirelength(); });
218 g_lua
.registerFunction
<string(DNSName::*)()>("tostring", [](const DNSName
&dn
) { return dn
.toString(); });
219 g_lua
.registerFunction
<string(DNSName::*)()>("toString", [](const DNSName
&dn
) { return dn
.toString(); });
220 g_lua
.writeFunction("newDNSName", [](const std::string
& name
) { return DNSName(name
); });
221 g_lua
.writeFunction("newDNSNameFromRaw", [](const std::string
& name
) { return DNSName(name
.c_str(), name
.size(), 0, false); });
222 g_lua
.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); });
223 g_lua
.writeFunction("newDNSNameSet", []() { return DNSNameSet(); });
226 g_lua
.registerFunction
<string(DNSNameSet::*)()>("toString", [](const DNSNameSet
&dns
) { return dns
.toString(); });
227 g_lua
.registerFunction
<void(DNSNameSet::*)(DNSName
&)>("add", [](DNSNameSet
& dns
, DNSName
& dn
) { dns
.insert(dn
); });
228 g_lua
.registerFunction
<bool(DNSNameSet::*)(DNSName
&)>("check", [](DNSNameSet
& dns
, DNSName
& dn
) { return dns
.find(dn
) != dns
.end(); });
229 g_lua
.registerFunction("delete",(size_t (DNSNameSet::*)(const DNSName
&)) &DNSNameSet::erase
);
230 g_lua
.registerFunction("size",(size_t (DNSNameSet::*)() const) &DNSNameSet::size
);
231 g_lua
.registerFunction("clear",(void (DNSNameSet::*)()) &DNSNameSet::clear
);
232 g_lua
.registerFunction("empty",(bool (DNSNameSet::*)()) &DNSNameSet::empty
);
234 /* SuffixMatchNode */
235 g_lua
.registerFunction
<void (SuffixMatchNode::*)(const boost::variant
<DNSName
, string
, vector
<pair
<int, DNSName
>>, vector
<pair
<int, string
>>> &name
)>("add", [](SuffixMatchNode
&smn
, const boost::variant
<DNSName
, string
, vector
<pair
<int, DNSName
>>, vector
<pair
<int, string
>>> &name
) {
236 if (name
.type() == typeid(DNSName
)) {
237 auto n
= boost::get
<DNSName
>(name
);
241 if (name
.type() == typeid(string
)) {
242 auto n
= boost::get
<string
>(name
);
246 if (name
.type() == typeid(vector
<pair
<int, DNSName
>>)) {
247 auto names
= boost::get
<vector
<pair
<int, DNSName
>>>(name
);
248 for (const auto& n
: names
) {
253 if (name
.type() == typeid(vector
<pair
<int, string
>>)) {
254 auto names
= boost::get
<vector
<pair
<int, string
>>>(name
);
255 for (const auto& n
: names
) {
261 g_lua
.registerFunction
<void (SuffixMatchNode::*)(const boost::variant
<DNSName
, string
, vector
<pair
<int, DNSName
>>, vector
<pair
<int, string
>>> &name
)>("remove", [](SuffixMatchNode
&smn
, const boost::variant
<DNSName
, string
, vector
<pair
<int, DNSName
>>, vector
<pair
<int, string
>>> &name
) {
262 if (name
.type() == typeid(DNSName
)) {
263 auto n
= boost::get
<DNSName
>(name
);
267 if (name
.type() == typeid(string
)) {
268 auto n
= boost::get
<string
>(name
);
273 if (name
.type() == typeid(vector
<pair
<int, DNSName
>>)) {
274 auto names
= boost::get
<vector
<pair
<int, DNSName
>>>(name
);
275 for (const auto& n
: names
) {
276 smn
.remove(n
.second
);
280 if (name
.type() == typeid(vector
<pair
<int, string
>>)) {
281 auto names
= boost::get
<vector
<pair
<int, string
>>>(name
);
282 for (const auto& n
: names
) {
290 g_lua
.registerFunction("check",(bool (SuffixMatchNode::*)(const DNSName
&) const) &SuffixMatchNode::check
);
293 g_lua
.writeFunction("newNetmask", [](boost::variant
<std::string
,ComboAddress
> s
, boost::optional
<uint8_t> bits
) {
294 if (s
.type() == typeid(ComboAddress
)) {
295 auto ca
= boost::get
<ComboAddress
>(s
);
297 return Netmask(ca
, *bits
);
301 else if (s
.type() == typeid(std::string
)) {
302 auto str
= boost::get
<std::string
>(s
);
305 throw std::runtime_error("Invalid parameter passed to 'newNetmask()'");
307 g_lua
.registerFunction("empty", &Netmask::empty
);
308 g_lua
.registerFunction("getBits", &Netmask::getBits
);
309 g_lua
.registerFunction
<ComboAddress(Netmask::*)()>("getNetwork", [](const Netmask
& nm
) { return nm
.getNetwork(); } ); // const reference makes this necessary
310 g_lua
.registerFunction
<ComboAddress(Netmask::*)()>("getMaskedNetwork", [](const Netmask
& nm
) { return nm
.getMaskedNetwork(); } );
311 g_lua
.registerFunction("isIpv4", &Netmask::isIPv4
);
312 g_lua
.registerFunction("isIPv4", &Netmask::isIPv4
);
313 g_lua
.registerFunction("isIpv6", &Netmask::isIPv6
);
314 g_lua
.registerFunction("isIPv6", &Netmask::isIPv6
);
315 g_lua
.registerFunction("match", (bool (Netmask::*)(const string
&) const)&Netmask::match
);
316 g_lua
.registerFunction("toString", &Netmask::toString
);
317 g_lua
.registerEqFunction(&Netmask::operator==);
318 g_lua
.registerToStringFunction(&Netmask::toString
);
321 g_lua
.writeFunction("newNMG", []() { return NetmaskGroup(); });
322 g_lua
.registerFunction
<void(NetmaskGroup::*)(const std::string
&mask
)>("addMask", [](NetmaskGroup
&nmg
, const std::string
& mask
)
326 g_lua
.registerFunction
<void(NetmaskGroup::*)(const std::map
<ComboAddress
,int>& map
)>("addMasks", [](NetmaskGroup
&nmg
, const std::map
<ComboAddress
,int>& map
)
328 for (const auto& entry
: map
) {
329 nmg
.addMask(Netmask(entry
.first
));
333 g_lua
.registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress
&) const)&NetmaskGroup::match
);
334 g_lua
.registerFunction("size", &NetmaskGroup::size
);
335 g_lua
.registerFunction("clear", &NetmaskGroup::clear
);
336 g_lua
.registerFunction
<string(NetmaskGroup::*)()>("toString", [](const NetmaskGroup
& nmg
) { return "NetmaskGroup " + nmg
.toString(); });
339 g_lua
.writeFunction("newQPSLimiter", [](int rate
, int burst
) { return QPSLimiter(rate
, burst
); });
340 g_lua
.registerFunction("check", &QPSLimiter::check
);
343 g_lua
.registerFunction
<std::string(ClientState::*)()>("toString", [](const ClientState
& fe
) {
344 setLuaNoSideEffect();
345 return fe
.local
.toStringWithPort();
347 g_lua
.registerMember("muted", &ClientState::muted
);
349 g_lua
.registerFunction
<void(ClientState::*)(std::shared_ptr
<BPFFilter
>)>("attachFilter", [](ClientState
& frontend
, std::shared_ptr
<BPFFilter
> bpf
) {
351 frontend
.attachFilter(bpf
);
354 g_lua
.registerFunction
<void(ClientState::*)()>("detachFilter", [](ClientState
& frontend
) {
355 frontend
.detachFilter();
357 #endif /* HAVE_EBPF */
361 g_lua
.writeFunction("newBPFFilter", [client
](uint32_t maxV4
, uint32_t maxV6
, uint32_t maxQNames
) {
363 return std::shared_ptr
<BPFFilter
>(nullptr);
365 return std::make_shared
<BPFFilter
>(maxV4
, maxV6
, maxQNames
);
368 g_lua
.registerFunction
<void(std::shared_ptr
<BPFFilter
>::*)(const ComboAddress
& ca
)>("block", [](std::shared_ptr
<BPFFilter
> bpf
, const ComboAddress
& ca
) {
370 return bpf
->block(ca
);
374 g_lua
.registerFunction
<void(std::shared_ptr
<BPFFilter
>::*)(const DNSName
& qname
, boost::optional
<uint16_t> qtype
)>("blockQName", [](std::shared_ptr
<BPFFilter
> bpf
, const DNSName
& qname
, boost::optional
<uint16_t> qtype
) {
376 return bpf
->block(qname
, qtype
? *qtype
: 255);
380 g_lua
.registerFunction
<void(std::shared_ptr
<BPFFilter
>::*)(const ComboAddress
& ca
)>("unblock", [](std::shared_ptr
<BPFFilter
> bpf
, const ComboAddress
& ca
) {
382 return bpf
->unblock(ca
);
386 g_lua
.registerFunction
<void(std::shared_ptr
<BPFFilter
>::*)(const DNSName
& qname
, boost::optional
<uint16_t> qtype
)>("unblockQName", [](std::shared_ptr
<BPFFilter
> bpf
, const DNSName
& qname
, boost::optional
<uint16_t> qtype
) {
388 return bpf
->unblock(qname
, qtype
? *qtype
: 255);
392 g_lua
.registerFunction
<std::string(std::shared_ptr
<BPFFilter
>::*)()>("getStats", [](const std::shared_ptr
<BPFFilter
> bpf
) {
393 setLuaNoSideEffect();
396 std::vector
<std::pair
<ComboAddress
, uint64_t> > stats
= bpf
->getAddrStats();
397 for (const auto& value
: stats
) {
398 if (value
.first
.sin4
.sin_family
== AF_INET
) {
399 res
+= value
.first
.toString() + ": " + std::to_string(value
.second
) + "\n";
401 else if (value
.first
.sin4
.sin_family
== AF_INET6
) {
402 res
+= "[" + value
.first
.toString() + "]: " + std::to_string(value
.second
) + "\n";
405 std::vector
<std::tuple
<DNSName
, uint16_t, uint64_t> > qstats
= bpf
->getQNameStats();
406 for (const auto& value
: qstats
) {
407 res
+= std::get
<0>(value
).toString() + " " + std::to_string(std::get
<1>(value
)) + ": " + std::to_string(std::get
<2>(value
)) + "\n";
413 g_lua
.registerFunction
<void(std::shared_ptr
<BPFFilter
>::*)()>("attachToAllBinds", [](std::shared_ptr
<BPFFilter
> bpf
) {
416 for (const auto& frontend
: g_frontends
) {
417 frontend
->attachFilter(bpf
);
422 g_lua
.writeFunction("newDynBPFFilter", [client
](std::shared_ptr
<BPFFilter
> bpf
) {
424 return std::shared_ptr
<DynBPFFilter
>(nullptr);
426 return std::make_shared
<DynBPFFilter
>(bpf
);
429 g_lua
.registerFunction
<void(std::shared_ptr
<DynBPFFilter
>::*)(const ComboAddress
& addr
, boost::optional
<int> seconds
)>("block", [](std::shared_ptr
<DynBPFFilter
> dbpf
, const ComboAddress
& addr
, boost::optional
<int> seconds
) {
431 struct timespec until
;
432 clock_gettime(CLOCK_MONOTONIC
, &until
);
433 until
.tv_sec
+= seconds
? *seconds
: 10;
434 dbpf
->block(addr
, until
);
438 g_lua
.registerFunction
<void(std::shared_ptr
<DynBPFFilter
>::*)()>("purgeExpired", [](std::shared_ptr
<DynBPFFilter
> dbpf
) {
441 clock_gettime(CLOCK_MONOTONIC
, &now
);
442 dbpf
->purgeExpired(now
);
446 g_lua
.registerFunction
<void(std::shared_ptr
<DynBPFFilter
>::*)(boost::variant
<std::string
, std::vector
<std::pair
<int, std::string
>>>)>("excludeRange", [](std::shared_ptr
<DynBPFFilter
> dbpf
, boost::variant
<std::string
, std::vector
<std::pair
<int, std::string
>>> ranges
) {
447 if (ranges
.type() == typeid(std::vector
<std::pair
<int, std::string
>>)) {
448 for (const auto& range
: *boost::get
<std::vector
<std::pair
<int, std::string
>>>(&ranges
)) {
449 dbpf
->excludeRange(Netmask(range
.second
));
453 dbpf
->excludeRange(Netmask(*boost::get
<std::string
>(&ranges
)));
457 g_lua
.registerFunction
<void(std::shared_ptr
<DynBPFFilter
>::*)(boost::variant
<std::string
, std::vector
<std::pair
<int, std::string
>>>)>("includeRange", [](std::shared_ptr
<DynBPFFilter
> dbpf
, boost::variant
<std::string
, std::vector
<std::pair
<int, std::string
>>> ranges
) {
458 if (ranges
.type() == typeid(std::vector
<std::pair
<int, std::string
>>)) {
459 for (const auto& range
: *boost::get
<std::vector
<std::pair
<int, std::string
>>>(&ranges
)) {
460 dbpf
->includeRange(Netmask(range
.second
));
464 dbpf
->includeRange(Netmask(*boost::get
<std::string
>(&ranges
)));
467 #endif /* HAVE_EBPF */
470 g_lua
.registerFunction
<size_t(EDNSOptionView::*)()>("count", [](const EDNSOptionView
& option
) {
471 return option
.values
.size();
473 g_lua
.registerFunction
<std::vector
<string
>(EDNSOptionView::*)()>("getValues", [] (const EDNSOptionView
& option
) {
474 std::vector
<string
> values
;
475 for (const auto& value
: option
.values
) {
476 values
.push_back(std::string(value
.content
, value
.size
));
481 g_lua
.writeFunction("newDOHResponseMapEntry", [](const std::string
& regex
, uint16_t status
, const std::string
& content
, boost::optional
<std::map
<std::string
, std::string
>> customHeaders
) {
482 boost::optional
<std::vector
<std::pair
<std::string
, std::string
>>> headers
{boost::none
};
484 headers
= std::vector
<std::pair
<std::string
, std::string
>>();
485 for (const auto& header
: *customHeaders
) {
486 headers
->push_back({ boost::to_lower_copy(header
.first
), header
.second
});
489 return std::make_shared
<DOHResponseMapEntry
>(regex
, status
, content
, headers
);