|
|
|
@ -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()` */ |
|
|
|
|