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 *);