]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/bindings: minimal Lua interface to packet and DNS primitives (wip)
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 15 Jun 2015 08:26:25 +0000 (10:26 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 15 Jun 2015 08:30:50 +0000 (10:30 +0200)
daemon/bindings/kres.c [new file with mode: 0644]
daemon/bindings/kres.h [new file with mode: 0644]
daemon/main.c

diff --git a/daemon/bindings/kres.c b/daemon/bindings/kres.c
new file mode 100644 (file)
index 0000000..986d13b
--- /dev/null
@@ -0,0 +1,167 @@
+/*  Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "daemon/bindings/kres.h"
+#include "daemon/bindings.h"
+
+/* Metatable list */
+#define META_PKT "kres.meta_pkt"
+
+/* 
+ * Packet interface
+ */
+
+#define WIRE_FLAGS(X) \
+       X(AA,aa) X(AD,ad) X(CD,cd) X(RD,rd) X(QR,qr) X(RA,ra) X(TC,tc)
+enum {
+       #define X(flag, _) WIRE_ ## flag,
+       WIRE_FLAGS(X)
+       #undef X
+};
+static lookup_table_t wire_flag_names[] = {
+       #define X(flag, _) { WIRE_ ## flag, #flag },
+       WIRE_FLAGS(X)
+       #undef X
+};
+
+static int pkt_flag(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       if (lua_gettop(L) > 1 && lua_isnumber(L, 2)) {
+               int flag_id = lua_tonumber(L, 2);
+               switch(flag_id) {
+               #define X(flag, code) case WIRE_ ## flag: knot_wire_set_ ## code (pkt->wire); break;
+               WIRE_FLAGS(X)
+               #undef X
+               }
+       }
+       return 0;
+}
+
+static int pkt_opcode(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       if (lua_gettop(L) > 1 && lua_isnumber(L, 2)) {
+               knot_wire_set_opcode(pkt->wire, lua_tonumber(L, 2));
+       }
+       lua_pushnumber(L, knot_wire_get_opcode(pkt->wire));
+       return 1;
+}
+
+static int pkt_rcode(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       if (lua_gettop(L) > 1 && lua_isnumber(L, 2)) {
+               knot_wire_set_rcode(pkt->wire, lua_tonumber(L, 2));
+       }
+       lua_pushnumber(L, knot_wire_get_rcode(pkt->wire));
+       return 1;
+}
+
+static int pkt_qtype(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       lua_pushnumber(L, knot_pkt_qtype(pkt));
+       return 1;
+}
+
+static int pkt_qclass(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       lua_pushnumber(L, knot_pkt_qclass(pkt));
+       return 1;       
+}
+
+static int pkt_qname(lua_State *L)
+{
+       knot_pkt_t *pkt = luaL_checkudata(L, 1, META_PKT);
+       const knot_dname_t *dname = knot_pkt_qname(pkt);
+       char dname_str[KNOT_DNAME_MAXLEN];
+       knot_dname_to_str(dname_str, dname, sizeof(dname_str));
+       lua_pushstring(L, dname_str);
+       return 1;       
+}
+
+#warning TODO: record interfaces
+
+static int pkt_meta_set(lua_State *L)
+{
+       static const luaL_Reg pkt_wrap[] = {
+               { "flag",      pkt_flag},
+               { "rcode",     pkt_rcode},
+               { "opcode",    pkt_opcode},
+               { "qtype",     pkt_qtype },
+               { "qclass",    pkt_qclass },
+               { "qname",     pkt_qname },
+               { NULL, NULL }
+       };
+       luaL_newmetatable(L, META_PKT);
+       luaL_setfuncs(L, pkt_wrap, 0);
+       lua_pushvalue(L, -1);
+       lua_setfield(L, -2, "__index");
+       lua_pop(L, 1);
+       return 0;
+}
+
+static int pkt_meta_get(lua_State *L)
+{
+       luaL_getmetatable(L, META_PKT);
+       lua_setmetatable(L, -2);
+       return 1;
+}
+
+/**
+ * Resolution context interface.
+ */
+
+#warning TODO: context interface, rplan
+
+#define WRAP_NUMBER(L, name, val) \
+       lua_pushnumber((L), (val)); \
+       lua_setfield((L), -2, (name))
+
+#define WRAP_CONST(L, name, prefix...) \
+       WRAP_NUMBER(L, #name, prefix ## name)
+
+#define WRAP_LUT(L, prefix, table) \
+       lua_newtable(L); \
+       for (lookup_table_t *elm = (table); elm->name; ++elm) { \
+               WRAP_NUMBER((L), elm->name, elm->id); \
+       } \
+       lua_setfield((L), -2, (prefix))
+
+int lib_kres(lua_State *L)
+{
+       static const luaL_Reg lib[] = {
+               { "packet", pkt_meta_get },
+               { NULL, NULL }
+       };
+       /* Create module and register functions */
+       register_lib(L, "kres", lib);
+       /* Register states */
+       WRAP_CONST(L, NOOP,    KNOT_STATE_);
+       WRAP_CONST(L, CONSUME, KNOT_STATE_);
+       WRAP_CONST(L, PRODUCE, KNOT_STATE_);
+       WRAP_CONST(L, DONE,    KNOT_STATE_);
+       WRAP_CONST(L, FAIL,    KNOT_STATE_);
+       /* Register RCODE, OPCODE */
+       WRAP_LUT(L, "rcode",  knot_rcode_names);
+       WRAP_LUT(L, "opcode", knot_opcode_names);
+       WRAP_LUT(L, "wire",   wire_flag_names);
+       /* Register metatables */
+       pkt_meta_set(L);
+       return 1;       
+}
\ No newline at end of file
diff --git a/daemon/bindings/kres.h b/daemon/bindings/kres.h
new file mode 100644 (file)
index 0000000..39209e0
--- /dev/null
@@ -0,0 +1,30 @@
+/*  Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Lua-friendly bindings to resolver library parts,
+ * notably packet parsing and interpretation and operation on primitives like domain names.
+ */
+#pragma once
+
+#include "daemon/bindings.h"
+
+/**
+ * Load libkres library.
+ * @param  L scriptable
+ * @return   number of packages to load
+ */
+int lib_kres(lua_State *L);
\ No newline at end of file
index 83e82429f8e91492ca8546f3725b2ab67ea644b6..42a08c624fe436d7342eb2eb6c1d6a95c8da098b 100644 (file)
@@ -27,6 +27,7 @@
 #include "daemon/worker.h"
 #include "daemon/engine.h"
 #include "daemon/bindings.h"
+#include "daemon/bindings/kres.h"
 
 static void tty_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
 {
@@ -145,6 +146,7 @@ int main(int argc, char **argv)
        engine_lualib(&engine, "net",     lib_net);
        engine_lualib(&engine, "cache",   lib_cache);
        engine_lualib(&engine, "event",   lib_event);
+       engine_lualib(&engine, "kres",    lib_kres);
 
        /* Create main worker. */
        struct worker_ctx *worker = mm_alloc(&pool, sizeof(*worker));