Commit 039504d4 authored by Petr Špaček's avatar Petr Špaček

Merge branch 'nitpicks-lua' into 'master'

smaller changes, mainly around lua error handling

See merge request !768
parents b52fb759 f283f729
Pipeline #45395 failed with stages
in 6 minutes and 16 seconds
......@@ -14,6 +14,10 @@ Improvements
- policy module: policy.rpz() will watch the file for changes by default
- packaging: lua cqueues added to default dependencies where available
Module API changes
------------------
- kr_straddr_split() changed API a bit (compiler will catch that)
Knot Resolver 3.2.1 (2019-01-10)
================================
......
......@@ -27,10 +27,8 @@ struct kr_cache * cache_assert_open(lua_State *L)
struct engine *engine = engine_luaget(L);
struct kr_cache *cache = &engine->resolver.cache;
assert(cache);
if (!cache || !kr_cache_is_open(cache)) {
format_error(L, "no cache is open yet, use cache.open() or cache.size, etc.");
lua_error(L);
}
if (!cache || !kr_cache_is_open(cache))
lua_error_p(L, "no cache is open yet, use cache.open() or cache.size, etc.");
return cache;
}
......@@ -80,10 +78,9 @@ static int cache_checkpoint(lua_State *L)
return 1;
}
if (lua_gettop(L) != 1 || !lua_isboolean(L, 1) || !lua_toboolean(L, 1)) {
format_error(L, "cache.checkpoint() takes no parameters or a true value");
lua_error(L);
}
if (lua_gettop(L) != 1 || !lua_isboolean(L, 1) || !lua_toboolean(L, 1))
lua_error_p(L, "cache.checkpoint() takes no parameters or a true value");
kr_cache_make_checkpoint(cache);
return 1;
}
......@@ -129,15 +126,14 @@ static int cache_max_ttl(lua_State *L)
int n = lua_gettop(L);
if (n > 0) {
if (!lua_isnumber(L, 1)) {
format_error(L, "expected 'max_ttl(number ttl)'");
lua_error(L);
}
if (!lua_isnumber(L, 1) || n > 1)
lua_error_p(L, "expected 'max_ttl(number ttl)'");
uint32_t min = cache->ttl_min;
int64_t ttl = lua_tonumber(L, 1);
if (ttl < 0 || ttl < min || ttl > UINT32_MAX) {
format_error(L, "max_ttl must be larger than minimum TTL, and in range <1, " STR(UINT32_MAX) ">'");
lua_error(L);
int64_t ttl = lua_tointeger(L, 1);
if (ttl < 1 || ttl < min || ttl > UINT32_MAX) {
lua_error_p(L,
"max_ttl must be larger than minimum TTL, and in range <1, "
STR(UINT32_MAX) ">'");
}
cache->ttl_max = ttl;
}
......@@ -152,15 +148,14 @@ static int cache_min_ttl(lua_State *L)
int n = lua_gettop(L);
if (n > 0) {
if (!lua_isnumber(L, 1)) {
format_error(L, "expected 'min_ttl(number ttl)'");
lua_error(L);
}
if (!lua_isnumber(L, 1))
lua_error_p(L, "expected 'min_ttl(number ttl)'");
uint32_t max = cache->ttl_max;
int64_t ttl = lua_tonumber(L, 1);
int64_t ttl = lua_tointeger(L, 1);
if (ttl < 0 || ttl > max || ttl > UINT32_MAX) {
format_error(L, "min_ttl must be smaller than maximum TTL, and in range <0, " STR(UINT32_MAX) ">'");
lua_error(L);
lua_error_p(L,
"min_ttl must be smaller than maximum TTL, and in range <0, "
STR(UINT32_MAX) ">'");
}
cache->ttl_min = ttl;
}
......@@ -173,28 +168,24 @@ static int cache_open(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n < 1 || !lua_isnumber(L, 1)) {
format_error(L, "expected 'open(number max_size, string config = \"\")'");
lua_error(L);
}
if (n < 1 || !lua_isnumber(L, 1))
lua_error_p(L, "expected 'open(number max_size, string config = \"\")'");
/* Select cache storage backend */
struct engine *engine = engine_luaget(L);
lua_Number csize_lua = lua_tonumber(L, 1);
lua_Number csize_lua = lua_tointeger(L, 1);
if (!(csize_lua >= 8192 && csize_lua < SIZE_MAX)) { /* min. is basically arbitrary */
format_error(L, "invalid cache size specified, it must be in range <8192, " STR(SIZE_MAX) ">");
lua_error(L);
lua_error_p(L, "invalid cache size specified, it must be in range <8192, "
STR(SIZE_MAX) ">");
}
size_t cache_size = csize_lua;
const char *conf = n > 1 ? lua_tostring(L, 2) : NULL;
const char *uri = conf;
const struct kr_cdb_api *api = cache_select(engine, &conf);
if (!api) {
format_error(L, "unsupported cache backend");
lua_error(L);
}
if (!api)
lua_error_p(L, "unsupported cache backend");
/* Close if already open */
kr_cache_close(&engine->resolver.cache);
......@@ -268,20 +259,15 @@ static int cache_prune(lua_State *L)
/* Check parameters */
int prune_max = UINT16_MAX;
int n = lua_gettop(L);
if (n >= 1 && lua_isnumber(L, 1)) {
if (n >= 1 && lua_isnumber(L, 1))
prune_max = lua_tointeger(L, 1);
}
/* Check if API supports pruning. */
int ret = kr_error(ENOSYS);
if (cache->api->prune) {
if (cache->api->prune)
ret = cache->api->prune(cache->db, prune_max);
}
/* Commit and format result. */
if (ret < 0) {
format_error(L, kr_strerror(ret));
lua_error(L);
}
lua_error_maybe(L, ret);
lua_pushinteger(L, ret);
return 1;
}
......@@ -293,10 +279,7 @@ static int cache_clear_everything(lua_State *L)
/* Clear records and packets. */
int ret = kr_cache_clear(cache);
if (ret < 0) {
format_error(L, kr_strerror(ret));
lua_error(L);
}
lua_error_maybe(L, ret);
/* Clear reputation tables */
struct engine *engine = engine_luaget(L);
......@@ -346,19 +329,14 @@ static int cache_get(lua_State *L)
/* Check parameters */
int n = lua_gettop(L);
if (n < 1 || !lua_isstring(L, 1)) {
format_error(L, "expected 'cache.get(string key)'");
lua_error(L);
}
if (n < 1 || !lua_isstring(L, 1))
lua_error_p(L, "expected 'cache.get(string key)'");
/* Retrieve set of keys */
const char *prefix = lua_tostring(L, 1);
knot_db_val_t keyval[100][2];
int ret = cache_prefixed(cache, prefix, false/*FIXME*/, keyval, 100);
if (ret < 0) {
format_error(L, kr_strerror(ret));
lua_error(L);
}
lua_error_maybe(L, ret);
/* Format output */
lua_newtable(L);
for (int i = 0; i < ret; ++i) {
......@@ -369,10 +347,8 @@ static int cache_get(lua_State *L)
#endif
static int cache_get(lua_State *L)
{
int ret = kr_error(ENOSYS);
format_error(L, kr_strerror(ret));
lua_error(L);
return ret;
lua_error_maybe(L, ENOSYS);
return kr_error(ENOSYS); /* doesn't happen */
}
/** Set time interval for cleaning rtt cache.
......@@ -391,15 +367,13 @@ static int cache_ns_tout(lua_State *L)
return 1;
}
if (!lua_isnumber(L, 1)) {
format_error(L, "expected 'cache.ns_tout(interval in ms)'");
lua_error(L);
}
if (!lua_isnumber(L, 1))
lua_error_p(L, "expected 'cache.ns_tout(interval in ms)'");
lua_Integer interval_lua = lua_tointeger(L, 1);
if (!(interval_lua > 0 && interval_lua < UINT_MAX)) {
format_error(L, "invalid interval specified, it must be in range > 0, < " STR(UINT_MAX));
lua_error(L);
lua_error_p(L, "invalid interval specified, it must be in range > 0, < "
STR(UINT_MAX));
}
ctx->cache_rtt_tout_retry_interval = interval_lua;
......
......@@ -71,10 +71,8 @@ static void event_fdcallback(uv_poll_t* handle, int status, int events)
static int event_sched(lua_State *L, unsigned timeout, unsigned repeat)
{
uv_timer_t *timer = malloc(sizeof(*timer));
if (!timer) {
format_error(L, "out of memory");
lua_error(L);
}
if (!timer)
lua_error_p(L, "out of memory");
/* Start timer with the reference */
uv_loop_t *loop = uv_default_loop();
......@@ -82,8 +80,7 @@ static int event_sched(lua_State *L, unsigned timeout, unsigned repeat)
int ret = uv_timer_start(timer, event_callback, timeout, repeat);
if (ret != 0) {
free(timer);
format_error(L, "couldn't start the event");
lua_error(L);
lua_error_p(L, "couldn't start the event");
}
/* Save callback and timer in registry */
......@@ -104,32 +101,27 @@ static int event_after(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2)) {
format_error(L, "expected 'after(number timeout, function)'");
lua_error(L);
}
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2))
lua_error_p(L, "expected 'after(number timeout, function)'");
return event_sched(L, lua_tonumber(L, 1), 0);
return event_sched(L, lua_tointeger(L, 1), 0);
}
static int event_recurrent(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2)) {
format_error(L, "expected 'recurrent(number interval, function)'");
lua_error(L);
}
return event_sched(L, 0, lua_tonumber(L, 1));
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2))
lua_error_p(L, "expected 'recurrent(number interval, function)'");
return event_sched(L, 0, lua_tointeger(L, 1));
}
static int event_cancel(lua_State *L)
{
int n = lua_gettop(L);
if (n < 1 || !lua_isnumber(L, 1)) {
format_error(L, "expected 'cancel(number event)'");
lua_error(L);
}
if (n < 1 || !lua_isnumber(L, 1))
lua_error_p(L, "expected 'cancel(number event)'");
/* Fetch event if it exists */
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_tointeger(L, 1));
......@@ -151,10 +143,8 @@ static int event_cancel(lua_State *L)
static int event_reschedule(lua_State *L)
{
int n = lua_gettop(L);
if (n < 2 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2)) {
format_error(L, "expected 'reschedule(number event, number timeout)'");
lua_error(L);
}
if (n < 2 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2))
lua_error_p(L, "expected 'reschedule(number event, number timeout)'");
/* Fetch event if it exists */
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_tointeger(L, 1));
......@@ -185,19 +175,15 @@ static int event_fdwatch(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2)) {
format_error(L, "expected 'socket(number fd, function)'");
lua_error(L);
}
if (n < 2 || !lua_isnumber(L, 1) || !lua_isfunction(L, 2))
lua_error_p(L, "expected 'socket(number fd, function)'");
uv_poll_t *handle = malloc(sizeof(*handle));
if (!handle) {
format_error(L, "out of memory");
lua_error(L);
}
if (!handle)
lua_error_p(L, "out of memory");
/* Start timer with the reference */
int sock = lua_tonumber(L, 1);
int sock = lua_tointeger(L, 1);
uv_loop_t *loop = uv_default_loop();
#if defined(__APPLE__) || defined(__FreeBSD__)
/* libuv is buggy and fails to create poller for
......@@ -219,8 +205,7 @@ static int event_fdwatch(lua_State *L)
}
if (ret != 0) {
free(handle);
format_error(L, "couldn't start event poller");
lua_error(L);
lua_error_p(L, "couldn't start event poller");
}
/* Save callback and timer in registry */
......
......@@ -15,6 +15,7 @@
*/
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
/* Each of these just creates the correspondingly named lua table of functions. */
......@@ -44,24 +45,23 @@ void kr_bindings_register(lua_State *L)
lualib(L, "worker", kr_bindings_worker);
}
int format_error(lua_State* L, const char *err)
void lua_error_p(lua_State *L, const char *fmt, ...)
{
lua_Debug d;
lua_getstack(L, 1, &d);
/* error message prefix */
lua_getinfo(L, "Sln", &d);
if (strncmp(d.short_src, "[", 1) != 0) {
lua_pushstring(L, d.short_src);
lua_pushstring(L, ":");
lua_pushnumber(L, d.currentline);
lua_pushstring(L, ": error: ");
lua_concat(L, 4);
} else {
lua_pushstring(L, "error: ");
/* Push formatted custom message, prepended with "ERROR: ". */
lua_pushliteral(L, "ERROR: ");
{
va_list args;
va_start(args, fmt);
lua_pushvfstring(L, fmt, args);
va_end(args);
}
/* error message */
lua_pushstring(L, err);
lua_concat(L, 2);
return 1;
lua_concat(L, 2);
/* Add a stack trace and throw the result as a lua error. */
luaL_traceback(L, L, lua_tostring(L, -1), 0);
lua_error(L);
/* TODO: we might construct a little more friendly trace by using luaL_where().
* In particular, in case the error happens in a function that was called
* directly from a config file (the most common case), there isn't much need
* to format the trace in this heavy way. */
}
......@@ -39,12 +39,29 @@
#define STR(s) STRINGIFY_TOKEN(s)
#define STRINGIFY_TOKEN(s) #s
/** @internal Prefix error with file:line
* Implementation in ./impl.c */
int KR_COLD format_error(lua_State* L, const char *err);
/** Throw a formatted lua error.
*
* The message will get prefixed by "ERROR: " and supplemented by stack trace.
* \return never! It calls lua_error().
*
* Example:
ERROR: not a valid pin_sha256: 'a1Z/3ek=', raw length 5 instead of 32
stack traceback:
[C]: in function 'tls_client'
/PathToPREFIX/lib/kdns_modules/policy.lua:175: in function 'TLS_FORWARD'
/PathToConfig.lua:46: in main chunk
*/
KR_PRINTF(2) KR_NORETURN KR_COLD
void lua_error_p(lua_State *L, const char *fmt, ...);
/** @internal Annotate for static checkers. */
KR_NORETURN int lua_error(lua_State *L);
/** Shortcut for common case. */
static inline void lua_error_maybe(lua_State *L, int err)
{
if (err) lua_error_p(L, "%s", kr_strerror(err));
}
static inline struct worker_ctx *wrk_luaget(lua_State *L) {
lua_getglobal(L, "__worker");
struct worker_ctx *worker = lua_touserdata(L, -1);
......
......@@ -35,15 +35,12 @@ static int mod_load(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n != 1 || !lua_isstring(L, 1)) {
format_error(L, "expected 'load(string name)'");
lua_error(L);
}
if (n != 1 || !lua_isstring(L, 1))
lua_error_p(L, "expected 'load(string name)'");
/* Parse precedence declaration */
char *declaration = strdup(lua_tostring(L, 1));
if (!declaration) {
if (!declaration)
return kr_error(ENOMEM);
}
const char *name = strtok(declaration, " ");
const char *precedence = strtok(NULL, " ");
const char *ref = strtok(NULL, " ");
......@@ -53,11 +50,10 @@ static int mod_load(lua_State *L)
free(declaration);
if (ret != 0) {
if (ret == kr_error(EIDRM)) {
format_error(L, "referenced module not found");
lua_error_p(L, "referenced module not found");
} else {
format_error(L, kr_strerror(ret));
lua_error_maybe(L, ret);
}
lua_error(L);
}
lua_pushboolean(L, 1);
......@@ -69,17 +65,12 @@ static int mod_unload(lua_State *L)
{
/* Check parameters */
int n = lua_gettop(L);
if (n != 1 || !lua_isstring(L, 1)) {
format_error(L, "expected 'unload(string name)'");
lua_error(L);
}
if (n != 1 || !lua_isstring(L, 1))
lua_error_p(L, "expected 'unload(string name)'");
/* Unload engine module */
struct engine *engine = engine_luaget(L);
int ret = engine_unregister(engine, lua_tostring(L, 1));
if (ret != 0) {
format_error(L, kr_strerror(ret));
lua_error(L);
}
lua_error_maybe(L, ret);
lua_pushboolean(L, 1);
return 1;
......
This diff is collapsed.
......@@ -27,17 +27,13 @@ static int wrk_resolve(lua_State *L)
}
uint8_t dname[KNOT_DNAME_MAXLEN];
if (!knot_dname_from_str(dname, lua_tostring(L, 1), sizeof(dname))) {
lua_pushstring(L, "invalid qname");
lua_error(L);
};
if (!knot_dname_from_str(dname, lua_tostring(L, 1), sizeof(dname)))
lua_error_p(L, "invalid qname");
/* Check class and type */
uint16_t rrtype = lua_tointeger(L, 2);
if (!lua_isnumber(L, 2)) {
lua_pushstring(L, "invalid RR type");
lua_error(L);
}
if (!lua_isnumber(L, 2))
lua_error_p(L, "invalid RR type");
uint16_t rrclass = lua_tointeger(L, 3);
if (!lua_isnumber(L, 3)) { /* Default class is IN */
......@@ -46,17 +42,13 @@ static int wrk_resolve(lua_State *L)
/* Add query options */
const struct kr_qflags *options = lua_topointer(L, 4);
if (!options) { /* but we rely on the lua wrapper when dereferencing non-NULL */
lua_pushstring(L, "invalid options");
lua_error(L);
}
if (!options) /* but we rely on the lua wrapper when dereferencing non-NULL */
lua_error_p(L, "invalid options");
/* Create query packet */
knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_EDNS_MAX_UDP_PAYLOAD, NULL);
if (!pkt) {
lua_pushstring(L, kr_strerror(ENOMEM));
lua_error(L);
}
if (!pkt)
lua_error_maybe(L, ENOMEM);
knot_pkt_put_question(pkt, dname, rrclass, rrtype);
knot_wire_set_rd(pkt->wire);
knot_wire_set_ad(pkt->wire);
......@@ -65,7 +57,7 @@ static int wrk_resolve(lua_State *L)
pkt->opt_rr = knot_rrset_copy(worker->engine->resolver.opt_rr, NULL);
if (!pkt->opt_rr) {
knot_pkt_free(pkt);
return kr_error(ENOMEM);
lua_error_maybe(L, ENOMEM);
}
if (options->DNSSEC_WANT) {
knot_edns_set_do(pkt->opt_rr);
......@@ -80,8 +72,7 @@ static int wrk_resolve(lua_State *L)
if (!task) {
knot_rrset_free(pkt->opt_rr, NULL);
knot_pkt_free(pkt);
lua_pushstring(L, "couldn't create a resolution request");
lua_error(L);
lua_error_p(L, "couldn't create a resolution request");
}
/* Add initialisation callback */
......
......@@ -27,6 +27,7 @@
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "daemon/bindings/impl.h"
#include "daemon/engine.h"
#include "daemon/ffimodule.h"
......@@ -62,9 +63,6 @@
#define TCP_BACKLOG_DEFAULT 511
#endif
/** @internal Annotate for static checkers. */
KR_NORETURN int lua_error (lua_State *L);
/* Cleanup engine state every 5 minutes */
const size_t CLEANUP_TIMER = 5*60*1000;
......@@ -133,31 +131,25 @@ static bool update_privileges(int uid, int gid)
static int l_setuser(lua_State *L)
{
int n = lua_gettop(L);
if (n < 1 || !lua_isstring(L, 1)) {
lua_pushliteral(L, "user(user[, group)");
lua_error(L);
}
if (n < 1 || !lua_isstring(L, 1))
lua_error_p(L, "user(user[, group])");
/* Fetch UID/GID based on string identifiers. */
struct passwd *user_pw = getpwnam(lua_tostring(L, 1));
if (!user_pw) {
lua_pushliteral(L, "invalid user name");
lua_error(L);
}
if (!user_pw)
lua_error_p(L, "invalid user name");
int uid = user_pw->pw_uid;
int gid = getgid();
if (n > 1 && lua_isstring(L, 2)) {
struct group *group_pw = getgrnam(lua_tostring(L, 2));
if (!group_pw) {
lua_pushliteral(L, "invalid group name");
lua_error(L);
}
if (!group_pw)
lua_error_p(L, "invalid group name");
gid = group_pw->gr_gid;
}
/* Drop privileges */
bool ret = update_privileges(uid, gid);
if (!ret) {
lua_pushstring(L, strerror(errno));
lua_error(L);
lua_error_maybe(L, errno);
}
lua_pushboolean(L, ret);
return 1;
......@@ -220,17 +212,13 @@ static int l_hostname(lua_State *L)
lua_pushstring(L, engine_get_hostname(engine));
return 1;
}
if ((lua_gettop(L) != 1) || !lua_isstring(L, 1)) {
lua_pushstring(L, "hostname takes at most one parameter: (\"fqdn\")");
lua_error(L);
}
if ((lua_gettop(L) != 1) || !lua_isstring(L, 1))
lua_error_p(L, "hostname takes at most one parameter: (\"fqdn\")");
if (engine_set_hostname(engine, lua_tostring(L, 1)) != 0) {
lua_pushstring(L, "setting hostname failed");
lua_error(L);
}
if (engine_set_hostname(engine, lua_tostring(L, 1)) != 0)
lua_error_p(L, "setting hostname failed");
lua_pushstring(L, engine_get_hostname(engine));
lua_pushstring(L, engine_get_hostname(engine));
return 1;
}
......@@ -288,15 +276,11 @@ static int l_moduledir(lua_State *L)
lua_pushstring(L, engine_get_moduledir(engine));
return 1;
}
if ((lua_gettop(L) != 1) || !lua_isstring(L, 1)) {
lua_pushstring(L, "moduledir takes at most one parameter: (\"directory\")");
lua_error(L);
}
if ((lua_gettop(L) != 1) || !lua_isstring(L, 1))
lua_error_p(L, "moduledir takes at most one parameter: (\"directory\")");
if (engine_set_moduledir(engine, lua_tostring(L, 1)) != 0) {
lua_pushstring(L, "setting moduledir failed");
lua_error(L);
}
if (engine_set_moduledir(engine, lua_tostring(L, 1)) != 0)
lua_error_p(L, "setting moduledir failed");
lua_pushstring(L, engine_get_moduledir(engine));
return 1;
......@@ -314,8 +298,7 @@ static int l_hint_root_file(lua_State *L)
if (!file) {
file = ROOTHINTS;
}
lua_push_printf(L, "error when opening '%s': %s", file, err);
lua_error(L);
lua_error_p(L, "error when opening '%s': %s", file, err);
} else {
lua_pushboolean(L, true);
return 1;
......@@ -454,18 +437,14 @@ static int l_tojson(lua_State *L)
static int l_fromjson(lua_State *L)
{
if (lua_gettop(L) != 1 || !lua_isstring(L, 1)) {
lua_pushliteral(L, "a JSON string is required");
lua_error(L);
}
if (lua_gettop(L) != 1 || !lua_isstring(L, 1))
lua_error_p(L, "a JSON string is required");
const char *json_str = lua_tostring(L, 1);
JsonNode *root_node = json_decode(json_str);
if (!root_node) {
lua_pushliteral(L, "invalid JSON string");
lua_error(L);
}
if (!root_node)
lua_error_p(L, "invalid JSON string");
l_unpack_json(L, root_node);
json_delete(root_node);
......@@ -478,10 +457,8 @@ static int l_fromjson(lua_State *L)
static int l_map(lua_State *L)
{
if (lua_gettop(L) != 1 || !lua_isstring(L, 1)) {
lua_pushliteral(L, "map('string with a lua expression')");
lua_error(L);
}
if (lua_gettop(L) != 1 || !lua_isstring(L, 1))
lua_error_p(L, "map('string with a lua expression')");
struct engine *engine = engine_luaget(L);
const char *cmd = lua_tostring(L, 1);
......@@ -534,10 +511,8 @@ static int l_trampoline(lua_State *L)
struct kr_module *module = lua_touserdata(L, lua_upvalueindex(1));
void* callback = lua_touserdata(L, lua_upvalueindex(2));
struct engine *engine = engine_luaget(L);
if (!module) {
lua_pushstring(L, "module closure missing upvalue");
lua_error(L);
}
if (!module)
lua_error_p(L, "module closure missing upvalue");
/* Now we only have property callback or config,
* if we expand the callables, we might need a callback_type.
......
......@@ -91,7 +91,7 @@ static inline int l_ffi_call(lua_State *L, int argc)
return kr_error(EIO);
}
if (lua_isnumber(L, -1)) { /* Return code */
status = lua_tonumber(L, -1);
status = lua_tointeger(L, -1);
} else if (lua_isthread(L, -1)) { /* Continuations */
status = l_ffi_defer(lua_tothread(L, -1));
}
......
......@@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <lua.h>
#include <uv.h>
#ifdef HAS_SYSTEMD
#include <systemd/sd-daemon.h>
......@@ -337,20 +338,6 @@ static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
#pragma GCC diagnostic pop
}
/** Split away port from the address. */
static const char *set_addr(char *addr, int *port)
{
char *p = strchr(addr, '@');
if (!p) {
p = strchr(addr, '#');
}
if (p) {
*port = strtol(p + 1, NULL, 10);
*p = '\0';
}
return addr;
}
/*
* Server operation.
......@@ -641,20 +628,21 @@ static int bind_fds(struct network *net, fd_array_t *fd_set, bool tls) {
return ret;
}
static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {
static int bind_sockets(struct network *net, addr_array_t *addr_set, bool tls) {
uint32_t flags = tls ? NET_TCP|NET_TLS : NET_UDP|NET_TCP;
int ret = 0;
for (size_t i = 0; i < addr_set->len; ++i) {
int port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;
const char *addr = set_addr(addr_set->at[i], &port);
ret = network_listen(net, addr, (uint16_t)port, flags);
uint16_t port = tls ? KR_DNS_TLS_PORT : KR_DNS_PORT;