From: Vladimír Čunát Date: Mon, 11 Mar 2019 17:33:19 +0000 (+0100) Subject: daemon/network: adapt _listen and _close to repeats X-Git-Tag: v4.0.0~21^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2667c5f0cd7ddc8b6880db28ca6dacccbb227167;p=thirdparty%2Fknot-resolver.git daemon/network: adapt _listen and _close to repeats 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. --- diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c index 7bd5fc585..0419aa9ad 100644 --- a/daemon/bindings/net.c +++ b/daemon/bindings/net.c @@ -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; } diff --git a/daemon/network.c b/daemon/network.c index bf18291af..8b3c9721d 100644 --- a/daemon/network.c +++ b/daemon/network.c @@ -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) { diff --git a/daemon/network.h b/daemon/network.h index 61b9835c4..36b88855e 100644 --- a/daemon/network.h +++ b/daemon/network.h @@ -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);