]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsdist-lua-bindings-dnsquestion.cc
dnsdist: Allow wrapping the FFI interface for the existing DNSQuestion object
[thirdparty/pdns.git] / pdns / dnsdist-lua-bindings-dnsquestion.cc
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 #include "dnsdist.hh"
23 #include "dnsdist-ecs.hh"
24 #include "dnsdist-lua.hh"
25 #include "dnsparser.hh"
26
27 void setupLuaBindingsDNSQuestion()
28 {
29 /* DNSQuestion */
30 /* PowerDNS DNSQuestion compat */
31 g_lua.registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.local; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void) newLocal; });
32 g_lua.registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName { return *dq.qname; }, [](DNSQuestion& dq, const DNSName newName) { (void) newName; });
33 g_lua.registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
34 g_lua.registerMember<uint16_t (DNSQuestion::*)>("qclass", [](const DNSQuestion& dq) -> uint16_t { return dq.qclass; }, [](DNSQuestion& dq, uint16_t newClass) { (void) newClass; });
35 g_lua.registerMember<int (DNSQuestion::*)>("rcode", [](const DNSQuestion& dq) -> int { return dq.dh->rcode; }, [](DNSQuestion& dq, int newRCode) { dq.dh->rcode = newRCode; });
36 g_lua.registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.remote; }, [](DNSQuestion& dq, const ComboAddress newRemote) { (void) newRemote; });
37 /* DNSDist DNSQuestion */
38 g_lua.registerMember("dh", &DNSQuestion::dh);
39 g_lua.registerMember<uint16_t (DNSQuestion::*)>("len", [](const DNSQuestion& dq) -> uint16_t { return dq.len; }, [](DNSQuestion& dq, uint16_t newlen) { dq.len = newlen; });
40 g_lua.registerMember<uint8_t (DNSQuestion::*)>("opcode", [](const DNSQuestion& dq) -> uint8_t { return dq.dh->opcode; }, [](DNSQuestion& dq, uint8_t newOpcode) { (void) newOpcode; });
41 g_lua.registerMember<size_t (DNSQuestion::*)>("size", [](const DNSQuestion& dq) -> size_t { return dq.size; }, [](DNSQuestion& dq, size_t newSize) { (void) newSize; });
42 g_lua.registerMember<bool (DNSQuestion::*)>("tcp", [](const DNSQuestion& dq) -> bool { return dq.tcp; }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
43 g_lua.registerMember<bool (DNSQuestion::*)>("skipCache", [](const DNSQuestion& dq) -> bool { return dq.skipCache; }, [](DNSQuestion& dq, bool newSkipCache) { dq.skipCache = newSkipCache; });
44 g_lua.registerMember<bool (DNSQuestion::*)>("useECS", [](const DNSQuestion& dq) -> bool { return dq.useECS; }, [](DNSQuestion& dq, bool useECS) { dq.useECS = useECS; });
45 g_lua.registerMember<bool (DNSQuestion::*)>("ecsOverride", [](const DNSQuestion& dq) -> bool { return dq.ecsOverride; }, [](DNSQuestion& dq, bool ecsOverride) { dq.ecsOverride = ecsOverride; });
46 g_lua.registerMember<uint16_t (DNSQuestion::*)>("ecsPrefixLength", [](const DNSQuestion& dq) -> uint16_t { return dq.ecsPrefixLength; }, [](DNSQuestion& dq, uint16_t newPrefixLength) { dq.ecsPrefixLength = newPrefixLength; });
47 g_lua.registerMember<boost::optional<uint32_t> (DNSQuestion::*)>("tempFailureTTL",
48 [](const DNSQuestion& dq) -> boost::optional<uint32_t> {
49 return dq.tempFailureTTL;
50 },
51 [](DNSQuestion& dq, boost::optional<uint32_t> newValue) {
52 dq.tempFailureTTL = newValue;
53 }
54 );
55 g_lua.registerFunction<bool(DNSQuestion::*)()>("getDO", [](const DNSQuestion& dq) {
56 return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
57 });
58
59 g_lua.registerFunction<std::map<uint16_t, EDNSOptionView>(DNSQuestion::*)()>("getEDNSOptions", [](DNSQuestion& dq) {
60 if (dq.ednsOptions == nullptr) {
61 parseEDNSOptions(dq);
62 }
63
64 return *dq.ednsOptions;
65 });
66 g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getTrailingData", [](const DNSQuestion& dq) {
67 return dq.getTrailingData();
68 });
69 g_lua.registerFunction<bool(DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dq, const std::string& tail) {
70 return dq.setTrailingData(tail);
71 });
72
73 g_lua.registerFunction<std::string(DNSQuestion::*)()>("getServerNameIndication", [](const DNSQuestion& dq) {
74 return dq.sni;
75 });
76
77 g_lua.registerFunction<void(DNSQuestion::*)(std::string)>("sendTrap", [](const DNSQuestion& dq, boost::optional<std::string> reason) {
78 #ifdef HAVE_NET_SNMP
79 if (g_snmpAgent && g_snmpTrapsEnabled) {
80 g_snmpAgent->sendDNSTrap(dq, reason ? *reason : "");
81 }
82 #endif /* HAVE_NET_SNMP */
83 });
84
85 g_lua.registerFunction<void(DNSQuestion::*)(std::string, std::string)>("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) {
86 if(dq.qTag == nullptr) {
87 dq.qTag = std::make_shared<QTag>();
88 }
89 dq.qTag->insert({strLabel, strValue});
90 });
91 g_lua.registerFunction<void(DNSQuestion::*)(vector<pair<string, string>>)>("setTagArray", [](DNSQuestion& dq, const vector<pair<string, string>>&tags) {
92 if (!dq.qTag) {
93 dq.qTag = std::make_shared<QTag>();
94 }
95
96 for (const auto& tag : tags) {
97 dq.qTag->insert({tag.first, tag.second});
98 }
99 });
100 g_lua.registerFunction<string(DNSQuestion::*)(std::string)>("getTag", [](const DNSQuestion& dq, const std::string& strLabel) {
101 if (!dq.qTag) {
102 return string();
103 }
104
105 std::string strValue;
106 const auto it = dq.qTag->find(strLabel);
107 if (it == dq.qTag->cend()) {
108 return string();
109 }
110 return it->second;
111 });
112 g_lua.registerFunction<QTag(DNSQuestion::*)(void)>("getTagArray", [](const DNSQuestion& dq) {
113 if (!dq.qTag) {
114 QTag empty;
115 return empty;
116 }
117
118 return *dq.qTag;
119 });
120
121 /* LuaWrapper doesn't support inheritance */
122 g_lua.registerMember<const ComboAddress (DNSResponse::*)>("localaddr", [](const DNSResponse& dq) -> const ComboAddress { return *dq.local; }, [](DNSResponse& dq, const ComboAddress newLocal) { (void) newLocal; });
123 g_lua.registerMember<const DNSName (DNSResponse::*)>("qname", [](const DNSResponse& dq) -> const DNSName { return *dq.qname; }, [](DNSResponse& dq, const DNSName newName) { (void) newName; });
124 g_lua.registerMember<uint16_t (DNSResponse::*)>("qtype", [](const DNSResponse& dq) -> uint16_t { return dq.qtype; }, [](DNSResponse& dq, uint16_t newType) { (void) newType; });
125 g_lua.registerMember<uint16_t (DNSResponse::*)>("qclass", [](const DNSResponse& dq) -> uint16_t { return dq.qclass; }, [](DNSResponse& dq, uint16_t newClass) { (void) newClass; });
126 g_lua.registerMember<int (DNSResponse::*)>("rcode", [](const DNSResponse& dq) -> int { return dq.dh->rcode; }, [](DNSResponse& dq, int newRCode) { dq.dh->rcode = newRCode; });
127 g_lua.registerMember<const ComboAddress (DNSResponse::*)>("remoteaddr", [](const DNSResponse& dq) -> const ComboAddress { return *dq.remote; }, [](DNSResponse& dq, const ComboAddress newRemote) { (void) newRemote; });
128 g_lua.registerMember<dnsheader* (DNSResponse::*)>("dh", [](const DNSResponse& dr) -> dnsheader* { return dr.dh; }, [](DNSResponse& dr, dnsheader * newdh) { dr.dh = newdh; });
129 g_lua.registerMember<uint16_t (DNSResponse::*)>("len", [](const DNSResponse& dq) -> uint16_t { return dq.len; }, [](DNSResponse& dq, uint16_t newlen) { dq.len = newlen; });
130 g_lua.registerMember<uint8_t (DNSResponse::*)>("opcode", [](const DNSResponse& dq) -> uint8_t { return dq.dh->opcode; }, [](DNSResponse& dq, uint8_t newOpcode) { (void) newOpcode; });
131 g_lua.registerMember<size_t (DNSResponse::*)>("size", [](const DNSResponse& dq) -> size_t { return dq.size; }, [](DNSResponse& dq, size_t newSize) { (void) newSize; });
132 g_lua.registerMember<bool (DNSResponse::*)>("tcp", [](const DNSResponse& dq) -> bool { return dq.tcp; }, [](DNSResponse& dq, bool newTcp) { (void) newTcp; });
133 g_lua.registerMember<bool (DNSResponse::*)>("skipCache", [](const DNSResponse& dq) -> bool { return dq.skipCache; }, [](DNSResponse& dq, bool newSkipCache) { dq.skipCache = newSkipCache; });
134 g_lua.registerFunction<void(DNSResponse::*)(std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc)>("editTTLs", [](const DNSResponse& dr, std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc) {
135 editDNSPacketTTL((char*) dr.dh, dr.len, editFunc);
136 });
137 g_lua.registerFunction<std::string(DNSResponse::*)(void)>("getTrailingData", [](const DNSResponse& dq) {
138 return dq.getTrailingData();
139 });
140 g_lua.registerFunction<bool(DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dq, const std::string& tail) {
141 return dq.setTrailingData(tail);
142 });
143
144 g_lua.registerFunction<void(DNSResponse::*)(std::string, std::string)>("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) {
145 if(dr.qTag == nullptr) {
146 dr.qTag = std::make_shared<QTag>();
147 }
148 dr.qTag->insert({strLabel, strValue});
149 });
150
151 g_lua.registerFunction<void(DNSResponse::*)(vector<pair<string, string>>)>("setTagArray", [](DNSResponse& dr, const vector<pair<string, string>>&tags) {
152 if (!dr.qTag) {
153 dr.qTag = std::make_shared<QTag>();
154 }
155
156 for (const auto& tag : tags) {
157 dr.qTag->insert({tag.first, tag.second});
158 }
159 });
160 g_lua.registerFunction<string(DNSResponse::*)(std::string)>("getTag", [](const DNSResponse& dr, const std::string& strLabel) {
161 if (!dr.qTag) {
162 return string();
163 }
164
165 std::string strValue;
166 const auto it = dr.qTag->find(strLabel);
167 if (it == dr.qTag->cend()) {
168 return string();
169 }
170 return it->second;
171 });
172 g_lua.registerFunction<QTag(DNSResponse::*)(void)>("getTagArray", [](const DNSResponse& dr) {
173 if (!dr.qTag) {
174 QTag empty;
175 return empty;
176 }
177
178 return *dr.qTag;
179 });
180
181 g_lua.registerFunction<void(DNSResponse::*)(std::string)>("sendTrap", [](const DNSResponse& dr, boost::optional<std::string> reason) {
182 #ifdef HAVE_NET_SNMP
183 if (g_snmpAgent && g_snmpTrapsEnabled) {
184 g_snmpAgent->sendDNSTrap(dr, reason ? *reason : "");
185 }
186 #endif /* HAVE_NET_SNMP */
187 });
188
189 #ifdef HAVE_DNS_OVER_HTTPS
190 g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getHTTPPath", [](const DNSQuestion& dq) {
191 if (dq.du == nullptr) {
192 return std::string();
193 }
194 return dq.du->getHTTPPath();
195 });
196
197 g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getHTTPQueryString", [](const DNSQuestion& dq) {
198 if (dq.du == nullptr) {
199 return std::string();
200 }
201 return dq.du->getHTTPQueryString();
202 });
203
204 g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getHTTPHost", [](const DNSQuestion& dq) {
205 if (dq.du == nullptr) {
206 return std::string();
207 }
208 return dq.du->getHTTPHost();
209 });
210
211 g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getHTTPScheme", [](const DNSQuestion& dq) {
212 if (dq.du == nullptr) {
213 return std::string();
214 }
215 return dq.du->getHTTPScheme();
216 });
217
218 g_lua.registerFunction<std::unordered_map<std::string, std::string>(DNSQuestion::*)(void)>("getHTTPHeaders", [](const DNSQuestion& dq) {
219 if (dq.du == nullptr) {
220 return std::unordered_map<std::string, std::string>();
221 }
222 return dq.du->getHTTPHeaders();
223 });
224
225 g_lua.registerFunction<void(DNSQuestion::*)(uint16_t statusCode, const std::string& body, const boost::optional<std::string> contentType)>("setHTTPResponse", [](DNSQuestion& dq, uint16_t statusCode, const std::string& body, const boost::optional<std::string> contentType) {
226 if (dq.du == nullptr) {
227 return;
228 }
229 dq.du->setHTTPResponse(statusCode, body, contentType ? *contentType : "");
230 });
231 #endif /* HAVE_DNS_OVER_HTTPS */
232
233 g_lua.registerFunction<bool(DNSQuestion::*)(bool nxd, const std::string& zone, uint32_t ttl, const std::string& mname, const std::string& rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum)>("setNegativeAndAdditionalSOA", [](DNSQuestion& dq, bool nxd, const std::string& zone, uint32_t ttl, const std::string& mname, const std::string& rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) {
234 return setNegativeAndAdditionalSOA(dq, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum);
235 });
236 }