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