From: Vladimír Čunát Date: Tue, 16 Apr 2019 09:57:03 +0000 (+0200) Subject: lua net.close(): multiple fixes X-Git-Tag: v4.0.0~4^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=047ace4dc54f773a8588204d63c57ba69a6a611d;p=thirdparty%2Fknot-resolver.git lua net.close(): multiple fixes - allow omitting port number - sync docs - fix memory leak - fix with kind != NULL --- diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c index fc7f23a34..c6081d22d 100644 --- a/daemon/bindings/net.c +++ b/daemon/bindings/net.c @@ -216,34 +216,23 @@ static int net_listen(lua_State *L) static int net_close(lua_State *L) { /* Check parameters */ - int n = lua_gettop(L); - if (n < 2) - lua_error_p(L, "expected 'close(string addr, number port)'"); - - /* FIXME: support different kind values */ - - /* Open resolution context cache */ - struct network *net = &engine_luaget(L)->net; + const int n = lua_gettop(L); + bool ok = (n == 1 || n == 2) && lua_isstring(L, 1); const char *addr = lua_tostring(L, 1); - const uint16_t port = lua_tointeger(L, 2); - endpoint_flags_t flags_all[] = { - { .sock_type = SOCK_DGRAM, .tls = false }, - { .sock_type = SOCK_STREAM, .tls = false }, - { .sock_type = SOCK_STREAM, .tls = true }, - }; - bool success = false; /*< at least one deletion succeeded */ - int ret = 0; - for (int i = 0; i < sizeof(flags_all) / sizeof(flags_all[0]); ++i) { - ret = network_close(net, addr, port, flags_all[i]); - if (ret == 0) { - success = true; - } else if (ret != kr_error(ENOENT)) { - break; - } - ret = 0; + int port; + if (ok && (n < 2 || lua_isnil(L, 2))) { + port = -1; + } else if (ok) { + ok = lua_isnumber(L, 2); + port = lua_tointeger(L, 2); + ok = ok && port >= 0 && port <= 65535; } - /* true: no fatal error and at least one kr_ok() */ - lua_pushboolean(L, ret == 0 && success); + if (!ok) + lua_error_p(L, "expected 'close(string addr, [number port])'"); + + struct network *net = &engine_luaget(L)->net; + int ret = network_close(net, addr, port); + lua_pushboolean(L, ret == 0); return 1; } diff --git a/daemon/bindings/net.rst b/daemon/bindings/net.rst index 794ea2fc4..7f9b582d0 100644 --- a/daemon/bindings/net.rst +++ b/daemon/bindings/net.rst @@ -122,11 +122,11 @@ configured in the config file. net.listen(net.lo, 5353) net.listen({net.eth0, '127.0.0.1'}, 53853, {tls = true}) -.. function:: net.close(address, [port = 53]) +.. function:: net.close(address, [port]) - :return: boolean + :return: boolean (at least one endpoint closed) - Close opened address/port pair, noop if not listening. + Close all endpoints listening on the specified address, optionally restricted by port as well. .. function:: net.list() diff --git a/daemon/network.c b/daemon/network.c index b7ac00988..c1b576eae 100644 --- a/daemon/network.c +++ b/daemon/network.c @@ -393,8 +393,7 @@ int network_listen(struct network *net, const char *addr, uint16_t port, return create_endpoint(net, addr, port, flags, &sa.ip, -1); } -int network_close(struct network *net, const char *addr, uint16_t port, - endpoint_flags_t flags) +int network_close(struct network *net, const char *addr, int port) { endpoint_array_t *ep_array = map_get(&net->endpoints, addr); if (!ep_array) { @@ -402,10 +401,10 @@ int network_close(struct network *net, const char *addr, uint16_t port, } size_t i = 0; - bool matched = false; + bool matched = false; /*< at least one match */ while (i < ep_array->len) { struct endpoint *ep = &ep_array->at[i]; - if (endpoint_flags_eq(flags, ep->flags)) { + if (port < 0 || ep->port == port) { endpoint_close(net, ep, false); array_del(*ep_array, i); matched = true; @@ -420,6 +419,7 @@ int network_close(struct network *net, const char *addr, uint16_t port, /* Collapse key if it has no endpoint. */ if (ep_array->len == 0) { + array_clear(*ep_array); free(ep_array); map_del(&net->endpoints, addr); } diff --git a/daemon/network.h b/daemon/network.h index faa3670c0..fbf408166 100644 --- a/daemon/network.h +++ b/daemon/network.h @@ -105,10 +105,10 @@ int network_listen(struct network *net, const char *addr, uint16_t port, */ int network_listen_fd(struct network *net, int fd, endpoint_flags_t flags); -/** Stop listening on all addr#port with equal flags. +/** Stop listening on all endpoints with matching addr#port. + * port < 0 serves as a wild-card. * \return kr_error(ENOENT) if nothing matched. */ -int network_close(struct network *net, const char *addr, uint16_t port, - endpoint_flags_t flags); +int network_close(struct network *net, const char *addr, int port); /** Close all endpoints immediately (no waiting for UV loop). */ void network_close_force(struct network *net);