From 21562866cec4c6be86cdb8d4fc7c688ee43c379f Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Tue, 28 Mar 2023 14:42:30 +0200 Subject: [PATCH] MT#56750 ports allocation: add helpers Add helpers for port reserving and freeing: - reserve_port() - release_reserved_port() Change-Id: I5b58c1f7f1081190d189dd6b97cf6e8a162e329e --- daemon/media_socket.c | 51 ++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index a1268a36c..54998f6e0 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -658,6 +658,25 @@ int is_local_endpoint(const struct intf_address *addr, unsigned int port) { return 0; } +/** + * This functions just (globally) reserves a port number, it doesn't do binding/unbinding. + */ +static void reserve_port(GQueue * free_ports_q, GHashTable * free_ports_ht, + GList * value_looked_up, unsigned int port) { + + g_queue_delete_link(free_ports_q, value_looked_up); + g_hash_table_remove(free_ports_ht, GUINT_TO_POINTER(port)); +} +/** + * This functions just releases reserved port number, it doesn't do binding/unbinding. + */ +static void release_reserved_port(GQueue * free_ports_q, GHashTable * free_ports_ht, + unsigned int port) { + + g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(port)); + GList * l = free_ports_q->tail; + g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(port), l); +} /* Append a list of free ports within min-max range */ static void __append_free_ports_to_int(struct intf_spec *spec) { unsigned int ports_amount, count; @@ -862,7 +881,6 @@ struct local_intf *get_any_interface_address(const struct logical_intf *lif, soc return get_interface_address(lif, get_socket_family_enum(SF_IP6)); } - /** * Opens a socket for a given port value and edits the iptables accordingly. * It doesn't provide a port selection logic. @@ -915,9 +933,7 @@ static void release_port_now(socket_t *r, struct intf_spec *spec) { /* first return the engaged port back */ mutex_lock(&pp->free_list_lock); - g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(port)); - GList * l = free_ports_q->tail; - g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(port), l); + release_reserved_port(free_ports_q, free_ports_ht, port); mutex_unlock(&pp->free_list_lock); } else { ilog(LOG_WARNING, "Unable to close the socket for port '%u'", port); @@ -982,8 +998,7 @@ int __get_consecutive_ports(GQueue *out, unsigned int num_ports, unsigned int wa wanted_start_port = 0; /* take what is proposed by FIFO instead */ } else { /* we got the port, and we are sure it wasn't engaged */ - g_queue_delete_link(free_ports_q, l); - g_hash_table_remove(free_ports_ht, GUINT_TO_POINTER(wanted_start_port)); + reserve_port(free_ports_q, free_ports_ht, l, wanted_start_port); port = wanted_start_port; } mutex_unlock(&pp->free_list_lock); @@ -1043,11 +1058,9 @@ new_cycle: /* ports for RTP must be even, if there is an additional port for RTCP */ if (num_ports > 1 && (port & 1)) { - /* try again */ + /* return port for RTP back and try again */ mutex_lock(&pp->free_list_lock); - g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(port)); /* return port for RTP back */ - GList * l = free_ports_q->tail; - g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(port), l); + release_reserved_port(free_ports_q, free_ports_ht, port); mutex_unlock(&pp->free_list_lock); goto new_cycle; } @@ -1062,27 +1075,23 @@ new_cycle: GList *l = g_hash_table_lookup(free_ports_ht, GUINT_TO_POINTER(additional_port)); if (!l) { - /* try again */ - g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(port)); /* return port for RTP back */ - GList * l = free_ports_q->tail; - g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(port), l); + /* return port for RTP back and try again */ + release_reserved_port(free_ports_q, free_ports_ht, port); mutex_unlock(&pp->free_list_lock); /* check if we managed to enagage anything in previous for-cycles */ while ((additional_port = GPOINTER_TO_UINT(g_queue_pop_head(&ports_to_engage)))) { mutex_lock(&pp->free_list_lock); - g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(additional_port)); - GList * l = free_ports_q->tail; - g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(additional_port), l); + /* return additional ports back */ + release_reserved_port(free_ports_q, free_ports_ht, additional_port); mutex_unlock(&pp->free_list_lock); } goto new_cycle; } else { /* engage this port right away */ - g_queue_delete_link(free_ports_q, l); - g_hash_table_remove(free_ports_ht, GUINT_TO_POINTER(additional_port)); + reserve_port(free_ports_q, free_ports_ht, l, additional_port); mutex_unlock(&pp->free_list_lock); /* track for which additional ports, we have to open sockets */ @@ -1110,9 +1119,7 @@ new_cycle: while ((port = GPOINTER_TO_UINT(g_queue_pop_head(&ports_to_engage)))) { mutex_lock(&pp->free_list_lock); - g_queue_push_tail(free_ports_q, GUINT_TO_POINTER(port)); - GList * l = free_ports_q->tail; - g_hash_table_replace(free_ports_ht, GUINT_TO_POINTER(port), l); + release_reserved_port(free_ports_q, free_ports_ht, port); mutex_unlock(&pp->free_list_lock); } /* ports already bound to a socket, will be freed by `free_port()` */