From 4658b90f0b3e9b74311434e2ad443d17fd6b50b3 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 17 Feb 2022 14:24:57 -0500 Subject: [PATCH] TT#14008 don't open extra interface ports when ICE is not in use There's no need to open ports on non-primary interfaces if ICE is not in use as these ports will not be used or seen by anyone. This mostly obsoletes the `save-interface-ports` config option, with the exception of ICE advertised by the offerer. We currently have no option to reject ICE from the offerer during the offer phase, so ports would always be opened on that side. Relevant to #1164 and 001abe5 Change-Id: I43df70bc0ec49b81f63aec97c776e48617b2acfd --- daemon/call.c | 12 +++++-- daemon/media_socket.c | 76 +++++++++++++----------------------------- include/media_socket.h | 2 +- 3 files changed, 34 insertions(+), 56 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index de0d95e61..dada14e42 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -894,6 +894,10 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne struct endpoint_map *em; struct stream_fd *sfd; GQueue intf_sockets = G_QUEUE_INIT; + unsigned int want_interfaces = media->logical_intf->list.length; + + if (rtpe_config.save_interface_ports || !MEDIA_ISSET(media, ICE)) + want_interfaces = 1; for (GList *l = media->endpoint_maps.tail; l; l = l->prev) { em = l->data; @@ -910,7 +914,9 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne } } - if ((em->wildcard || always_reuse) && em->num_ports >= num_ports) { + if ((em->wildcard || always_reuse) && em->num_ports >= num_ports + && em->intf_sfds.length >= want_interfaces) + { __C_DBG("found a wildcard endpoint map%s", ep ? " and filling it in" : ""); if (ep) { em->endpoint = *ep; @@ -933,7 +939,7 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne else if (memcmp(&em->endpoint, ep, sizeof(*ep))) continue; - if (em->num_ports >= num_ports) { + if (em->num_ports >= num_ports && em->intf_sfds.length >= want_interfaces) { if (is_addr_unspecified(&em->endpoint.address)) em->endpoint.address = ep->address; return em; @@ -960,7 +966,7 @@ make_new: alloc: if (num_ports > 16) return NULL; - if (get_consecutive_ports(&intf_sockets, num_ports, media)) + if (get_consecutive_ports(&intf_sockets, num_ports, want_interfaces, media)) return NULL; __C_DBG("allocating stream_fds for %u ports", num_ports); diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 0e0dc985c..7152a9080 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -928,13 +928,12 @@ fail: } /* puts a list of "struct intf_list" into "out", containing socket_t list */ -int get_consecutive_ports(GQueue *out, unsigned int num_ports, struct call_media *media) +int get_consecutive_ports(GQueue *out, unsigned int num_ports, unsigned int num_intfs, struct call_media *media) { GList *l; struct intf_list *il; const struct local_intf *loc; const struct logical_intf *log = media->logical_intf; - const sockfamily_t *desired_family = media->desired_family; const str *label = &media->call->callid; /* @@ -948,64 +947,37 @@ int get_consecutive_ports(GQueue *out, unsigned int num_ports, struct call_media ilog(LOG_DEBUG, ""); */ - if (!rtpe_config.save_interface_ports) { - for (l = log->list.head; l; l = l->next) { - loc = l->data; - - il = g_slice_alloc0(sizeof(*il)); - il->local_intf = loc; - g_queue_push_tail(out, il); - if (G_LIKELY(!__get_consecutive_ports(&il->list, num_ports, 0, loc->spec, label))) { - // success - found available ports on local interfaces, so far - continue; - } else { - // fail - did not found available ports on at least one local interface - goto error_ports; - } - } - - return 0; + for (l = log->list.head; l; l = l->next) { + if (out->length >= num_intfs) + break; -error_ports: - ilog(LOG_ERR, "Failed to get %d consecutive ports on all locals of logical '"STR_FORMAT"'", - num_ports, STR_FMT(&log->name)); + loc = l->data; - // free all ports alloc'ed so far for the previous local interfaces - while ((il = g_queue_pop_head(out))) { - free_socket_intf_list(il); + il = g_slice_alloc0(sizeof(*il)); + il->local_intf = loc; + g_queue_push_tail(out, il); + if (G_LIKELY(!__get_consecutive_ports(&il->list, num_ports, 0, loc->spec, label))) { + // success - found available ports on local interfaces, so far + continue; + } else { + // fail - did not found available ports on at least one local interface + goto error_ports; } + } - return -1; - - } else { - for (l = log->list.head; l; l = l->next) { - loc = l->data; + return 0; - // check desired family of local interface - if (desired_family != loc->spec->local_address.addr.family) { - ilog(LOG_DEBUG, "Did not find yet one local interface for family %s; continue...", desired_family->rfc_name); - continue; - } +error_ports: + ilog(LOG_ERR, "Failed to get %d consecutive ports on all locals of logical '"STR_FORMAT"'", + num_ports, STR_FMT(&log->name)); - ilog(LOG_DEBUG, "Found one local interface for family %s", desired_family->rfc_name); - - il = g_slice_alloc0(sizeof(*il)); - il->local_intf = loc; - if (G_LIKELY(!__get_consecutive_ports(&il->list, num_ports, 0, loc->spec, label))) { - // success - found available ports on one local interface - g_queue_push_tail(out, il); - return 0; - } else { - // fail - no available ports on one local interface... continue - free_socket_intf_list(il); - } - } + // free all ports alloc'ed so far for the previous local interfaces + while ((il = g_queue_pop_head(out))) { + free_socket_intf_list(il); + } - ilog(LOG_ERR, "Failed to get %d consecutive ports on one local of logical '"STR_FORMAT"'", - num_ports, STR_FMT(&log->name)); + return -1; - return -1; - } } void free_socket_intf_list(struct intf_list *il) { socket_t *sock; diff --git a/include/media_socket.h b/include/media_socket.h index 43f751bdf..f3f6687ad 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -173,7 +173,7 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port); int __get_consecutive_ports(GQueue *out, unsigned int num_ports, unsigned int wanted_start_port, struct intf_spec *spec, const str *); -int get_consecutive_ports(GQueue *out, unsigned int num_ports, struct call_media *media); +int get_consecutive_ports(GQueue *out, unsigned int num_ports, unsigned int num_intfs, struct call_media *media); struct stream_fd *stream_fd_new(socket_t *fd, struct call *call, const struct local_intf *lif); struct stream_fd *stream_fd_lookup(const endpoint_t *); void stream_fd_release(struct stream_fd *);