]>
Commit | Line | Data |
---|---|---|
6bb38cd6 RG |
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 | */ | |
f037144c RG |
22 | #include <fcntl.h> |
23 | #include <sys/stat.h> | |
24 | #include <sys/types.h> | |
25 | ||
f4b1f1fd | 26 | #include "config.h" |
6bb38cd6 RG |
27 | #include "dnsdist.hh" |
28 | #include "dnsdist-lua.hh" | |
29 | #include "dnsdist-protobuf.hh" | |
30 | ||
82a91ddf | 31 | #include "dnstap.hh" |
6bb38cd6 | 32 | #include "dolog.hh" |
82a91ddf | 33 | #include "fstrm_logger.hh" |
6bb38cd6 RG |
34 | #include "remote_logger.hh" |
35 | ||
f4b1f1fd | 36 | #ifdef HAVE_LIBCRYPTO |
5d5d8c2e | 37 | #include "ipcipher.hh" |
f4b1f1fd | 38 | #endif /* HAVE_LIBCRYPTO */ |
6bb38cd6 RG |
39 | |
40 | void setupLuaBindings(bool client) | |
41 | { | |
42 | g_lua.writeFunction("infolog", [](const string& arg) { | |
43 | infolog("%s", arg); | |
44 | }); | |
45 | g_lua.writeFunction("errlog", [](const string& arg) { | |
46 | errlog("%s", arg); | |
47 | }); | |
48 | g_lua.writeFunction("warnlog", [](const string& arg) { | |
49 | warnlog("%s", arg); | |
50 | }); | |
51 | g_lua.writeFunction("show", [](const string& arg) { | |
52 | g_outputBuffer+=arg; | |
53 | g_outputBuffer+="\n"; | |
54 | }); | |
55 | ||
f5aff975 CHB |
56 | /* Exceptions */ |
57 | g_lua.registerFunction<string(std::exception_ptr::*)()>("__tostring", [](const std::exception_ptr& eptr) { | |
58 | try { | |
59 | if (eptr) { | |
60 | std::rethrow_exception(eptr); | |
61 | } | |
62 | } catch(const std::exception& e) { | |
63 | return string(e.what()); | |
64 | } catch(const PDNSException& e) { | |
65 | return e.reason; | |
66 | } catch(...) { | |
67 | return string("Unknown exception"); | |
68 | } | |
69 | return string("No exception"); | |
70 | }); | |
6bb38cd6 | 71 | /* ServerPolicy */ |
a1b1a29d | 72 | g_lua.writeFunction("newServerPolicy", [](string name, policyfunc_t policy) { return ServerPolicy{name, policy, true};}); |
6bb38cd6 RG |
73 | g_lua.registerMember("name", &ServerPolicy::name); |
74 | g_lua.registerMember("policy", &ServerPolicy::policy); | |
a1b1a29d | 75 | g_lua.registerMember("isLua", &ServerPolicy::isLua); |
a4fd2d2f | 76 | g_lua.registerFunction("toString", &ServerPolicy::toString); |
6bb38cd6 | 77 | |
a1b1a29d RG |
78 | g_lua.writeVariable("firstAvailable", ServerPolicy{"firstAvailable", firstAvailable, false}); |
79 | g_lua.writeVariable("roundrobin", ServerPolicy{"roundrobin", roundrobin, false}); | |
80 | g_lua.writeVariable("wrandom", ServerPolicy{"wrandom", wrandom, false}); | |
81 | g_lua.writeVariable("whashed", ServerPolicy{"whashed", whashed, false}); | |
1720247e | 82 | g_lua.writeVariable("chashed", ServerPolicy{"chashed", chashed, false}); |
a1b1a29d | 83 | g_lua.writeVariable("leastOutstanding", ServerPolicy{"leastOutstanding", leastOutstanding, false}); |
6bb38cd6 RG |
84 | |
85 | /* ServerPool */ | |
86 | g_lua.registerFunction<void(std::shared_ptr<ServerPool>::*)(std::shared_ptr<DNSDistPacketCache>)>("setCache", [](std::shared_ptr<ServerPool> pool, std::shared_ptr<DNSDistPacketCache> cache) { | |
87 | if (pool) { | |
88 | pool->packetCache = cache; | |
89 | } | |
90 | }); | |
91 | g_lua.registerFunction("getCache", &ServerPool::getCache); | |
92 | g_lua.registerFunction<void(std::shared_ptr<ServerPool>::*)()>("unsetCache", [](std::shared_ptr<ServerPool> pool) { | |
93 | if (pool) { | |
94 | pool->packetCache = nullptr; | |
95 | } | |
96 | }); | |
7e687744 RG |
97 | g_lua.registerFunction("getECS", &ServerPool::getECS); |
98 | g_lua.registerFunction("setECS", &ServerPool::setECS); | |
6bb38cd6 RG |
99 | |
100 | /* DownstreamState */ | |
101 | g_lua.registerFunction<void(DownstreamState::*)(int)>("setQPS", [](DownstreamState& s, int lim) { s.qps = lim ? QPSLimiter(lim, lim) : QPSLimiter(); }); | |
102 | g_lua.registerFunction<void(std::shared_ptr<DownstreamState>::*)(string)>("addPool", [](std::shared_ptr<DownstreamState> s, string pool) { | |
103 | auto localPools = g_pools.getCopy(); | |
104 | addServerToPool(localPools, pool, s); | |
105 | g_pools.setState(localPools); | |
106 | s->pools.insert(pool); | |
107 | }); | |
108 | g_lua.registerFunction<void(std::shared_ptr<DownstreamState>::*)(string)>("rmPool", [](std::shared_ptr<DownstreamState> s, string pool) { | |
109 | auto localPools = g_pools.getCopy(); | |
110 | removeServerFromPool(localPools, pool, s); | |
111 | g_pools.setState(localPools); | |
112 | s->pools.erase(pool); | |
113 | }); | |
2831298d | 114 | g_lua.registerFunction<uint64_t(DownstreamState::*)()>("getOutstanding", [](const DownstreamState& s) { return s.outstanding.load(); }); |
6bb38cd6 RG |
115 | g_lua.registerFunction("isUp", &DownstreamState::isUp); |
116 | g_lua.registerFunction("setDown", &DownstreamState::setDown); | |
117 | g_lua.registerFunction("setUp", &DownstreamState::setUp); | |
118 | g_lua.registerFunction<void(DownstreamState::*)(boost::optional<bool> newStatus)>("setAuto", [](DownstreamState& s, boost::optional<bool> newStatus) { | |
119 | if (newStatus) { | |
120 | s.upStatus = *newStatus; | |
121 | } | |
122 | s.setAuto(); | |
123 | }); | |
124 | g_lua.registerFunction("getName", &DownstreamState::getName); | |
125 | g_lua.registerFunction("getNameWithAddr", &DownstreamState::getNameWithAddr); | |
126 | g_lua.registerMember("upStatus", &DownstreamState::upStatus); | |
5a2bbe8c CHB |
127 | g_lua.registerMember<int (DownstreamState::*)>("weight", |
128 | [](const DownstreamState& s) -> int {return s.weight;}, | |
129 | [](DownstreamState& s, int newWeight) {s.setWeight(newWeight);} | |
130 | ); | |
6bb38cd6 RG |
131 | g_lua.registerMember("order", &DownstreamState::order); |
132 | g_lua.registerMember("name", &DownstreamState::name); | |
133 | ||
134 | /* dnsheader */ | |
135 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setRD", [](dnsheader& dh, bool v) { | |
136 | dh.rd=v; | |
137 | }); | |
138 | ||
139 | g_lua.registerFunction<bool(dnsheader::*)()>("getRD", [](dnsheader& dh) { | |
140 | return (bool)dh.rd; | |
141 | }); | |
142 | ||
143 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) { | |
144 | dh.cd=v; | |
145 | }); | |
146 | ||
147 | g_lua.registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) { | |
148 | return (bool)dh.cd; | |
149 | }); | |
150 | ||
151 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) { | |
152 | dh.tc=v; | |
153 | if(v) dh.ra = dh.rd; // you'll always need this, otherwise TC=1 gets ignored | |
154 | }); | |
155 | ||
156 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setQR", [](dnsheader& dh, bool v) { | |
157 | dh.qr=v; | |
158 | }); | |
159 | ||
160 | /* ComboAddress */ | |
161 | g_lua.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); }); | |
162 | g_lua.registerFunction<string(ComboAddress::*)()>("tostring", [](const ComboAddress& ca) { return ca.toString(); }); | |
163 | g_lua.registerFunction<string(ComboAddress::*)()>("tostringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); }); | |
164 | g_lua.registerFunction<string(ComboAddress::*)()>("toString", [](const ComboAddress& ca) { return ca.toString(); }); | |
165 | g_lua.registerFunction<string(ComboAddress::*)()>("toStringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); }); | |
166 | g_lua.registerFunction<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } ); | |
167 | g_lua.registerFunction<void(ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress& ca, unsigned int bits) { ca.truncate(bits); }); | |
168 | g_lua.registerFunction<bool(ComboAddress::*)()>("isIPv4", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET; }); | |
169 | g_lua.registerFunction<bool(ComboAddress::*)()>("isIPv6", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET6; }); | |
170 | g_lua.registerFunction<bool(ComboAddress::*)()>("isMappedIPv4", [](const ComboAddress& ca) { return ca.isMappedIPv4(); }); | |
171 | g_lua.registerFunction<ComboAddress(ComboAddress::*)()>("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); }); | |
172 | g_lua.registerFunction<bool(nmts_t::*)(const ComboAddress&)>("match", [](nmts_t& s, const ComboAddress& ca) { return s.match(ca); }); | |
173 | ||
f4b1f1fd | 174 | #ifdef HAVE_LIBCRYPTO |
7d280342 | 175 | g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipencrypt", [](const ComboAddress& ca, const std::string& key) { |
176 | return encryptCA(ca, key); | |
177 | }); | |
178 | g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipdecrypt", [](const ComboAddress& ca, const std::string& key) { | |
179 | return decryptCA(ca, key); | |
180 | }); | |
01223eb9 | 181 | |
182 | g_lua.writeFunction("makeIPCipherKey", [](const std::string& password) { | |
183 | return makeIPCipherKey(password); | |
184 | }); | |
f4b1f1fd | 185 | #endif /* HAVE_LIBCRYPTO */ |
488bcb39 | 186 | |
6bb38cd6 RG |
187 | /* DNSName */ |
188 | g_lua.registerFunction("isPartOf", &DNSName::isPartOf); | |
189 | g_lua.registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); }); | |
190 | g_lua.registerFunction<unsigned int(DNSName::*)()>("countLabels", [](const DNSName& name) { return name.countLabels(); }); | |
191 | g_lua.registerFunction<size_t(DNSName::*)()>("wirelength", [](const DNSName& name) { return name.wirelength(); }); | |
192 | g_lua.registerFunction<string(DNSName::*)()>("tostring", [](const DNSName&dn ) { return dn.toString(); }); | |
193 | g_lua.registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); }); | |
194 | g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); }); | |
195 | g_lua.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); }); | |
9f618bcc AD |
196 | g_lua.writeFunction("newDNSNameSet", []() { return DNSNameSet(); }); |
197 | ||
198 | /* DNSNameSet */ | |
199 | g_lua.registerFunction<string(DNSNameSet::*)()>("toString", [](const DNSNameSet&dns ) { return dns.toString(); }); | |
200 | g_lua.registerFunction<void(DNSNameSet::*)(DNSName&)>("add", [](DNSNameSet& dns, DNSName& dn) { dns.insert(dn); }); | |
cc0e7aa9 | 201 | g_lua.registerFunction<bool(DNSNameSet::*)(DNSName&)>("check", [](DNSNameSet& dns, DNSName& dn) { return dns.find(dn) != dns.end(); }); |
9f618bcc AD |
202 | g_lua.registerFunction("delete",(size_t (DNSNameSet::*)(const DNSName&)) &DNSNameSet::erase); |
203 | g_lua.registerFunction("size",(size_t (DNSNameSet::*)() const) &DNSNameSet::size); | |
204 | g_lua.registerFunction("clear",(void (DNSNameSet::*)()) &DNSNameSet::clear); | |
205 | g_lua.registerFunction("empty",(bool (DNSNameSet::*)()) &DNSNameSet::empty); | |
6bb38cd6 RG |
206 | |
207 | /* SuffixMatchNode */ | |
41ff82c9 PL |
208 | 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) { |
209 | if (name.type() == typeid(DNSName)) { | |
210 | auto n = boost::get<DNSName>(name); | |
211 | smn.add(n); | |
212 | return; | |
213 | } | |
214 | if (name.type() == typeid(string)) { | |
215 | auto n = boost::get<string>(name); | |
216 | smn.add(n); | |
217 | return; | |
218 | } | |
219 | if (name.type() == typeid(vector<pair<int, DNSName>>)) { | |
220 | auto names = boost::get<vector<pair<int, DNSName>>>(name); | |
221 | for (auto const n : names) { | |
222 | smn.add(n.second); | |
223 | } | |
224 | return; | |
225 | } | |
226 | if (name.type() == typeid(vector<pair<int, string>>)) { | |
227 | auto names = boost::get<vector<pair<int, string>>>(name); | |
228 | for (auto const n : names) { | |
229 | smn.add(n.second); | |
230 | } | |
231 | return; | |
232 | } | |
233 | }); | |
6bb38cd6 RG |
234 | g_lua.registerFunction("check",(bool (SuffixMatchNode::*)(const DNSName&) const) &SuffixMatchNode::check); |
235 | ||
236 | /* NetmaskGroup */ | |
237 | g_lua.writeFunction("newNMG", []() { return NetmaskGroup(); }); | |
238 | g_lua.registerFunction<void(NetmaskGroup::*)(const std::string&mask)>("addMask", [](NetmaskGroup&nmg, const std::string& mask) | |
239 | { | |
240 | nmg.addMask(mask); | |
241 | }); | |
242 | g_lua.registerFunction<void(NetmaskGroup::*)(const std::map<ComboAddress,int>& map)>("addMasks", [](NetmaskGroup&nmg, const std::map<ComboAddress,int>& map) | |
243 | { | |
244 | for (const auto& entry : map) { | |
245 | nmg.addMask(Netmask(entry.first)); | |
246 | } | |
247 | }); | |
248 | ||
249 | g_lua.registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress&) const)&NetmaskGroup::match); | |
250 | g_lua.registerFunction("size", &NetmaskGroup::size); | |
251 | g_lua.registerFunction("clear", &NetmaskGroup::clear); | |
a4fd2d2f | 252 | g_lua.registerFunction<string(NetmaskGroup::*)()>("toString", [](const NetmaskGroup& nmg ) { return "NetmaskGroup " + nmg.toString(); }); |
6bb38cd6 RG |
253 | |
254 | /* QPSLimiter */ | |
255 | g_lua.writeFunction("newQPSLimiter", [](int rate, int burst) { return QPSLimiter(rate, burst); }); | |
256 | g_lua.registerFunction("check", &QPSLimiter::check); | |
257 | ||
258 | /* ClientState */ | |
259 | g_lua.registerFunction<std::string(ClientState::*)()>("toString", [](const ClientState& fe) { | |
260 | setLuaNoSideEffect(); | |
261 | return fe.local.toStringWithPort(); | |
262 | }); | |
263 | g_lua.registerMember("muted", &ClientState::muted); | |
264 | #ifdef HAVE_EBPF | |
265 | g_lua.registerFunction<void(ClientState::*)(std::shared_ptr<BPFFilter>)>("attachFilter", [](ClientState& frontend, std::shared_ptr<BPFFilter> bpf) { | |
266 | if (bpf) { | |
267 | frontend.attachFilter(bpf); | |
268 | } | |
269 | }); | |
270 | g_lua.registerFunction<void(ClientState::*)()>("detachFilter", [](ClientState& frontend) { | |
271 | frontend.detachFilter(); | |
272 | }); | |
273 | #endif /* HAVE_EBPF */ | |
274 | ||
275 | /* PacketCache */ | |
7d294573 | 276 | g_lua.writeFunction("newPacketCache", [](size_t maxEntries, boost::optional<std::unordered_map<std::string, boost::variant<bool, size_t>>> vars) { |
c1b81381 RG |
277 | |
278 | bool keepStaleData = false; | |
7d294573 RG |
279 | size_t maxTTL = 86400; |
280 | size_t minTTL = 0; | |
281 | size_t tempFailTTL = 60; | |
282 | size_t maxNegativeTTL = 3600; | |
283 | size_t staleTTL = 60; | |
284 | size_t numberOfShards = 1; | |
285 | bool dontAge = false; | |
286 | bool deferrableInsertLock = true; | |
287 | bool ecsParsing = false; | |
c1b81381 RG |
288 | |
289 | if (vars) { | |
290 | ||
291 | if (vars->count("deferrableInsertLock")) { | |
292 | deferrableInsertLock = boost::get<bool>((*vars)["deferrableInsertLock"]); | |
293 | } | |
294 | ||
295 | if (vars->count("dontAge")) { | |
296 | dontAge = boost::get<bool>((*vars)["dontAge"]); | |
297 | } | |
298 | ||
299 | if (vars->count("keepStaleData")) { | |
300 | keepStaleData = boost::get<bool>((*vars)["keepStaleData"]); | |
301 | } | |
302 | ||
c1b81381 RG |
303 | if (vars->count("maxNegativeTTL")) { |
304 | maxNegativeTTL = boost::get<size_t>((*vars)["maxNegativeTTL"]); | |
305 | } | |
306 | ||
307 | if (vars->count("maxTTL")) { | |
308 | maxTTL = boost::get<size_t>((*vars)["maxTTL"]); | |
309 | } | |
310 | ||
311 | if (vars->count("minTTL")) { | |
312 | minTTL = boost::get<size_t>((*vars)["minTTL"]); | |
313 | } | |
314 | ||
315 | if (vars->count("numberOfShards")) { | |
316 | numberOfShards = boost::get<size_t>((*vars)["numberOfShards"]); | |
317 | } | |
318 | ||
319 | if (vars->count("parseECS")) { | |
320 | ecsParsing = boost::get<bool>((*vars)["parseECS"]); | |
321 | } | |
322 | ||
323 | if (vars->count("staleTTL")) { | |
324 | staleTTL = boost::get<size_t>((*vars)["staleTTL"]); | |
325 | } | |
326 | ||
327 | if (vars->count("temporaryFailureTTL")) { | |
328 | tempFailTTL = boost::get<size_t>((*vars)["temporaryFailureTTL"]); | |
329 | } | |
c1b81381 RG |
330 | } |
331 | ||
7d294573 | 332 | auto res = std::make_shared<DNSDistPacketCache>(maxEntries, maxTTL, minTTL, tempFailTTL, maxNegativeTTL, staleTTL, dontAge, numberOfShards, deferrableInsertLock, ecsParsing); |
c1b81381 RG |
333 | |
334 | res->setKeepStaleData(keepStaleData); | |
335 | ||
336 | return res; | |
6bb38cd6 RG |
337 | }); |
338 | g_lua.registerFunction("toString", &DNSDistPacketCache::toString); | |
339 | g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull); | |
340 | g_lua.registerFunction("purgeExpired", &DNSDistPacketCache::purgeExpired); | |
341 | g_lua.registerFunction("expunge", &DNSDistPacketCache::expunge); | |
342 | g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const DNSName& dname, boost::optional<uint16_t> qtype, boost::optional<bool> suffixMatch)>("expungeByName", []( | |
343 | std::shared_ptr<DNSDistPacketCache> cache, | |
344 | const DNSName& dname, | |
345 | boost::optional<uint16_t> qtype, | |
346 | boost::optional<bool> suffixMatch) { | |
347 | if (cache) { | |
6ed24ca0 | 348 | g_outputBuffer="Expunged " + std::to_string(cache->expungeByName(dname, qtype ? *qtype : QType(QType::ANY).getCode(), suffixMatch ? *suffixMatch : false)) + " records\n"; |
6bb38cd6 RG |
349 | } |
350 | }); | |
351 | g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)()>("printStats", [](const std::shared_ptr<DNSDistPacketCache> cache) { | |
352 | if (cache) { | |
353 | g_outputBuffer="Entries: " + std::to_string(cache->getEntriesCount()) + "/" + std::to_string(cache->getMaxEntries()) + "\n"; | |
354 | g_outputBuffer+="Hits: " + std::to_string(cache->getHits()) + "\n"; | |
355 | g_outputBuffer+="Misses: " + std::to_string(cache->getMisses()) + "\n"; | |
356 | g_outputBuffer+="Deferred inserts: " + std::to_string(cache->getDeferredInserts()) + "\n"; | |
357 | g_outputBuffer+="Deferred lookups: " + std::to_string(cache->getDeferredLookups()) + "\n"; | |
358 | g_outputBuffer+="Lookup Collisions: " + std::to_string(cache->getLookupCollisions()) + "\n"; | |
359 | g_outputBuffer+="Insert Collisions: " + std::to_string(cache->getInsertCollisions()) + "\n"; | |
360 | g_outputBuffer+="TTL Too Shorts: " + std::to_string(cache->getTTLTooShorts()) + "\n"; | |
361 | } | |
362 | }); | |
c1b81381 RG |
363 | g_lua.registerFunction<std::unordered_map<std::string, uint64_t>(std::shared_ptr<DNSDistPacketCache>::*)()>("getStats", [](const std::shared_ptr<DNSDistPacketCache> cache) { |
364 | std::unordered_map<std::string, uint64_t> stats; | |
365 | if (cache) { | |
366 | stats["entries"] = cache->getEntriesCount(); | |
367 | stats["maxEntries"] = cache->getMaxEntries(); | |
368 | stats["hits"] = cache->getHits(); | |
369 | stats["misses"] = cache->getMisses(); | |
370 | stats["deferredInserts"] = cache->getDeferredInserts(); | |
371 | stats["deferredLookups"] = cache->getDeferredLookups(); | |
372 | stats["lookupCollisions"] = cache->getLookupCollisions(); | |
373 | stats["insertCollisions"] = cache->getInsertCollisions(); | |
374 | stats["ttlTooShorts"] = cache->getTTLTooShorts(); | |
375 | } | |
376 | return stats; | |
377 | }); | |
f037144c RG |
378 | g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const std::string& fname)>("dump", [](const std::shared_ptr<DNSDistPacketCache> cache, const std::string& fname) { |
379 | if (cache) { | |
380 | ||
381 | int fd = open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660); | |
382 | if (fd < 0) { | |
383 | g_outputBuffer = "Error opening dump file for writing: " + string(strerror(errno)) + "\n"; | |
384 | return; | |
385 | } | |
386 | ||
387 | uint64_t records = 0; | |
388 | try { | |
389 | records = cache->dump(fd); | |
390 | } | |
391 | catch (const std::exception& e) { | |
392 | close(fd); | |
393 | throw; | |
394 | } | |
395 | ||
396 | close(fd); | |
397 | ||
398 | g_outputBuffer += "Dumped " + std::to_string(records) + " records\n"; | |
399 | } | |
400 | }); | |
6bb38cd6 RG |
401 | |
402 | /* ProtobufMessage */ | |
403 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(std::string)>("setTag", [](DNSDistProtoBufMessage& message, const std::string& strValue) { | |
404 | message.addTag(strValue); | |
405 | }); | |
406 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(vector<pair<int, string>>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector<pair<int, string>>&tags) { | |
407 | for (const auto& tag : tags) { | |
408 | message.addTag(tag.second); | |
409 | } | |
410 | }); | |
411 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(boost::optional <time_t> sec, boost::optional <uint32_t> uSec)>("setProtobufResponseType", | |
412 | [](DNSDistProtoBufMessage& message, boost::optional <time_t> sec, boost::optional <uint32_t> uSec) { | |
413 | message.setType(DNSProtoBufMessage::Response); | |
414 | message.setQueryTime(sec?*sec:0, uSec?*uSec:0); | |
415 | }); | |
416 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob)>("addResponseRR", [](DNSDistProtoBufMessage& message, | |
417 | const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob) { | |
418 | message.addRR(DNSName(strQueryName), uType, uClass, uTTL, strBlob); | |
419 | }); | |
420 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const Netmask&)>("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); }); | |
421 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const DNSName&, uint16_t, uint16_t)>("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); }); | |
422 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(size_t)>("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); }); | |
423 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setTime(sec, usec); }); | |
424 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setQueryTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setQueryTime(sec, usec); }); | |
425 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(uint8_t)>("setResponseCode", [](DNSDistProtoBufMessage& message, uint8_t rcode) { message.setResponseCode(rcode); }); | |
426 | g_lua.registerFunction<std::string(DNSDistProtoBufMessage::*)()>("toDebugString", [](const DNSDistProtoBufMessage& message) { return message.toDebugString(); }); | |
427 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setRequestor", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { | |
428 | message.setRequestor(addr); | |
429 | }); | |
430 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setRequestorFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { | |
431 | message.setRequestor(str); | |
432 | }); | |
433 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setResponder", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { | |
434 | message.setResponder(addr); | |
435 | }); | |
436 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setResponderFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { | |
437 | message.setResponder(str); | |
438 | }); | |
312a09a6 RG |
439 | g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setServerIdentity", [](DNSDistProtoBufMessage& message, const std::string& str) { |
440 | message.setServerIdentity(str); | |
441 | }); | |
6bb38cd6 | 442 | |
82a91ddf CH |
443 | g_lua.registerFunction<std::string(DnstapMessage::*)()>("toDebugString", [](const DnstapMessage& message) { return message.toDebugString(); }); |
444 | g_lua.registerFunction<void(DnstapMessage::*)(const std::string&)>("setExtra", [](DnstapMessage& message, const std::string& str) { | |
445 | message.setExtra(str); | |
446 | }); | |
447 | ||
6bb38cd6 RG |
448 | /* RemoteLogger */ |
449 | g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional<uint16_t> timeout, boost::optional<uint64_t> maxQueuedEntries, boost::optional<uint8_t> reconnectWaitTime) { | |
da71b63b | 450 | return std::shared_ptr<RemoteLoggerInterface>(new RemoteLogger(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? (*maxQueuedEntries*100) : 10000, reconnectWaitTime ? *reconnectWaitTime : 1, client)); |
82a91ddf CH |
451 | }); |
452 | ||
453 | g_lua.writeFunction("newFrameStreamUnixLogger", [client](const std::string& address) { | |
82a91ddf | 454 | #ifdef HAVE_FSTRM |
6b44773a | 455 | return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_UNIX, address, !client)); |
82a91ddf CH |
456 | #else |
457 | throw std::runtime_error("fstrm support is required to build an AF_UNIX FrameStreamLogger"); | |
458 | #endif /* HAVE_FSTRM */ | |
459 | }); | |
460 | ||
461 | g_lua.writeFunction("newFrameStreamTcpLogger", [client](const std::string& address) { | |
82a91ddf | 462 | #if defined(HAVE_FSTRM) && defined(HAVE_FSTRM_TCP_WRITER_INIT) |
6b44773a | 463 | return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_INET, address, !client)); |
82a91ddf CH |
464 | #else |
465 | throw std::runtime_error("fstrm with TCP support is required to build an AF_INET FrameStreamLogger"); | |
466 | #endif /* HAVE_FSTRM */ | |
467 | }); | |
6bb38cd6 | 468 | |
a4fd2d2f CH |
469 | g_lua.registerFunction("toString", &RemoteLoggerInterface::toString); |
470 | ||
6bb38cd6 | 471 | #ifdef HAVE_DNSCRYPT |
43234e76 RG |
472 | /* DNSCryptContext bindings */ |
473 | g_lua.registerFunction<std::string(DNSCryptContext::*)()>("getProviderName", [](const DNSCryptContext& ctx) { return ctx.getProviderName().toStringNoDot(); }); | |
43234e76 RG |
474 | g_lua.registerFunction("markActive", &DNSCryptContext::markActive); |
475 | g_lua.registerFunction("markInactive", &DNSCryptContext::markInactive); | |
476 | g_lua.registerFunction("removeInactiveCertificate", &DNSCryptContext::removeInactiveCertificate); | |
477 | g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const std::string& certFile, const std::string& keyFile, boost::optional<bool> active)>("loadNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const std::string& certFile, const std::string& keyFile, boost::optional<bool> active) { | |
478 | ||
479 | if (ctx == nullptr) { | |
480 | throw std::runtime_error("DNSCryptContext::loadNewCertificate() called on a nil value"); | |
481 | } | |
482 | ||
483 | ctx->loadNewCertificate(certFile, keyFile, active ? *active : true); | |
484 | }); | |
485 | g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active)>("addNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active) { | |
486 | ||
487 | if (ctx == nullptr) { | |
488 | throw std::runtime_error("DNSCryptContext::addNewCertificate() called on a nil value"); | |
489 | } | |
490 | ||
491 | ctx->addNewCertificate(newCert, newKey, active ? *active : true); | |
492 | }); | |
493 | g_lua.registerFunction<std::map<int, std::shared_ptr<DNSCryptCertificatePair>>(std::shared_ptr<DNSCryptContext>::*)()>("getCertificatePairs", [](std::shared_ptr<DNSCryptContext> ctx) { | |
494 | std::map<int, std::shared_ptr<DNSCryptCertificatePair>> result; | |
495 | ||
496 | if (ctx != nullptr) { | |
497 | size_t idx = 1; | |
498 | for (auto pair : ctx->getCertificates()) { | |
499 | result[idx++] = pair; | |
6bb38cd6 RG |
500 | } |
501 | } | |
43234e76 RG |
502 | |
503 | return result; | |
504 | }); | |
c2baf928 | 505 | |
43234e76 RG |
506 | g_lua.registerFunction<std::shared_ptr<DNSCryptCertificatePair>(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) { |
507 | ||
508 | if (ctx == nullptr) { | |
509 | throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value"); | |
510 | } | |
511 | ||
512 | std::shared_ptr<DNSCryptCertificatePair> result = nullptr; | |
55710b0f RG |
513 | auto pairs = ctx->getCertificates(); |
514 | if (idx < pairs.size()) { | |
515 | result = pairs.at(idx); | |
43234e76 RG |
516 | } |
517 | ||
518 | return result; | |
519 | }); | |
520 | ||
c2baf928 | 521 | g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificate", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) { |
55710b0f RG |
522 | |
523 | if (ctx == nullptr) { | |
c2baf928 | 524 | throw std::runtime_error("DNSCryptContext::getCertificate() called on a nil value"); |
55710b0f RG |
525 | } |
526 | ||
527 | auto pairs = ctx->getCertificates(); | |
c2baf928 RG |
528 | if (idx < pairs.size()) { |
529 | return pairs.at(idx)->cert; | |
55710b0f RG |
530 | } |
531 | ||
c2baf928 | 532 | throw std::runtime_error("This DNSCrypt context has no certificate at index " + std::to_string(idx)); |
55710b0f RG |
533 | }); |
534 | ||
43234e76 RG |
535 | g_lua.registerFunction<std::string(std::shared_ptr<DNSCryptContext>::*)()>("printCertificates", [](const std::shared_ptr<DNSCryptContext> ctx) { |
536 | ostringstream ret; | |
537 | ||
538 | if (ctx != nullptr) { | |
539 | size_t idx = 1; | |
37b6d73d | 540 | boost::format fmt("%1$-3d %|5t|%2$-8d %|10t|%3$-7d %|20t|%4$-21.21s %|41t|%5$-21.21s"); |
43234e76 RG |
541 | ret << (fmt % "#" % "Serial" % "Version" % "From" % "To" ) << endl; |
542 | ||
543 | for (auto pair : ctx->getCertificates()) { | |
544 | const auto cert = pair->cert; | |
545 | const DNSCryptExchangeVersion version = DNSCryptContext::getExchangeVersion(cert); | |
546 | ||
547 | ret << (fmt % idx % cert.getSerial() % (version == DNSCryptExchangeVersion::VERSION1 ? 1 : 2) % DNSCryptContext::certificateDateToStr(cert.getTSStart()) % DNSCryptContext::certificateDateToStr(cert.getTSEnd())) << endl; | |
548 | } | |
549 | } | |
550 | ||
551 | return ret.str(); | |
552 | }); | |
553 | ||
554 | g_lua.registerFunction<void(DNSCryptContext::*)(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) { | |
555 | DNSCryptPrivateKey privateKey; | |
556 | DNSCryptCert cert; | |
557 | ||
558 | try { | |
559 | if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) { | |
560 | ctx.addNewCertificate(cert, privateKey); | |
561 | } | |
562 | } | |
563 | catch(const std::exception& e) { | |
564 | errlog(e.what()); | |
565 | g_outputBuffer="Error: "+string(e.what())+"\n"; | |
566 | } | |
567 | }); | |
568 | ||
569 | /* DNSCryptCertificatePair */ | |
570 | g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptCertificatePair>::*)()>("getCertificate", [](const std::shared_ptr<DNSCryptCertificatePair> pair) { | |
571 | if (pair == nullptr) { | |
572 | throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value"); | |
573 | } | |
574 | return pair->cert; | |
575 | }); | |
576 | g_lua.registerFunction<bool(std::shared_ptr<DNSCryptCertificatePair>::*)()>("isActive", [](const std::shared_ptr<DNSCryptCertificatePair> pair) { | |
577 | if (pair == nullptr) { | |
578 | throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value"); | |
6bb38cd6 | 579 | } |
43234e76 | 580 | return pair->active; |
6bb38cd6 RG |
581 | }); |
582 | ||
43234e76 RG |
583 | /* DNSCryptCert */ |
584 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.magic), sizeof(cert.magic)); }); | |
585 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.esVersion), sizeof(cert.esVersion)); }); | |
586 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.protocolMinorVersion), sizeof(cert.protocolMinorVersion)); }); | |
587 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signature), sizeof(cert.signature)); }); | |
588 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.resolverPK), sizeof(cert.signedData.resolverPK)); }); | |
589 | g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.clientMagic), sizeof(cert.signedData.clientMagic)); }); | |
590 | g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); }); | |
591 | g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); }); | |
592 | g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSEnd", [](const DNSCryptCert& cert) { return ntohl(cert.getTSEnd()); }); | |
6bb38cd6 RG |
593 | #endif |
594 | ||
595 | /* BPF Filter */ | |
596 | #ifdef HAVE_EBPF | |
597 | g_lua.writeFunction("newBPFFilter", [client](uint32_t maxV4, uint32_t maxV6, uint32_t maxQNames) { | |
598 | if (client) { | |
599 | return std::shared_ptr<BPFFilter>(nullptr); | |
600 | } | |
601 | return std::make_shared<BPFFilter>(maxV4, maxV6, maxQNames); | |
602 | }); | |
603 | ||
604 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("block", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) { | |
605 | if (bpf) { | |
606 | return bpf->block(ca); | |
607 | } | |
608 | }); | |
609 | ||
610 | 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) { | |
611 | if (bpf) { | |
612 | return bpf->block(qname, qtype ? *qtype : 255); | |
613 | } | |
614 | }); | |
615 | ||
616 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("unblock", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) { | |
617 | if (bpf) { | |
618 | return bpf->unblock(ca); | |
619 | } | |
620 | }); | |
621 | ||
622 | 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) { | |
623 | if (bpf) { | |
624 | return bpf->unblock(qname, qtype ? *qtype : 255); | |
625 | } | |
626 | }); | |
627 | ||
628 | g_lua.registerFunction<std::string(std::shared_ptr<BPFFilter>::*)()>("getStats", [](const std::shared_ptr<BPFFilter> bpf) { | |
629 | setLuaNoSideEffect(); | |
630 | std::string res; | |
631 | if (bpf) { | |
632 | std::vector<std::pair<ComboAddress, uint64_t> > stats = bpf->getAddrStats(); | |
633 | for (const auto& value : stats) { | |
634 | if (value.first.sin4.sin_family == AF_INET) { | |
635 | res += value.first.toString() + ": " + std::to_string(value.second) + "\n"; | |
636 | } | |
637 | else if (value.first.sin4.sin_family == AF_INET6) { | |
638 | res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n"; | |
639 | } | |
640 | } | |
641 | std::vector<std::tuple<DNSName, uint16_t, uint64_t> > qstats = bpf->getQNameStats(); | |
642 | for (const auto& value : qstats) { | |
643 | res += std::get<0>(value).toString() + " " + std::to_string(std::get<1>(value)) + ": " + std::to_string(std::get<2>(value)) + "\n"; | |
644 | } | |
645 | } | |
646 | return res; | |
647 | }); | |
648 | ||
649 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)()>("attachToAllBinds", [](std::shared_ptr<BPFFilter> bpf) { | |
650 | std::string res; | |
651 | if (bpf) { | |
652 | for (const auto& frontend : g_frontends) { | |
653 | frontend->attachFilter(bpf); | |
654 | } | |
655 | } | |
656 | }); | |
657 | ||
658 | g_lua.writeFunction("newDynBPFFilter", [client](std::shared_ptr<BPFFilter> bpf) { | |
659 | if (client) { | |
660 | return std::shared_ptr<DynBPFFilter>(nullptr); | |
661 | } | |
662 | return std::make_shared<DynBPFFilter>(bpf); | |
663 | }); | |
664 | ||
665 | 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) { | |
666 | if (dbpf) { | |
667 | struct timespec until; | |
668 | clock_gettime(CLOCK_MONOTONIC, &until); | |
669 | until.tv_sec += seconds ? *seconds : 10; | |
670 | dbpf->block(addr, until); | |
671 | } | |
672 | }); | |
673 | ||
674 | g_lua.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)()>("purgeExpired", [](std::shared_ptr<DynBPFFilter> dbpf) { | |
675 | if (dbpf) { | |
676 | struct timespec now; | |
677 | clock_gettime(CLOCK_MONOTONIC, &now); | |
678 | dbpf->purgeExpired(now); | |
679 | } | |
680 | }); | |
ee38369c RS |
681 | |
682 | 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) { | |
683 | if (ranges.type() == typeid(std::vector<std::pair<int, std::string>>)) { | |
684 | for (const auto& range : *boost::get<std::vector<std::pair<int, std::string>>>(&ranges)) { | |
685 | dbpf->excludeRange(Netmask(range.second)); | |
686 | } | |
687 | } | |
688 | else { | |
689 | dbpf->excludeRange(Netmask(*boost::get<std::string>(&ranges))); | |
690 | } | |
691 | }); | |
692 | ||
693 | 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) { | |
694 | if (ranges.type() == typeid(std::vector<std::pair<int, std::string>>)) { | |
695 | for (const auto& range : *boost::get<std::vector<std::pair<int, std::string>>>(&ranges)) { | |
696 | dbpf->includeRange(Netmask(range.second)); | |
697 | } | |
698 | } | |
699 | else { | |
700 | dbpf->includeRange(Netmask(*boost::get<std::string>(&ranges))); | |
701 | } | |
702 | }); | |
6bb38cd6 | 703 | #endif /* HAVE_EBPF */ |
cbf4e13a RG |
704 | |
705 | /* EDNSOptionView */ | |
706 | g_lua.registerFunction<size_t(EDNSOptionView::*)()>("count", [](const EDNSOptionView& option) { | |
707 | return option.values.size(); | |
708 | }); | |
0d51414d PD |
709 | g_lua.registerFunction<std::vector<string>(EDNSOptionView::*)()>("getValues", [] (const EDNSOptionView& option) { |
710 | std::vector<string> values; | |
cbf4e13a | 711 | for (const auto& value : option.values) { |
0d51414d | 712 | values.push_back(std::string(value.content, value.size)); |
cbf4e13a RG |
713 | } |
714 | return values; | |
715 | }); | |
6bb38cd6 | 716 | } |