diff --git a/daemon/media_socket.c b/daemon/media_socket.c index c113fa5d3..2828204d6 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -682,11 +682,18 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port) { /** * This function just (globally) reserves a port number, it doesn't provide any binding/unbinding. + * Returns list link if successful, or NULL if failed. */ -static void reserve_port(struct port_pool *pp, ports_list *link) { - t_queue_unlink(&pp->free_ports_q, link); - unsigned int port = GPOINTER_TO_UINT(link->data); +static ports_list *reserve_port(struct port_pool *pp, unsigned int port) { + if (port < pp->min || port > pp->max) + return NULL; + LOCK(&pp->free_list_lock); + __auto_type list = free_ports_link(pp, port); + if (!list) + return NULL; + t_queue_unlink(&pp->free_ports_q, list); free_ports_link(pp, port) = NULL; + return list; } /** * This function just releases reserved port number, it doesn't provide any binding/unbinding. @@ -840,11 +847,9 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool unsigned int port = GPOINTER_TO_UINT(l->data); if (port > 65535) continue; - ports_list *ll = spec->port_pool.free_ports[port]; - if (ll) { - reserve_port(&spec->port_pool, ll); + __auto_type ll = reserve_port(&spec->port_pool, port); + if (ll) t_list_free(ll); - } } t_hash_table_insert(__intf_spec_addr_type_hash, &spec->local_address, spec); @@ -928,13 +933,9 @@ void interfaces_exclude_port(endpoint_t *e) { if (e->port < pp->min || e->port > pp->max) continue; - mutex_lock(&pp->free_list_lock); - __auto_type ll = free_ports_link(pp, e->port); - if (ll) { - reserve_port(pp, ll); + __auto_type ll = reserve_port(pp, e->port); + if (ll) t_list_free(ll); - } - mutex_unlock(&pp->free_list_lock); } } @@ -1103,18 +1104,15 @@ int __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigned /* specifically requested port */ if (wanted_start_port > 0) { ilog(LOG_DEBUG, "A specific port value is requested, wanted_start_port: '%d'", wanted_start_port); - mutex_lock(&pp->free_list_lock); - port_link = free_ports_link(pp, wanted_start_port); + port_link = reserve_port(pp, wanted_start_port); if (!port_link) { /* if engaged already, just select any other (so default logic) */ ilog(LOG_WARN, "This requested port has been already engaged, can't take it."); wanted_start_port = 0; /* take what is proposed by FIFO instead */ } else { /* we got the port, and we are sure it wasn't engaged */ - reserve_port(pp, port_link); port = wanted_start_port; } - mutex_unlock(&pp->free_list_lock); } /* make sure we have ports to be used */ @@ -1184,9 +1182,7 @@ new_cycle: { additional_port++; - mutex_lock(&pp->free_list_lock); - __auto_type add_link = additional_port <= pp->max ? free_ports_link(pp, additional_port) : NULL; - mutex_unlock(&pp->free_list_lock); + __auto_type add_link = reserve_port(pp, additional_port); if (!add_link) { /* return port for RTP back and try again */ @@ -1202,9 +1198,6 @@ new_cycle: } /* engage this port right away */ - reserve_port(pp, add_link); - mutex_unlock(&pp->free_list_lock); - /* track for which additional ports, we have to open sockets */ t_queue_push_tail_link(&ports_to_engage, add_link); }