]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Allow wrapping the FFI interface for the existing DNSQuestion object
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 3 Dec 2019 16:10:09 +0000 (17:10 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 11 Feb 2020 10:49:57 +0000 (11:49 +0100)
12 files changed:
pdns/dnsdist-lua-bindings-dnsquestion.cc
pdns/dnsdist-lua-bindings.cc
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/.gitignore
pdns/dnsdistdist/Makefile.am
pdns/dnsdistdist/dnsdist-lua-ffi-interface.h [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-ffi.cc
pdns/dnsdistdist/dnsdist-lua-ffi.hh
regression-tests.dnsdist/test_DOH.py
regression-tests.dnsdist/test_EDNSOptions.py

index eff46f3ab5aa7c835ab483a0492dbabea2305262..71840e7f36481f79cc40cd4353102e3304c6d898 100644 (file)
@@ -64,25 +64,10 @@ void setupLuaBindingsDNSQuestion()
       return *dq.ednsOptions;
     });
   g_lua.registerFunction<std::string(DNSQuestion::*)(void)>("getTrailingData", [](const DNSQuestion& dq) {
-      const char* message = reinterpret_cast<const char*>(dq.dh);
-      const uint16_t messageLen = getDNSPacketLength(message, dq.len);
-      const std::string tail = std::string(message + messageLen, dq.len - messageLen);
-      return tail;
+      return dq.getTrailingData();
     });
   g_lua.registerFunction<bool(DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dq, const std::string& tail) {
-      char* message = reinterpret_cast<char*>(dq.dh);
-      const uint16_t messageLen = getDNSPacketLength(message, dq.len);
-      const uint16_t tailLen = tail.size();
-      if(tailLen > (dq.size - messageLen)) {
-        return false;
-      }
-
-      /* Update length and copy data from the Lua string. */
-      dq.len = messageLen + tailLen;
-      if(tailLen > 0) {
-        tail.copy(message + messageLen, tailLen);
-      }
-      return true;
+      return dq.setTrailingData(tail);
     });
 
   g_lua.registerFunction<std::string(DNSQuestion::*)()>("getServerNameIndication", [](const DNSQuestion& dq) {
@@ -150,25 +135,10 @@ void setupLuaBindingsDNSQuestion()
         editDNSPacketTTL((char*) dr.dh, dr.len, editFunc);
       });
   g_lua.registerFunction<std::string(DNSResponse::*)(void)>("getTrailingData", [](const DNSResponse& dq) {
-      const char* message = reinterpret_cast<const char*>(dq.dh);
-      const uint16_t messageLen = getDNSPacketLength(message, dq.len);
-      const std::string tail = std::string(message + messageLen, dq.len - messageLen);
-      return tail;
+      return dq.getTrailingData();
     });
   g_lua.registerFunction<bool(DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dq, const std::string& tail) {
-      char* message = reinterpret_cast<char*>(dq.dh);
-      const uint16_t messageLen = getDNSPacketLength(message, dq.len);
-      const uint16_t tailLen = tail.size();
-      if(tailLen > (dq.size - messageLen)) {
-        return false;
-      }
-
-      /* Update length and copy data from the Lua string. */
-      dq.len = messageLen + tailLen;
-      if(tailLen > 0) {
-        tail.copy(message + messageLen, tailLen);
-      }
-      return true;
+      return dq.setTrailingData(tail);
     });
 
   g_lua.registerFunction<void(DNSResponse::*)(std::string, std::string)>("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) {
index 06cc42f9da88f566e31916730b729f93a40998cf..fc25caddf3f66e434b9fcd02529b1ea3e3e479a6 100644 (file)
@@ -172,6 +172,29 @@ void setupLuaBindings(bool client)
 
   /* ComboAddress */
   g_lua.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); });
+  g_lua.writeFunction("newCAFromRaw", [](const std::string& raw, boost::optional<uint16_t> port) {
+                                        if (raw.size() == 4) {
+                                          struct sockaddr_in sin4;
+                                          memset(&sin4, 0, sizeof(sin4));
+                                          sin4.sin_family = AF_INET;
+                                          memcpy(&sin4.sin_addr.s_addr, raw.c_str(), raw.size());
+                                          if (port) {
+                                            sin4.sin_port = htons(*port);
+                                          }
+                                          return ComboAddress(&sin4);
+                                        }
+                                        else if (raw.size() == 16) {
+                                          struct sockaddr_in6 sin6;
+                                          memset(&sin6, 0, sizeof(sin6));
+                                          sin6.sin6_family = AF_INET6;
+                                          memcpy(&sin6.sin6_addr.s6_addr, raw.c_str(), raw.size());
+                                          if (port) {
+                                            sin6.sin6_port = htons(*port);
+                                          }
+                                          return ComboAddress(&sin6);
+                                        }
+                                        return ComboAddress();
+                                      });
   g_lua.registerFunction<string(ComboAddress::*)()>("tostring", [](const ComboAddress& ca) { return ca.toString(); });
   g_lua.registerFunction<string(ComboAddress::*)()>("tostringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
   g_lua.registerFunction<string(ComboAddress::*)()>("toString", [](const ComboAddress& ca) { return ca.toString(); });
@@ -192,6 +215,7 @@ void setupLuaBindings(bool client)
   g_lua.registerFunction<string(DNSName::*)()>("tostring", [](const DNSName&dn ) { return dn.toString(); });
   g_lua.registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
   g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); });
+  g_lua.writeFunction("newDNSNameFromRaw", [](const std::string& name) { return DNSName(name.c_str(), name.size(), 0, false); });
   g_lua.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); });
   g_lua.writeFunction("newDNSNameSet", []() { return DNSNameSet(); });
 
index a2979bac0b020f64cceed9f2c3e7434083a85009..0cb77d6064e8eeafa19d0c0c61cdf3ae6832942a 100644 (file)
@@ -36,6 +36,9 @@
 #include "dnsdist-ecs.hh"
 #include "dnsdist-healthchecks.hh"
 #include "dnsdist-lua.hh"
+#ifdef LUAJIT_VERSION
+#include "dnsdist-lua-ffi.hh"
+#endif /* LUAJIT_VERSION */
 #include "dnsdist-rings.hh"
 #include "dnsdist-secpoll.hh"
 
@@ -2191,6 +2194,10 @@ vector<std::function<void(void)>> setupLua(bool client, bool configCheck, const
   setupLuaRules();
   setupLuaVars();
 
+#ifdef LUAJIT_VERSION
+  g_lua.executeCode(getLuaFFIWrappers());
+#endif
+
   std::ifstream ifs(config);
   if(!ifs)
     warnlog("Unable to read configuration from '%s'", config);
index 00cb2e3dfb89210b30e786410163f3ca9977d4e4..75d7c56ea299d30c8a31bd31fb61128377ee9d9c 100644 (file)
@@ -193,6 +193,30 @@ struct DelayedPacket
 
 DelayPipe<DelayedPacket>* g_delay = nullptr;
 
+std::string DNSQuestion::getTrailingData() const
+{
+  const char* message = reinterpret_cast<const char*>(this->dh);
+  const uint16_t messageLen = getDNSPacketLength(message, this->len);
+  return std::string(message + messageLen, this->len - messageLen);
+}
+
+bool DNSQuestion::setTrailingData(const std::string& tail)
+{
+  char* message = reinterpret_cast<char*>(this->dh);
+  const uint16_t messageLen = getDNSPacketLength(message, this->len);
+  const uint16_t tailLen = tail.size();
+  if (tailLen > (this->size - messageLen)) {
+    return false;
+  }
+
+  /* Update length and copy data from the Lua string. */
+  this->len = messageLen + tailLen;
+  if(tailLen > 0) {
+    tail.copy(message + messageLen, tailLen);
+  }
+  return true;
+}
+
 void doLatencyStats(double udiff)
 {
   if(udiff < 1000) ++g_stats.latency0_1;
index 9443dc8ce943e6cea281feb07817312d4a97ecbe..44c992d01be2b960a87904174d3557c02d3b78ff 100644 (file)
@@ -70,6 +70,9 @@ struct DNSQuestion
   DNSQuestion& operator=(const DNSQuestion&) = delete;
   DNSQuestion(DNSQuestion&&) = default;
 
+  std::string getTrailingData() const;
+  bool setTrailingData(const std::string&);
+
 #ifdef HAVE_PROTOBUF
   boost::optional<boost::uuids::uuid> uniqueId;
 #endif
index 5cec6c5e8f509f43c772c05c100016761b72ad24..30c50de897c677d5d2055f6273d0e0d986564ec9 100644 (file)
@@ -18,6 +18,7 @@
 /configure
 /depcomp
 /dnsdist.1
+/dnsdist-lua-ffi-interface.inc
 /dnslabeltext.cc
 /ext/ipcrypt/Makefile
 /ext/ipcrypt/Makefile.in
index a050dfbe94ecfd3e7611572b0d3f2759ac49aa87..6e493486218e87e43bd015101d5b19a884fdf8c9 100644 (file)
@@ -10,6 +10,7 @@ CLEANFILES = \
        dnsmessage.pb.h \
        htmlfiles.h.tmp \
        htmlfiles.h \
+       dnsdist-lua-ffi-interface.inc \
        dnstap.pb.cc \
        dnstap.pb.h
 
@@ -17,12 +18,18 @@ dnslabeltext.cc: dnslabeltext.rl
        $(AM_V_GEN)$(RAGEL) $< -o dnslabeltext.cc
 
 BUILT_SOURCES=htmlfiles.h \
+       dnsdist-lua-ffi-interface.inc \
        dnslabeltext.cc
 
 htmlfiles.h: $(srcdir)/html/*
        $(AM_V_GEN)$(srcdir)/incfiles $(srcdir) > $@.tmp
        @mv $@.tmp $@
 
+dnsdist-lua-ffi-interface.inc: dnsdist-lua-ffi-interface.h
+       echo 'R"FFIContent(' > $@
+       cat $< >> $@
+       echo ')FFIContent"' >> $@
+
 SRC_JS_FILES := $(wildcard src_js/*.js)
 MIN_JS_FILES := $(patsubst src_js/%.js,html/js/%.min.js,$(SRC_JS_FILES))
 
@@ -136,6 +143,7 @@ dnsdist_SOURCES = \
        dnsdist-lua-bindings-packetcache.cc \
        dnsdist-lua-bindings-protobuf.cc \
        dnsdist-lua-ffi.cc dnsdist-lua-ffi.hh \
+       dnsdist-lua-ffi-interface.h dnsdist-lua-ffi-interface.inc \
        dnsdist-lua-inspection.cc \
        dnsdist-lua-inspection-ffi.cc dnsdist-lua-inspection-ffi.hh \
        dnsdist-lua-rules.cc \
diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h
new file mode 100644 (file)
index 0000000..fa8841d
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t;
+
+typedef struct dnsdist_ednsoption {
+  uint16_t    optionCode;
+  uint16_t    len;
+  const void* data;
+} dnsdist_ednsoption_t;
+
+typedef struct dnsdist_http_header {
+  const char* name;
+  const char* value;
+} dnsdist_http_header_t;
+
+typedef struct dnsdist_tag {
+  const char* name;
+  const char* value;
+} dnsdist_tag_t;
+
+void dnsdist_ffi_dnsquestion_get_localaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_local_port(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_remote_port(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_qtype(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_qclass(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+int dnsdist_ffi_dnsquestion_get_rcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+void* dnsdist_ffi_dnsquestion_get_header(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_len(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+size_t dnsdist_ffi_dnsquestion_get_size(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+uint8_t dnsdist_ffi_dnsquestion_get_opcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_tcp(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_skip_cache(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_use_ecs(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_add_xpf(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_ecs_override(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+uint16_t dnsdist_ffi_dnsquestion_get_ecs_prefix_length(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_is_temp_failure_ttl_set(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+uint32_t dnsdist_ffi_dnsquestion_get_temp_failure_ttl(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dnsquestion_get_do(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default")));
+const char* dnsdist_ffi_dnsquestion_get_tag(const dnsdist_ffi_dnsquestion_t* dq, const char* label) __attribute__ ((visibility ("default")));
+const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+
+// returns the length of the resulting 'out' array. 'out' is not set if the length is 0
+size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default")));
+size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default")));
+size_t dnsdist_ffi_dnsquestion_get_tag_array(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_tag_t** out) __attribute__ ((visibility ("default")));
+
+void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_rcode(dnsdist_ffi_dnsquestion_t* dq, int rcode) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_len(dnsdist_ffi_dnsquestion_t* dq, uint16_t len) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_skip_cache(dnsdist_ffi_dnsquestion_t* dq, bool skipCache) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_use_ecs(dnsdist_ffi_dnsquestion_t* dq, bool useECS) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_ecs_override(dnsdist_ffi_dnsquestion_t* dq, bool ecsOverride) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_ecs_prefix_length(dnsdist_ffi_dnsquestion_t* dq, uint16_t ecsPrefixLength) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t tempFailureTTL) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_unset_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
+void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value) __attribute__ ((visibility ("default")));
+
+void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default")));
+
+size_t dnsdist_ffi_dnsquestion_get_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char** out) __attribute__ ((visibility ("default")));
+
+bool dnsdist_ffi_dnsquestion_set_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char* data, size_t dataLen) __attribute__ ((visibility ("default")));
+
+void dnsdist_ffi_dnsquestion_send_trap(dnsdist_ffi_dnsquestion_t* dq, const char* reason, size_t reasonLen) __attribute__ ((visibility ("default")));
index 5653c9f96d5220f976f27e80bddaa551a547ff2a..cfffc2c1e34c4706ee44e27786497b0049404f2a 100644 (file)
@@ -55,6 +55,16 @@ void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq,
   dnsdist_ffi_comboaddress_to_raw(*dq->dq->remote, addr, addrSize);
 }
 
+uint16_t dnsdist_ffi_dnsquestion_get_local_port(const dnsdist_ffi_dnsquestion_t* dq)
+{
+  return dq->dq->local->getPort();
+}
+
+uint16_t dnsdist_ffi_dnsquestion_get_remote_port(const dnsdist_ffi_dnsquestion_t* dq)
+{
+  return dq->dq->remote->getPort();
+}
+
 void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize)
 {
   const auto& storage = dq->dq->qname->getStorage();
@@ -286,6 +296,31 @@ size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* dq, c
 #endif
 }
 
+size_t dnsdist_ffi_dnsquestion_get_tag_array(dnsdist_ffi_dnsquestion_t* dq, const dnsdist_tag_t** out)
+{
+  if (dq->dq->qTag == nullptr || dq->dq->qTag->size() == 0) {
+    return 0;
+  }
+
+  dq->tagsVect.clear();
+  dq->tagsVect.resize(dq->dq->qTag->size());
+  size_t pos = 0;
+
+  for (const auto& tag : *dq->dq->qTag) {
+    auto& entry = dq->tagsVect.at(pos);
+    entry.name = tag.first.c_str();
+    entry.value = tag.second.c_str();
+    ++pos;
+  }
+
+
+  if (!dq->tagsVect.empty()) {
+    *out = dq->tagsVect.data();
+  }
+
+  return dq->tagsVect.size();
+}
+
 void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize)
 {
   dq->result = std::string(str, strSize);
@@ -339,6 +374,11 @@ void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq,
   dq->dq->tempFailureTTL = tempFailureTTL;
 }
 
+void dnsdist_ffi_dnsquestion_unset_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq)
+{
+  dq->dq->tempFailureTTL = boost::none;
+}
+
 void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value)
 {
   if (!dq->dq->qTag) {
@@ -347,3 +387,42 @@ void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char*
 
   dq->dq->qTag->insert({label, value});
 }
+
+size_t dnsdist_ffi_dnsquestion_get_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char** out)
+{
+  dq->trailingData = dq->dq->getTrailingData();
+  if (!dq->trailingData.empty()) {
+    *out = dq->trailingData.data();
+  }
+
+  return dq->trailingData.size();
+}
+
+bool dnsdist_ffi_dnsquestion_set_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char* data, size_t dataLen)
+{
+  return dq->dq->setTrailingData(std::string(data, dataLen));
+}
+
+void dnsdist_ffi_dnsquestion_send_trap(dnsdist_ffi_dnsquestion_t* dq, const char* reason, size_t reasonLen)
+{
+  if (g_snmpAgent && g_snmpTrapsEnabled) {
+    g_snmpAgent->sendDNSTrap(*dq->dq, std::string(reason, reasonLen));
+  }
+}
+
+const std::string& getLuaFFIWrappers()
+{
+  static const std::string interface =
+#include "dnsdist-lua-ffi-interface.inc"
+    ;
+  static const std::string code = R"FFICodeContent(
+  local ffi = require("ffi")
+  local C = ffi.C
+
+  ffi.cdef[[
+)FFICodeContent" + interface + R"FFICodeContent(
+  ]]
+
+)FFICodeContent";
+  return code;
+}
index 05ba6a45608d5664d555abbfc1a05db0d80a87db..913c759474056ab7fd59aebfde132bf4e4882361 100644 (file)
 #include "dnsdist.hh"
 
 extern "C" {
-  typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t;
-
-  typedef struct dnsdist_ednsoption {
-    uint16_t    optionCode;
-    uint16_t    len;
-    const void* data;
-  } dnsdist_ednsoption_t;
-
-  typedef struct dnsdist_http_header {
-    const char* name;
-    const char* value;
-  } dnsdist_http_header_t;
-
-  void dnsdist_ffi_dnsquestion_get_localaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default")));
-  uint16_t dnsdist_ffi_dnsquestion_get_qtype(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  uint16_t dnsdist_ffi_dnsquestion_get_qclass(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  int dnsdist_ffi_dnsquestion_get_rcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  void* dnsdist_ffi_dnsquestion_get_header(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  uint16_t dnsdist_ffi_dnsquestion_get_len(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  size_t dnsdist_ffi_dnsquestion_get_size(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  uint8_t dnsdist_ffi_dnsquestion_get_opcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_tcp(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_skip_cache(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_use_ecs(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_add_xpf(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_ecs_override(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  uint16_t dnsdist_ffi_dnsquestion_get_ecs_prefix_length(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_is_temp_failure_ttl_set(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  uint32_t dnsdist_ffi_dnsquestion_get_temp_failure_ttl(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  bool dnsdist_ffi_dnsquestion_get_do(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_tag(const dnsdist_ffi_dnsquestion_t* dq, const char* label) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-
-  // returns the length of the resulting 'out' array. 'out' is not set if the length is 0
-  size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default")));
-  size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default")));
-
-  void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_rcode(dnsdist_ffi_dnsquestion_t* dq, int rcode) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_len(dnsdist_ffi_dnsquestion_t* dq, uint16_t len) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_skip_cache(dnsdist_ffi_dnsquestion_t* dq, bool skipCache) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_use_ecs(dnsdist_ffi_dnsquestion_t* dq, bool useECS) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_ecs_override(dnsdist_ffi_dnsquestion_t* dq, bool ecsOverride) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_ecs_prefix_length(dnsdist_ffi_dnsquestion_t* dq, uint16_t ecsPrefixLength) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t tempFailureTTL) __attribute__ ((visibility ("default")));
-  void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value) __attribute__ ((visibility ("default")));
-
-  void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default")));
+#include "dnsdist-lua-ffi-interface.h"
 }
 
 // dnsdist_ffi_dnsquestion_t is a lightuserdata
@@ -100,11 +47,15 @@ struct dnsdist_ffi_dnsquestion_t
 
   DNSQuestion* dq{nullptr};
   std::vector<dnsdist_ednsoption_t> ednsOptionsVect;
-  std::vector<dnsdist_http_header> httpHeadersVect;
+  std::vector<dnsdist_http_header_t> httpHeadersVect;
+  std::vector<dnsdist_tag_t> tagsVect;
   std::unordered_map<std::string, std::string> httpHeaders;
+  std::string trailingData;
   boost::optional<std::string> result{boost::none};
   boost::optional<std::string> httpPath{boost::none};
   boost::optional<std::string> httpQueryString{boost::none};
   boost::optional<std::string> httpHost{boost::none};
   boost::optional<std::string> httpScheme{boost::none};
 };
+
+const std::string& getLuaFFIWrappers();
index 790df628fd1a2740a4624a7068c0b7de2d4a267f..eb4b1cfcbffbe110a223de385d75d8dff9c85849 100644 (file)
@@ -900,26 +900,6 @@ class TestDOHFFI(DNSDistDOHTest):
 
     local ffi = require("ffi")
 
-    ffi.cdef[[
-  typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t;
-
-  typedef struct dnsdist_http_header {
-    const char* name;
-    const char* value;
-  } dnsdist_http_header_t;
-
-  void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default")));
-
-  const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-  const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default")));
-
-  size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default")));
-
-  void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default")));
-  ]]
-
     function dohHandler(dq)
       local scheme = ffi.string(ffi.C.dnsdist_ffi_dnsquestion_get_http_scheme(dq))
       local host = ffi.string(ffi.C.dnsdist_ffi_dnsquestion_get_http_host(dq))
index f62a9e3d9e2e7f04bb11c56e2fcfc5c3525c07e8..7b1c8bbeff7eb62f5b3c4c25e74d727eed4a515c 100644 (file)
@@ -390,20 +390,6 @@ class TestEDNSOptionsLuaFFI(DNSDistTest):
     _config_template = """
     local ffi = require("ffi")
 
-    ffi.cdef[[
-  typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t;
-
-  typedef struct dnsdist_ednsoption {
-    uint16_t    optionCode;
-    uint16_t    len;
-    const void* data;
-  } dnsdist_ednsoption_t;
-
-  void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default")));
-  // returns the length of the resulting 'out' array. 'out' is not set if the length is 0
-  size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default")));
-  ]]
-
     function testEDNSOptions(dq)
       local options_ptr = ffi.new("const dnsdist_ednsoption_t *[1]")
       local ret_ptr_param = ffi.cast("const dnsdist_ednsoption_t **", options_ptr)