]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/bindings: some basic Lua interface to rplan and query
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 15 Jun 2015 20:53:07 +0000 (22:53 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 15 Jun 2015 20:53:07 +0000 (22:53 +0200)
daemon/bindings/kres.c
daemon/bindings/kres.h
daemon/ffimodule.c

index 164a18f183af5a11aceb1d217aaa14b36cf005d4..f9d11c1625a4a9be9acea3f7071cb036f314e042 100644 (file)
 #include "daemon/bindings/kres.h"
 #include "daemon/bindings.h"
 
-/* Metatable list */
-#define META_PKT "kres.meta_pkt"
+/** @internal Register metatable. */
+#define META_REGISTER(L, funcs, name) \
+       luaL_newmetatable((L), (name)); \
+       luaL_setfuncs((L), (funcs), 0); \
+       lua_pushvalue((L), -1); \
+       lua_setfield((L), -2, "__index"); \
+       lua_pop((L), 1);
+
+/** @internal Shortcut for dname conversion. */
+static inline void lua_pushdname(lua_State *L, const knot_dname_t *name)
+{
+       char dname_str[KNOT_DNAME_MAXLEN];
+       knot_dname_to_str(dname_str, name, sizeof(dname_str));
+       lua_pushstring(L, dname_str);
+}
 
 /* 
  * Packet interface
@@ -88,45 +101,89 @@ static int pkt_qclass(lua_State *L)
 static int pkt_qname(lua_State *L)
 {
        knot_pkt_t *pkt = lua_touserdata(L, 1);
-       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);
+       lua_pushdname(L, knot_pkt_qname(pkt));
        return 1;       
 }
 
 #warning TODO: record interfaces
 
-static int pkt_meta_set(lua_State *L)
+static int pkt_meta_register(lua_State *L)
 {
-       static const luaL_Reg pkt_wrap[] = {
-               { "flag",      pkt_flag},
-               { "rcode",     pkt_rcode},
-               { "opcode",    pkt_opcode},
-               { "qtype",     pkt_qtype },
+       static const luaL_Reg wrap[] = {
+               { "flag",      pkt_flag   },
+               { "rcode",     pkt_rcode  },
+               { "opcode",    pkt_opcode },
+               { "qtype",     pkt_qtype  },
                { "qclass",    pkt_qclass },
-               { "qname",     pkt_qname },
+               { "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);
+       META_REGISTER (L, wrap, META_PKT);
        return 0;
 }
 
-static int pkt_meta_get(lua_State *L)
+/**
+ * Query interface.
+ */
+
+static int query_qtype(lua_State *L)
 {
-       luaL_getmetatable(L, META_PKT);
-       lua_setmetatable(L, -2);
+       struct kr_query *qry = lua_touserdata(L, 1);
+       lua_pushnumber(L, qry->stype);
        return 1;
 }
 
+static int query_qclass(lua_State *L)
+{
+       struct kr_query *qry = lua_touserdata(L, 1);
+       lua_pushnumber(L, qry->sclass);
+       return 1;       
+}
+
+static int query_qname(lua_State *L)
+{
+       struct kr_query *qry = lua_touserdata(L, 1);
+       lua_pushdname(L, qry->sname);
+       return 1;       
+}
+
+static int query_meta_register(lua_State *L)
+{
+       static const luaL_Reg wrap[] = {
+               { "qtype",     query_qtype  },
+               { "qclass",    query_qclass },
+               { "qname",     query_qname  },
+               { NULL, NULL }
+       };
+       META_REGISTER (L, wrap, META_QUERY);
+       return 0;
+}
+
 /**
  * Resolution context interface.
  */
 
+static int rplan_query(lua_State *L)
+{
+       struct kr_rplan *rplan = lua_touserdata(L, 1);
+       lua_pushlightuserdata(L, kr_rplan_current(rplan));
+       luaL_getmetatable(L, META_QUERY);
+       lua_setmetatable(L, -2);
+       return 1;
+}
+
+static int rplan_meta_register(lua_State *L)
+{
+       static const luaL_Reg wrap[] = {
+               { "query",      rplan_query },
+               // { "pending",    rplan_pending },
+               // { "resolved",   rplan_resolved },
+               { NULL, NULL }
+       };
+       META_REGISTER (L, wrap, META_RPLAN);
+       return 0;
+}
+
 #warning TODO: context interface, rplan
 
 #define WRAP_NUMBER(L, name, val) \
@@ -146,7 +203,6 @@ static int pkt_meta_get(lua_State *L)
 int lib_kres(lua_State *L)
 {
        static const luaL_Reg lib[] = {
-               { "packet", pkt_meta_get },
                { NULL, NULL }
        };
        /* Create module and register functions */
@@ -162,6 +218,8 @@ int lib_kres(lua_State *L)
        WRAP_LUT(L, "opcode", knot_opcode_names);
        WRAP_LUT(L, "wire",   wire_flag_names);
        /* Register metatables */
-       pkt_meta_set(L);
+       pkt_meta_register(L);
+       query_meta_register(L);
+       rplan_meta_register(L);
        return 1;       
 }
\ No newline at end of file
index 39209e03a3b530083f9f763ca43bf1a1530b5fb8..d9881e36e351df2801d4bfbc166754309c1fb1e8 100644 (file)
 
 #include "daemon/bindings.h"
 
+/* Metatable list */
+#define META_PKT   "kres.meta_pkt"
+#define META_QUERY "kres.meta_query"
+#define META_RPLAN "kres.meta_rplan"
+
 /**
  * Load libkres library.
  * @param  L scriptable
index d1482b184a011e4fd0762b131a7684707d7de4c6..26eed9674097a4422581dbfa44e27c4f1536366d 100644 (file)
@@ -17,8 +17,9 @@
 #include <uv.h>
 
 #include "daemon/engine.h"
-#include "daemon/bindings.h"
 #include "daemon/ffimodule.h"
+#include "daemon/bindings.h"
+#include "daemon/bindings/kres.h"
 #include "lib/module.h"
 #include "lib/layer.h"
 
 #define l_resume(L, argc) lua_resume((L), (argc))
 #endif
 
+/** @internal Set metatable on the object on stack. */
+static void set_metatable(lua_State *L, const char *tname)
+{
+       luaL_getmetatable(L, tname);
+       lua_setmetatable(L, -2);
+}
+
 /** @internal Helper for retrieving the right function entrypoint. */
 static inline lua_State *l_ffi_preface(struct kr_module *module, const char *call) {
        lua_State *L = module->lib;
@@ -131,51 +139,61 @@ static int l_ffi_deinit(struct kr_module *module)
                lua_pop(L, 1); \
                return ctx->state; \
        } \
-       lua_pushnumber(L, ctx->state);
+       lua_pushnumber(L, ctx->state)
+
+/** @internal Push rplan and metatable. */
+#define LAYER_PUSH_RPLAN(ctx) do { \
+       struct kr_request *req = (ctx)->data; \
+       lua_pushlightuserdata(L, &req->rplan); \
+       set_metatable(L, META_RPLAN); \
+} while (0)
 
 static int l_ffi_layer_begin(knot_layer_t *ctx, void *module_param)
 {
+       ctx->data = module_param;
        LAYER_FFI_CALL(ctx, "begin");
        lua_pushlightuserdata(L, module_param);
-       ctx->data = module_param;
        return l_ffi_call(L, 2);
 }
 
 static int l_ffi_layer_reset(knot_layer_t *ctx)
 {
        LAYER_FFI_CALL(ctx, "reset");
-       lua_pushlightuserdata(L, ctx->data);
+       LAYER_PUSH_RPLAN(ctx);
        return l_ffi_call(L, 2);
 }
 
 static int l_ffi_layer_finish(knot_layer_t *ctx)
 {
        LAYER_FFI_CALL(ctx, "finish");
-       lua_pushlightuserdata(L, ctx->data);
+       LAYER_PUSH_RPLAN(ctx);
        return l_ffi_call(L, 2);
 }
 
 static int l_ffi_layer_consume(knot_layer_t *ctx, knot_pkt_t *pkt)
 {
        LAYER_FFI_CALL(ctx, "consume");
-       lua_pushlightuserdata(L, ctx->data);
+       LAYER_PUSH_RPLAN(ctx);
        lua_pushlightuserdata(L, pkt);
+       set_metatable(L, META_PKT);
        return l_ffi_call(L, 3);
 }
 
 static int l_ffi_layer_produce(knot_layer_t *ctx, knot_pkt_t *pkt)
 {
        LAYER_FFI_CALL(ctx, "produce");
-       lua_pushlightuserdata(L, ctx->data);
+       LAYER_PUSH_RPLAN(ctx);
        lua_pushlightuserdata(L, pkt);
+       set_metatable(L, META_PKT);
        return l_ffi_call(L, 3);
 }
 
 static int l_ffi_layer_fail(knot_layer_t *ctx, knot_pkt_t *pkt)
 {
        LAYER_FFI_CALL(ctx, "fail");
-       lua_pushlightuserdata(L, ctx->data);
+       LAYER_PUSH_RPLAN(ctx);
        lua_pushlightuserdata(L, pkt);
+       set_metatable(L, META_PKT);
        return l_ffi_call(L, 3);
 }
 
@@ -200,7 +218,8 @@ static const knot_layer_api_t* l_ffi_layer(struct kr_module *module)
                api = malloc(sizeof(*api));
                if (api) {
                        memset(api, 0, sizeof(*api));
-                       LAYER_REGISTER(L, api, begin);
+                       /* Begin is always set, as it initializes layer baton. */
+                       api->begin = l_ffi_layer_begin;
                        LAYER_REGISTER(L, api, finish);
                        LAYER_REGISTER(L, api, consume);
                        LAYER_REGISTER(L, api, produce);
@@ -218,6 +237,7 @@ static const knot_layer_api_t* l_ffi_layer(struct kr_module *module)
 
 #undef LAYER_REGISTER
 #undef LAYER_FFI_CALL
+#undef LAYER_PUSH_RPLAN
 
 /** @internal Helper macro for function presence check. */
 #define REGISTER_FFI_CALL(L, attr, name, cb) do { \