]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/network: adapt _listen and _close to repeats
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 11 Mar 2019 17:33:19 +0000 (18:33 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 12 Mar 2019 11:42:03 +0000 (12:42 +0100)
We could get multiple addr#port tuples even before the UDP+TCP split,
but now it would becom quite common, so the API needs to count on that.

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

index 7bd5fc5850f13c0304ed8aa3cfe64f3a74d9ef5b..0419aa9ad7b51866c55ca2ae4c27f500692a148f 100644 (file)
@@ -169,7 +169,8 @@ static int net_close(lua_State *L)
 
        /* Open resolution context cache */
        struct engine *engine = engine_luaget(L);
-       int ret = network_close(&engine->net, lua_tostring(L, 1), lua_tointeger(L, 2));
+       int ret = network_close(&engine->net, lua_tostring(L, 1), lua_tointeger(L, 2),
+                               lua_tointeger(L, 3)/* 0 if not number-like */);
        lua_pushboolean(L, ret == 0);
        return 1;
 }
index bf18291afad47fb78bac5e907b8a14dc4fcf0ac4..8b3c9721dfeae4db389f8217f4924a5218d1d742 100644 (file)
@@ -204,13 +204,14 @@ static int open_endpoint(struct network *net, struct endpoint *ep,
 }
 
 /** @internal Fetch endpoint array and offset of the address/port query. */
-static endpoint_array_t *network_get(struct network *net, const char *addr, uint16_t port, size_t *index)
+static endpoint_array_t *network_get(struct network *net, const char *addr, uint16_t port,
+                                       uint16_t flags, size_t *index)
 {
        endpoint_array_t *ep_array = map_get(&net->endpoints, addr);
        if (ep_array) {
                for (size_t i = ep_array->len; i--;) {
                        struct endpoint *ep = ep_array->at[i];
-                       if (ep->port == port) {
+                       if (ep->port == port && ep->flags == flags) {
                                *index = i;
                                return ep_array;
                        }
@@ -298,7 +299,7 @@ int network_listen(struct network *net, const char *addr, uint16_t port, uint16_
 
        /* Already listening */
        size_t index = 0;
-       if (network_get(net, addr, port, &index)) {
+       if (network_get(net, addr, port, flags, &index)) {
                return kr_ok();
        }
 
@@ -327,17 +328,29 @@ int network_listen(struct network *net, const char *addr, uint16_t port, uint16_
        return ret;
 }
 
-int network_close(struct network *net, const char *addr, uint16_t port)
+int network_close(struct network *net, const char *addr, uint16_t port, uint16_t flags)
 {
-       size_t index = 0;
-       endpoint_array_t *ep_array = network_get(net, addr, port, &index);
+       endpoint_array_t *ep_array = map_get(&net->endpoints, addr);
        if (!ep_array) {
                return kr_error(ENOENT);
        }
 
-       /* Close endpoint in array. */
-       close_endpoint(ep_array->at[index], false);
-       array_del(*ep_array, index);
+       size_t i = 0;
+       bool matched = false;
+       while (i < ep_array->len) {
+               struct endpoint *ep = ep_array->at[i];
+               if (!flags || flags == ep->flags) {
+                       close_endpoint(ep, false);
+                       array_del(*ep_array, i);
+                       matched = true;
+                       /* do not advance i */
+               } else {
+                       ++i;
+               }
+       }
+       if (!matched) {
+               return kr_error(ENOENT);
+       }
 
        /* Collapse key if it has no endpoint. */
        if (ep_array->len == 0) {
index 61b9835c4d0b68c16a0081adae1b771597cabb69..36b88855ee98f53b558b4582a4074e8dbffc8972 100644 (file)
@@ -69,13 +69,17 @@ void network_init(struct network *net, uv_loop_t *loop, int tcp_backlog);
 void network_deinit(struct network *net);
 
 /** Start listenting on addr#port.
- * \param flags see enum endpoint_flag; (NET_UDP | NET_TCP) is allowed. */
+ * \param flags see enum endpoint_flag; (NET_UDP | NET_TCP) is allowed.
+ * \note if we did listen already, nothing is done and kr_ok() is returned. */
 int network_listen(struct network *net, const char *addr, uint16_t port, uint16_t flags);
 
 /** Start listenting on an open file-descriptor. */
 int network_listen_fd(struct network *net, int fd, bool use_tls);
 
-int network_close(struct network *net, const char *addr, uint16_t port);
+/** Stop listening on all addr#port with equal flags; flags == 0 means all of them.
+ * \return kr_error(ENOENT) if nothing matched. */
+int network_close(struct network *net, const char *addr, uint16_t port, uint16_t flags);
+
 int network_set_tls_cert(struct network *net, const char *cert);
 int network_set_tls_key(struct network *net, const char *key);
 void network_new_hostname(struct network *net, struct engine *engine);