}
}
-static int close_endpoint(struct endpoint *ep, bool force)
-{
- if (ep->handle) {
- close_handle(ep->handle, force);
- }
- free(ep);
- return kr_ok();
-}
-
/** Endpoint visitor (see @file map.h) */
static int close_key(const char *key, void *val, void *ext)
{
endpoint_array_t *ep_array = val;
- for (size_t i = ep_array->len; i--;) {
- close_endpoint(ep_array->at[i], true);
+ for (int i = 0; i < ep_array->len; ++i) {
+ close_handle(ep_array->at[i].handle, true);
}
return 0;
}
}
}
-/** Fetch or create endpoint array and insert endpoint. */
+/** Fetch or create endpoint array and insert endpoint (shallow memcpy). */
static int insert_endpoint(struct network *net, const char *addr, struct endpoint *ep)
{
/* Fetch or insert address into map */
array_init(*ep_array);
}
- if (array_push(*ep_array, ep) < 0) {
+ if (array_reserve(*ep_array, ep_array->len + 1)) {
return kr_error(ENOMEM);
}
+ memcpy(&ep_array->at[ep_array->len++], ep, sizeof(*ep));
return kr_ok();
}
return kr_error(EINVAL);
}
-/** @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,
- endpoint_flags_t flags, size_t *index)
+/** @internal Fetch a pointer to endpoint of given parameters (or NULL).
+ * Beware that there might be multiple matches, though that's not common. */
+static struct endpoint * endpoint_get(struct network *net, const char *addr,
+ uint16_t port, endpoint_flags_t flags)
{
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 && endpoint_flags_eq(ep->flags, flags)) {
- *index = i;
- return ep_array;
- }
+ if (!ep_array) {
+ return NULL;
+ }
+ for (int i = 0; i < ep_array->len; ++i) {
+ struct endpoint *ep = &ep_array->at[i];
+ if (ep->port == port && endpoint_flags_eq(ep->flags, flags)) {
+ return ep;
}
}
return NULL;
const struct sockaddr *sa, int fd)
{
/* Bind interfaces */
- struct endpoint *ep = calloc(1, sizeof(*ep));
- if (!ep) {
- return kr_error(ENOMEM);
- }
- ep->port = port;
- ep->flags = flags;
- int ret = open_endpoint(net, ep, sa, fd);
+ struct endpoint ep = {
+ .handle = NULL,
+ .port = port,
+ .flags = flags,
+ };
+ int ret = open_endpoint(net, &ep, sa, fd);
if (ret == 0) {
- ret = insert_endpoint(net, addr_str, ep);
+ ret = insert_endpoint(net, addr_str, &ep);
}
- if (ret != 0) {
- close_endpoint(ep, false);
+ if (ret != 0 && ep.handle) {
+ close_handle(ep.handle, false);
}
return ret;
}
assert(!EINVAL);
return kr_error(EINVAL);
}
- size_t index = 0;
- if (network_get(net, addr, port, flags, &index)) {
+ if (endpoint_get(net, addr, port, flags)) {
return kr_ok(); /* Already listening */
}
size_t i = 0;
bool matched = false;
while (i < ep_array->len) {
- struct endpoint *ep = ep_array->at[i];
+ struct endpoint *ep = &ep_array->at[i];
if (endpoint_flags_eq(flags, ep->flags)) {
- close_endpoint(ep, false);
+ close_handle(ep->handle, false);
array_del(*ep_array, i);
matched = true;
/* do not advance i */
assert(bpffd != NULL);
for (size_t i = 0; i < endpoints->len; i++) {
- struct endpoint *endpoint = endpoints->at[i];
+ struct endpoint *endpoint = &endpoints->at[i];
uv_os_fd_t sockfd = -1;
if (endpoint->handle != NULL)
uv_fileno(endpoint->handle, &sockfd);
assert(endpoints != NULL);
for (size_t i = 0; i < endpoints->len; i++) {
- struct endpoint *endpoint = endpoints->at[i];
+ struct endpoint *endpoint = &endpoints->at[i];
uv_os_fd_t sockfd = -1;
if (endpoint->handle != NULL)
uv_fileno(endpoint->handle, &sockfd);