]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon: ‘net’ package, implemented ‘net.interfaces’
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 29 Mar 2015 22:23:29 +0000 (00:23 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 29 Mar 2015 22:23:29 +0000 (00:23 +0200)
lists available interfaces

daemon/bindings.c
daemon/bindings.h
daemon/engine.c
daemon/engine.h
daemon/main.c

index 1ba5e05c277e63036660033325aaed7ddcbb91e2..5cd28cb0005e9ca4ab52c168cd964ce913ba6ba5 100644 (file)
@@ -14,6 +14,8 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <uv.h>
+
 #include "lib/cache.h"
 #include "daemon/bindings.h"
 
@@ -59,8 +61,19 @@ static int mod_load(lua_State *L)
 /** Unload module. */
 static int mod_unload(lua_State *L)
 {
-       lua_pushstring(L, "not implemented");
-       lua_error(L);
+       /* Check parameters */
+       int n = lua_gettop(L);
+       if (n != 1 || !lua_isstring(L, 1)) {
+               lua_pushstring(L, "expected module name");
+               lua_error(L);
+       }
+       /* Unload engine module */
+       struct engine *engine = engine_luaget(L);
+       int ret = engine_unregister(engine, lua_tostring(L, 1));
+       if (ret != 0) {
+               lua_pushstring(L, kr_strerror(ret));
+               lua_error(L);
+       }
        return 0;
 }
 
@@ -77,11 +90,93 @@ int lib_modules(lua_State *L)
        return 1;
 }
 
-int lib_config(lua_State *L)
+/** List active endpoints. */
+static int net_list(lua_State *L)
+{
+       lua_pushstring(L, "not implemented");
+       lua_error(L);
+       return 0;
+}
+
+/** Listen on endpoint. */
+static int net_listen(lua_State *L)
+{
+       lua_pushstring(L, "not implemented");
+       lua_error(L);
+       return 0;
+}
+
+/** Close endpoint. */
+static int net_close(lua_State *L)
 {
+       lua_pushstring(L, "not implemented");
+       lua_error(L);
        return 0;
 }
 
+/** List available interfaces.
+ * @TODO: Implement as a map {name: { addr: [], mac: "" }}
+ */
+static int net_interfaces(lua_State *L)
+{
+       /* Retrieve interface list */
+       int count = 0;
+       char buf[INET6_ADDRSTRLEN]; /* http://tools.ietf.org/html/rfc4291 */
+       uv_interface_address_t *info = NULL;
+       uv_interface_addresses(&info, &count);
+
+       /* Fill table. */
+       lua_newtable(L);
+       for (int i = count; i--; ) {
+               uv_interface_address_t iface = info[i];
+               lua_newtable(L);
+               lua_pushstring(L, iface.name);
+               lua_setfield(L, -2, "id");
+
+               /* Address */
+               buf[0] = '\0';
+               switch(iface.address.address4.sin_family) {
+               case AF_INET:
+                       uv_ip4_name(&iface.address.address4, buf, sizeof(buf));
+                       break;
+               case AF_INET6:
+                       uv_ip6_name(&iface.address.address6, buf, sizeof(buf));
+                       break;
+               }
+               lua_pushstring(L, buf);
+               lua_setfield(L, -2, "addr");
+
+               /* Hardware address. */
+               char *p = buf;
+               memset(buf, 0, sizeof(buf));
+               for (unsigned k = 0; k < sizeof(iface.phys_addr); ++k) {
+                       sprintf(p, "%0x", iface.phys_addr[k] & 0xff);
+                       p += 2;
+               }
+               lua_pushstring(L, buf);
+               lua_setfield(L, -2, "mac");             
+
+               /* Push table */
+               lua_rawseti(L, -2, i);
+       }
+       uv_free_interface_addresses(info, count);
+
+       return 1;
+}
+
+int lib_net(lua_State *L)
+{
+       static const luaL_Reg lib[] = {
+               { "list",       net_list },
+               { "listen",     net_listen },
+               { "close",      net_close },
+               { "interfaces", net_interfaces },
+               { NULL, NULL }
+       };
+       register_lib(L, "net", lib);
+       return 1;
+}
+
 /** Open cache */
 static int cache_open(lua_State *L)
 {
index d0e2a93d3b1967f630a421c57908973324e01e04..c1ad1a286aff3fc64c580becc4afd8e72bbc10e6 100644 (file)
 int lib_modules(lua_State *L);
 
 /**
- * Load 'config' package.
+ * Load 'net' package.
  * @param  L scriptable
  * @return   number of packages to load
  */
-int lib_config(lua_State *L);
+int lib_net(lua_State *L);
 
 /**
  * Load 'cache' package.
index 39ea18d87a671ae59ac88b34f4774f59d25150b8..fb1d48cb2f4d9aca84fb51debe7214b5ca13abd8 100644 (file)
  * Global bindings.
  */
 
+/** Register module callback into Lua world. */
+#define REGISTER_MODULE_CALL(L, module, cb, name) \
+       lua_pushlightuserdata((L), (module)); \
+       lua_pushlightuserdata((L), (cb)); \
+       lua_pushcclosure((L), l_trampoline, 2); \
+       lua_setfield((L), -2, (name))
+
 /** Print help and available commands. */
 static int l_help(lua_State *L)
 {
@@ -56,26 +63,23 @@ static int l_quit(lua_State *L)
 /** Trampoline function for module properties. */
 static int l_trampoline(lua_State *L)
 {
-       const char *name = lua_tostring(L, lua_upvalueindex(1));
-       const char *property = lua_tostring(L, lua_upvalueindex(2));
+       struct kr_module *module = lua_touserdata(L, lua_upvalueindex(1));
+       void* callback = lua_touserdata(L, lua_upvalueindex(2));
        struct engine *engine = engine_luaget(L);
 
-       /* Find module. */
-       for (unsigned i = 0; i < engine->modules.len; ++i) {
-               struct kr_module *module = &engine->modules.at[i];
-               if (strcmp(module->name, name) != 0) {
-                       continue;
-               }
-               /* Find property. */
-               for (struct kr_prop *p = module->props; p && p->name; ++p) {
-                       if (strcmp(p->name, property) == 0) {
-                               auto_free char *ret = p->cb(engine, module, NULL);
-                               lua_pushstring(L, ret);
-                               return 1;
-                       }
-               }
-               break;
+       /* Now we only have property callback or config,
+        * if we expand the callables, we might need a callback_type.
+        */
+       if (callback == module->config) {
+               const char *param = lua_tostring(L, 1);
+               module->config(module, param);
+       } else {
+               kr_prop_cb *prop = (kr_prop_cb *)callback;
+               auto_free char *ret = prop(engine, module, lua_tostring(L, 1));
+               lua_pushstring(L, ret);
+               return 1;
        }
+
        /* No results */
        return 0;
 }
@@ -186,6 +190,14 @@ int engine_cmd(struct engine *engine, const char *str)
 
 static int engine_loadconf(struct engine *engine)
 {
+       /* Init environment */
+       static const char l_init[] = {
+               #include "daemon/lua/init.inc"
+       };
+       if (luaL_dostring(engine->L, l_init) != 0) {
+               return kr_error(ENOEXEC);
+       }
+
        /* Load config file */
        int ret = 0;
        if(access("config", F_OK ) != -1 ) {
@@ -193,7 +205,7 @@ static int engine_loadconf(struct engine *engine)
        } else {
                /* Load defaults */
                static const char config_init[] = {
-                       #include "daemon/lua/init.inc"
+                       #include "daemon/lua/config.inc"
                };
                ret = luaL_dostring(engine->L, config_init);
        }
@@ -244,11 +256,13 @@ int engine_register(struct engine *engine, const char *name)
        /* Register properties */
        if (module->props) {
                lua_newtable(engine->L);
+               if (module->config != NULL) {
+                       REGISTER_MODULE_CALL(engine->L, module, module->config, "config");
+               }
                for (struct kr_prop *p = module->props; p->name; ++p) {
-                       lua_pushstring(engine->L, module->name);
-                       lua_pushstring(engine->L, p->name);
-                       lua_pushcclosure(engine->L, l_trampoline, 2);
-                       lua_setfield(engine->L, -2, p->name);
+                       if (p->cb != NULL && p->name != NULL) {
+                               REGISTER_MODULE_CALL(engine->L, module, p->cb, p->name);
+                       }
                }
                lua_setglobal(engine->L, module->name);
        }
index 023d45cac8fe6ed8cf241fc530a4b9194b45f23b..5a49f9b0d1708f1f52d6f6a4a0e25ff406e92992 100644 (file)
@@ -20,7 +20,6 @@
  * @internal These are forward decls to allow building modules with engine but without Lua.
  */
 struct lua_State;
-typedef int (*lua_CFunction) (struct lua_State *L);
 
 #include "lib/resolve.h"
 #include "lib/generic/array.h"
@@ -40,5 +39,5 @@ void engine_stop(struct engine *engine);
 int engine_register(struct engine *engine, const char *module);
 int engine_unregister(struct engine *engine, const char *module);
 /** Return engine light userdata. */
-void engine_lualib(struct engine *engine, const char *name, lua_CFunction lib_cb);
+void engine_lualib(struct engine *engine, const char *name, int (*lib_cb) (struct lua_State *));
 struct engine *engine_luaget(struct lua_State *L);
\ No newline at end of file
index 396bdaba7aaf485657088a6555bd9e1c0efccad7..41411e66f307104a2d788981104362f264b36121 100644 (file)
@@ -144,8 +144,8 @@ int main(int argc, char **argv)
 
        /* Load bindings */
        engine_lualib(&engine, "modules", lib_modules);
-       engine_lualib(&engine, "config", lib_config);
-       engine_lualib(&engine, "cache",  lib_cache);
+       engine_lualib(&engine, "net",     lib_net);
+       engine_lualib(&engine, "cache",   lib_cache);
 
        /* Create main worker. */
        struct worker_ctx worker = {