/* 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;
}
}
/** @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;
}
/* Already listening */
size_t index = 0;
- if (network_get(net, addr, port, &index)) {
+ if (network_get(net, addr, port, flags, &index)) {
return kr_ok();
}
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) {
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);