From: Marek Vavruša Date: Sun, 29 Mar 2015 22:23:29 +0000 (+0200) Subject: daemon: ‘net’ package, implemented ‘net.interfaces’ X-Git-Tag: v1.0.0-beta1~274^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77a1a1c4f9e9a5021da2bc78d4077cbc922baab0;p=thirdparty%2Fknot-resolver.git daemon: ‘net’ package, implemented ‘net.interfaces’ lists available interfaces --- diff --git a/daemon/bindings.c b/daemon/bindings.c index 1ba5e05c2..5cd28cb00 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -14,6 +14,8 @@ along with this program. If not, see . */ +#include + #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) { diff --git a/daemon/bindings.h b/daemon/bindings.h index d0e2a93d3..c1ad1a286 100644 --- a/daemon/bindings.h +++ b/daemon/bindings.h @@ -33,11 +33,11 @@ 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. diff --git a/daemon/engine.c b/daemon/engine.c index 39ea18d87..fb1d48cb2 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -27,6 +27,13 @@ * 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); } diff --git a/daemon/engine.h b/daemon/engine.h index 023d45cac..5a49f9b0d 100644 --- a/daemon/engine.h +++ b/daemon/engine.h @@ -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 diff --git a/daemon/main.c b/daemon/main.c index 396bdaba7..41411e66f 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -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 = {