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;
}
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()
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) {
}
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;
/* Collapse key if it has no endpoint. */
if (ep_array->len == 0) {
+ array_clear(*ep_array);
free(ep_array);
map_del(&net->endpoints, addr);
}
*/
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);