]>
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 | */ | |
f4b1f1fd | 22 | #include "config.h" |
6bb38cd6 RG |
23 | #include "dnsdist.hh" |
24 | #include "dnsdist-lua.hh" | |
6bb38cd6 RG |
25 | |
26 | #include "dolog.hh" | |
6bb38cd6 RG |
27 | |
28 | void setupLuaBindings(bool client) | |
29 | { | |
30 | g_lua.writeFunction("infolog", [](const string& arg) { | |
31 | infolog("%s", arg); | |
32 | }); | |
33 | g_lua.writeFunction("errlog", [](const string& arg) { | |
34 | errlog("%s", arg); | |
35 | }); | |
36 | g_lua.writeFunction("warnlog", [](const string& arg) { | |
37 | warnlog("%s", arg); | |
38 | }); | |
39 | g_lua.writeFunction("show", [](const string& arg) { | |
40 | g_outputBuffer+=arg; | |
41 | g_outputBuffer+="\n"; | |
42 | }); | |
43 | ||
f5aff975 CHB |
44 | /* Exceptions */ |
45 | g_lua.registerFunction<string(std::exception_ptr::*)()>("__tostring", [](const std::exception_ptr& eptr) { | |
46 | try { | |
47 | if (eptr) { | |
48 | std::rethrow_exception(eptr); | |
49 | } | |
50 | } catch(const std::exception& e) { | |
51 | return string(e.what()); | |
52 | } catch(const PDNSException& e) { | |
53 | return e.reason; | |
54 | } catch(...) { | |
55 | return string("Unknown exception"); | |
56 | } | |
57 | return string("No exception"); | |
58 | }); | |
6bb38cd6 | 59 | /* ServerPolicy */ |
be05aa91 | 60 | g_lua.writeFunction("newServerPolicy", [](string name, ServerPolicy::policyfunc_t policy) { return std::make_shared<ServerPolicy>(name, policy, true);}); |
6bb38cd6 RG |
61 | g_lua.registerMember("name", &ServerPolicy::name); |
62 | g_lua.registerMember("policy", &ServerPolicy::policy); | |
21e189be | 63 | g_lua.registerMember("ffipolicy", &ServerPolicy::ffipolicy); |
a1b1a29d | 64 | g_lua.registerMember("isLua", &ServerPolicy::isLua); |
21e189be | 65 | g_lua.registerMember("isFFI", &ServerPolicy::isFFI); |
a4fd2d2f | 66 | g_lua.registerFunction("toString", &ServerPolicy::toString); |
6bb38cd6 | 67 | |
a1b1a29d RG |
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}); | |
1720247e | 72 | g_lua.writeVariable("chashed", ServerPolicy{"chashed", chashed, false}); |
a1b1a29d | 73 | g_lua.writeVariable("leastOutstanding", ServerPolicy{"leastOutstanding", leastOutstanding, false}); |
6bb38cd6 RG |
74 | |
75 | /* ServerPool */ | |
76 | g_lua.registerFunction<void(std::shared_ptr<ServerPool>::*)(std::shared_ptr<DNSDistPacketCache>)>("setCache", [](std::shared_ptr<ServerPool> pool, std::shared_ptr<DNSDistPacketCache> cache) { | |
77 | if (pool) { | |
78 | pool->packetCache = cache; | |
79 | } | |
80 | }); | |
81 | g_lua.registerFunction("getCache", &ServerPool::getCache); | |
82 | g_lua.registerFunction<void(std::shared_ptr<ServerPool>::*)()>("unsetCache", [](std::shared_ptr<ServerPool> pool) { | |
83 | if (pool) { | |
84 | pool->packetCache = nullptr; | |
85 | } | |
86 | }); | |
7e687744 RG |
87 | g_lua.registerFunction("getECS", &ServerPool::getECS); |
88 | g_lua.registerFunction("setECS", &ServerPool::setECS); | |
6bb38cd6 RG |
89 | |
90 | /* DownstreamState */ | |
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); | |
97 | }); | |
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); | |
103 | }); | |
2831298d | 104 | g_lua.registerFunction<uint64_t(DownstreamState::*)()>("getOutstanding", [](const DownstreamState& s) { return s.outstanding.load(); }); |
6bb38cd6 RG |
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) { | |
109 | if (newStatus) { | |
110 | s.upStatus = *newStatus; | |
111 | } | |
112 | s.setAuto(); | |
113 | }); | |
508543b4 RG |
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(); }); | |
6bb38cd6 | 116 | g_lua.registerMember("upStatus", &DownstreamState::upStatus); |
5a2bbe8c CHB |
117 | g_lua.registerMember<int (DownstreamState::*)>("weight", |
118 | [](const DownstreamState& s) -> int {return s.weight;}, | |
119 | [](DownstreamState& s, int newWeight) {s.setWeight(newWeight);} | |
120 | ); | |
6bb38cd6 | 121 | g_lua.registerMember("order", &DownstreamState::order); |
be05aa91 | 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); }); |
adfdcc4b | 123 | g_lua.registerFunction<std::string(DownstreamState::*)()>("getID", [](const DownstreamState& s) { return boost::uuids::to_string(s.id); }); |
6bb38cd6 RG |
124 | |
125 | /* dnsheader */ | |
126 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setRD", [](dnsheader& dh, bool v) { | |
127 | dh.rd=v; | |
128 | }); | |
129 | ||
130 | g_lua.registerFunction<bool(dnsheader::*)()>("getRD", [](dnsheader& dh) { | |
131 | return (bool)dh.rd; | |
132 | }); | |
133 | ||
5de00b87 RG |
134 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setRA", [](dnsheader& dh, bool v) { |
135 | dh.ra=v; | |
136 | }); | |
137 | ||
138 | g_lua.registerFunction<bool(dnsheader::*)()>("getRA", [](dnsheader& dh) { | |
139 | return (bool)dh.ra; | |
140 | }); | |
141 | ||
142 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setAD", [](dnsheader& dh, bool v) { | |
143 | dh.ad=v; | |
144 | }); | |
145 | ||
146 | g_lua.registerFunction<bool(dnsheader::*)()>("getAD", [](dnsheader& dh) { | |
147 | return (bool)dh.ad; | |
148 | }); | |
149 | ||
150 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setAA", [](dnsheader& dh, bool v) { | |
151 | dh.aa=v; | |
202c4ab9 | 152 | }); |
5de00b87 RG |
153 | |
154 | g_lua.registerFunction<bool(dnsheader::*)()>("getAA", [](dnsheader& dh) { | |
155 | return (bool)dh.aa; | |
156 | }); | |
157 | ||
6bb38cd6 RG |
158 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) { |
159 | dh.cd=v; | |
160 | }); | |
161 | ||
162 | g_lua.registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) { | |
163 | return (bool)dh.cd; | |
164 | }); | |
165 | ||
166 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) { | |
167 | dh.tc=v; | |
168 | if(v) dh.ra = dh.rd; // you'll always need this, otherwise TC=1 gets ignored | |
169 | }); | |
170 | ||
171 | g_lua.registerFunction<void(dnsheader::*)(bool)>("setQR", [](dnsheader& dh, bool v) { | |
172 | dh.qr=v; | |
173 | }); | |
174 | ||
175 | /* ComboAddress */ | |
176 | g_lua.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); }); | |
0ed8f0fa RG |
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()); | |
183 | if (port) { | |
184 | sin4.sin_port = htons(*port); | |
185 | } | |
186 | return ComboAddress(&sin4); | |
187 | } | |
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()); | |
193 | if (port) { | |
194 | sin6.sin6_port = htons(*port); | |
195 | } | |
196 | return ComboAddress(&sin6); | |
197 | } | |
198 | return ComboAddress(); | |
199 | }); | |
6bb38cd6 RG |
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); }); | |
211 | ||
212 | /* DNSName */ | |
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(); }); | |
272d037e | 216 | g_lua.registerFunction<size_t(DNSName::*)()>("hash", [](const DNSName& name) { return name.hash(); }); |
6bb38cd6 RG |
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); }); | |
0ed8f0fa | 221 | g_lua.writeFunction("newDNSNameFromRaw", [](const std::string& name) { return DNSName(name.c_str(), name.size(), 0, false); }); |
6bb38cd6 | 222 | g_lua.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); }); |
9f618bcc AD |
223 | g_lua.writeFunction("newDNSNameSet", []() { return DNSNameSet(); }); |
224 | ||
225 | /* 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); }); | |
cc0e7aa9 | 228 | g_lua.registerFunction<bool(DNSNameSet::*)(DNSName&)>("check", [](DNSNameSet& dns, DNSName& dn) { return dns.find(dn) != dns.end(); }); |
9f618bcc AD |
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); | |
6bb38cd6 RG |
233 | |
234 | /* SuffixMatchNode */ | |
41ff82c9 PL |
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); | |
238 | smn.add(n); | |
239 | return; | |
240 | } | |
241 | if (name.type() == typeid(string)) { | |
242 | auto n = boost::get<string>(name); | |
243 | smn.add(n); | |
244 | return; | |
245 | } | |
246 | if (name.type() == typeid(vector<pair<int, DNSName>>)) { | |
247 | auto names = boost::get<vector<pair<int, DNSName>>>(name); | |
ba8ade8e | 248 | for (const auto& n : names) { |
41ff82c9 PL |
249 | smn.add(n.second); |
250 | } | |
251 | return; | |
252 | } | |
253 | if (name.type() == typeid(vector<pair<int, string>>)) { | |
254 | auto names = boost::get<vector<pair<int, string>>>(name); | |
ba8ade8e | 255 | for (const auto& n : names) { |
41ff82c9 PL |
256 | smn.add(n.second); |
257 | } | |
258 | return; | |
259 | } | |
260 | }); | |
bc5c693b PL |
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); | |
264 | smn.remove(n); | |
265 | return; | |
266 | } | |
267 | if (name.type() == typeid(string)) { | |
268 | auto n = boost::get<string>(name); | |
269 | DNSName d(n); | |
270 | smn.remove(d); | |
271 | return; | |
272 | } | |
273 | if (name.type() == typeid(vector<pair<int, DNSName>>)) { | |
274 | auto names = boost::get<vector<pair<int, DNSName>>>(name); | |
ba8ade8e | 275 | for (const auto& n : names) { |
bc5c693b PL |
276 | smn.remove(n.second); |
277 | } | |
278 | return; | |
279 | } | |
280 | if (name.type() == typeid(vector<pair<int, string>>)) { | |
281 | auto names = boost::get<vector<pair<int, string>>>(name); | |
ba8ade8e | 282 | for (const auto& n : names) { |
bc5c693b PL |
283 | DNSName d(n.second); |
284 | smn.remove(d); | |
285 | } | |
286 | return; | |
287 | } | |
288 | }); | |
289 | ||
6bb38cd6 RG |
290 | g_lua.registerFunction("check",(bool (SuffixMatchNode::*)(const DNSName&) const) &SuffixMatchNode::check); |
291 | ||
e1c9b027 RG |
292 | /* Netmask */ |
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); | |
296 | if (bits) { | |
297 | return Netmask(ca, *bits); | |
298 | } | |
299 | return Netmask(ca); | |
300 | } | |
301 | else if (s.type() == typeid(std::string)) { | |
302 | auto str = boost::get<std::string>(s); | |
303 | return Netmask(str); | |
304 | } | |
305 | throw std::runtime_error("Invalid parameter passed to 'newNetmask()'"); | |
306 | }); | |
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); | |
319 | ||
6bb38cd6 RG |
320 | /* NetmaskGroup */ |
321 | g_lua.writeFunction("newNMG", []() { return NetmaskGroup(); }); | |
322 | g_lua.registerFunction<void(NetmaskGroup::*)(const std::string&mask)>("addMask", [](NetmaskGroup&nmg, const std::string& mask) | |
323 | { | |
324 | nmg.addMask(mask); | |
325 | }); | |
326 | g_lua.registerFunction<void(NetmaskGroup::*)(const std::map<ComboAddress,int>& map)>("addMasks", [](NetmaskGroup&nmg, const std::map<ComboAddress,int>& map) | |
327 | { | |
328 | for (const auto& entry : map) { | |
329 | nmg.addMask(Netmask(entry.first)); | |
330 | } | |
331 | }); | |
332 | ||
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); | |
a4fd2d2f | 336 | g_lua.registerFunction<string(NetmaskGroup::*)()>("toString", [](const NetmaskGroup& nmg ) { return "NetmaskGroup " + nmg.toString(); }); |
6bb38cd6 RG |
337 | |
338 | /* QPSLimiter */ | |
339 | g_lua.writeFunction("newQPSLimiter", [](int rate, int burst) { return QPSLimiter(rate, burst); }); | |
340 | g_lua.registerFunction("check", &QPSLimiter::check); | |
341 | ||
342 | /* ClientState */ | |
343 | g_lua.registerFunction<std::string(ClientState::*)()>("toString", [](const ClientState& fe) { | |
344 | setLuaNoSideEffect(); | |
345 | return fe.local.toStringWithPort(); | |
346 | }); | |
347 | g_lua.registerMember("muted", &ClientState::muted); | |
348 | #ifdef HAVE_EBPF | |
349 | g_lua.registerFunction<void(ClientState::*)(std::shared_ptr<BPFFilter>)>("attachFilter", [](ClientState& frontend, std::shared_ptr<BPFFilter> bpf) { | |
350 | if (bpf) { | |
351 | frontend.attachFilter(bpf); | |
352 | } | |
353 | }); | |
354 | g_lua.registerFunction<void(ClientState::*)()>("detachFilter", [](ClientState& frontend) { | |
355 | frontend.detachFilter(); | |
356 | }); | |
357 | #endif /* HAVE_EBPF */ | |
358 | ||
6bb38cd6 RG |
359 | /* BPF Filter */ |
360 | #ifdef HAVE_EBPF | |
361 | g_lua.writeFunction("newBPFFilter", [client](uint32_t maxV4, uint32_t maxV6, uint32_t maxQNames) { | |
362 | if (client) { | |
363 | return std::shared_ptr<BPFFilter>(nullptr); | |
364 | } | |
365 | return std::make_shared<BPFFilter>(maxV4, maxV6, maxQNames); | |
366 | }); | |
367 | ||
368 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("block", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) { | |
369 | if (bpf) { | |
370 | return bpf->block(ca); | |
371 | } | |
372 | }); | |
373 | ||
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) { | |
375 | if (bpf) { | |
376 | return bpf->block(qname, qtype ? *qtype : 255); | |
377 | } | |
378 | }); | |
379 | ||
380 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("unblock", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) { | |
381 | if (bpf) { | |
382 | return bpf->unblock(ca); | |
383 | } | |
384 | }); | |
385 | ||
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) { | |
387 | if (bpf) { | |
388 | return bpf->unblock(qname, qtype ? *qtype : 255); | |
389 | } | |
390 | }); | |
391 | ||
392 | g_lua.registerFunction<std::string(std::shared_ptr<BPFFilter>::*)()>("getStats", [](const std::shared_ptr<BPFFilter> bpf) { | |
393 | setLuaNoSideEffect(); | |
394 | std::string res; | |
395 | if (bpf) { | |
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"; | |
400 | } | |
401 | else if (value.first.sin4.sin_family == AF_INET6) { | |
402 | res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n"; | |
403 | } | |
404 | } | |
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"; | |
408 | } | |
409 | } | |
410 | return res; | |
411 | }); | |
412 | ||
413 | g_lua.registerFunction<void(std::shared_ptr<BPFFilter>::*)()>("attachToAllBinds", [](std::shared_ptr<BPFFilter> bpf) { | |
414 | std::string res; | |
415 | if (bpf) { | |
416 | for (const auto& frontend : g_frontends) { | |
417 | frontend->attachFilter(bpf); | |
418 | } | |
419 | } | |
420 | }); | |
421 | ||
422 | g_lua.writeFunction("newDynBPFFilter", [client](std::shared_ptr<BPFFilter> bpf) { | |
423 | if (client) { | |
424 | return std::shared_ptr<DynBPFFilter>(nullptr); | |
425 | } | |
426 | return std::make_shared<DynBPFFilter>(bpf); | |
427 | }); | |
428 | ||
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) { | |
430 | if (dbpf) { | |
431 | struct timespec until; | |
432 | clock_gettime(CLOCK_MONOTONIC, &until); | |
433 | until.tv_sec += seconds ? *seconds : 10; | |
434 | dbpf->block(addr, until); | |
435 | } | |
436 | }); | |
437 | ||
438 | g_lua.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)()>("purgeExpired", [](std::shared_ptr<DynBPFFilter> dbpf) { | |
439 | if (dbpf) { | |
440 | struct timespec now; | |
441 | clock_gettime(CLOCK_MONOTONIC, &now); | |
442 | dbpf->purgeExpired(now); | |
443 | } | |
444 | }); | |
ee38369c RS |
445 | |
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)); | |
450 | } | |
451 | } | |
452 | else { | |
453 | dbpf->excludeRange(Netmask(*boost::get<std::string>(&ranges))); | |
454 | } | |
455 | }); | |
456 | ||
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)); | |
461 | } | |
462 | } | |
463 | else { | |
464 | dbpf->includeRange(Netmask(*boost::get<std::string>(&ranges))); | |
465 | } | |
466 | }); | |
6bb38cd6 | 467 | #endif /* HAVE_EBPF */ |
cbf4e13a RG |
468 | |
469 | /* EDNSOptionView */ | |
470 | g_lua.registerFunction<size_t(EDNSOptionView::*)()>("count", [](const EDNSOptionView& option) { | |
471 | return option.values.size(); | |
472 | }); | |
0d51414d PD |
473 | g_lua.registerFunction<std::vector<string>(EDNSOptionView::*)()>("getValues", [] (const EDNSOptionView& option) { |
474 | std::vector<string> values; | |
cbf4e13a | 475 | for (const auto& value : option.values) { |
0d51414d | 476 | values.push_back(std::string(value.content, value.size)); |
cbf4e13a RG |
477 | } |
478 | return values; | |
479 | }); | |
f441962a | 480 | |
ded6907c RG |
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}; | |
483 | if (customHeaders) { | |
484 | headers = std::vector<std::pair<std::string, std::string>>(); | |
485 | for (const auto& header : *customHeaders) { | |
e1b72559 | 486 | headers->push_back({ boost::to_lower_copy(header.first), header.second }); |
ded6907c RG |
487 | } |
488 | } | |
489 | return std::make_shared<DOHResponseMapEntry>(regex, status, content, headers); | |
28b56482 | 490 | }); |
6bb38cd6 | 491 | } |