]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lua net.close(): multiple fixes
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 16 Apr 2019 09:57:03 +0000 (11:57 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 18 Apr 2019 07:54:32 +0000 (09:54 +0200)
- allow omitting port number
- sync docs
- fix memory leak
- fix with kind != NULL

daemon/bindings/net.c
daemon/bindings/net.rst
daemon/network.c
daemon/network.h

index fc7f23a34630ec89f09a3bef47b27fb99a30ec20..c6081d22d1dc802f3670224a8b8d6b23ec5f6044 100644 (file)
@@ -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;
 }
 
index 794ea2fc46c73d6287df90fa52786f2c8403861b..7f9b582d0b6d385ff12f00e4af6b8a9c261be88d 100644 (file)
@@ -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()
 
index b7ac00988a0f8c323677718a5c1cf8faddd24fb0..c1b576eaef5f70554c6a7141287fe533598b9d92 100644 (file)
@@ -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);
        }
index faa3670c0183bb85cedf918f45aeaa05a0afeb32..fbf408166e9cd8d99687ff6fa163dbc2fa30ae5e 100644 (file)
@@ -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);