Browse Source

MT#55283 split up __get_consecutive_ports

Separate out the two distinct use cases of requesting a specific port,
and requesting (one or more) random ports.

Change-Id: Ifbe7725d8638d49f620c9f4b9445342d180c8770
pull/1918/head
Richard Fuchs 10 months ago
parent
commit
1ad61d90bb
3 changed files with 67 additions and 87 deletions
  1. +61
    -76
      daemon/media_socket.c
  2. +4
    -9
      daemon/redis.c
  3. +2
    -2
      include/media_socket.h

+ 61
- 76
daemon/media_socket.c View File

@ -1193,6 +1193,22 @@ static bool open_port_link_sockets(socket_port_q *out, struct intf_spec *spec, c
return true;
}
struct socket_port_link get_specific_port(unsigned int port,
struct intf_spec *spec, const str *label)
{
ilog(LOG_DEBUG, "A specific port value is requested: '%d'", port);
__auto_type spl = get_one_port_link(port, spec);
if (spl.links.length) {
if (add_socket(&spl.socket, port, spec, label))
return spl;
release_reserved_port(&spec->port_pool, &spl.links, port);
}
/* if engaged already, just select any other (so default logic) */
ilog(LOG_WARN, "This requested port %d has been already engaged, can't take it.", port);
return (struct socket_port_link) {0};
}
/**
* Puts a list of `socket_t` objects into the `out`.
*
@ -1201,7 +1217,7 @@ static bool open_port_link_sockets(socket_port_q *out, struct intf_spec *spec, c
* @param spec, interface specifications
* @param out, a list of sockets for this particular session (not a global list)
*/
bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigned int wanted_start_port,
static bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports,
struct intf_spec *spec, const str *label)
{
unsigned int allocation_attempts = 0, available_ports = 0, additional_port = 0, port = 0;
@ -1215,12 +1231,6 @@ bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigne
goto fail;
}
/* for the wanted port, only one port can be engaged */
if (num_ports > 1 && wanted_start_port > 0) {
ilog(LOG_ERR, "A specific port value is requested, but ports to be engaged > 1");
goto fail;
}
free_ports_q = &pp->free_ports_q;
/* a presence of free lists data is critical for us */
@ -1229,36 +1239,14 @@ bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigne
goto fail;
}
/* specifically requested port */
if (wanted_start_port > 0) {
ilog(LOG_DEBUG, "A specific port value is requested, wanted_start_port: '%d'", wanted_start_port);
__auto_type spl = get_one_port_link(wanted_start_port, spec);
if (!spl.links.length) {
/* 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 */
port = wanted_start_port;
__auto_type splp = g_new(struct socket_port_link, 1);
*splp = spl;
t_queue_push_tail(out, splp);
}
}
/* make sure we have ports to be used */
mutex_lock(&pp->free_list_lock);
available_ports = t_queue_get_length(free_ports_q);
mutex_unlock(&pp->free_list_lock);
if (!available_ports && wanted_start_port == 0) {
ilog(LOG_ERR, "Empty ports queue, no more ports left to use");
goto fail;
}
/* if there is only 1 port left, and it's not rtcp-mux, then
* it makes no sence to conitnue - ran out ports */
if (num_ports > 1 && wanted_start_port == 0 && available_ports == 1) {
if (available_ports < num_ports) {
ilog(LOG_ERR, "Ran out of ports, can't engage an additional port (for RTCP)");
goto fail;
}
@ -1274,60 +1262,61 @@ bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigne
while (1)
{
new_cycle:
ilog(LOG_DEBUG, "Trying to find RTP/RTCP ports (allocation attempt = '%d')",
allocation_attempts);
if (++allocation_attempts > available_ports) {
ilog(LOG_ERR, "Failure while trying to bind a port to the socket");
goto fail;
}
if (!wanted_start_port) {
/* For cases with no rtcp-mux: RTP must be an even port,
* and RTCP port is always the next one to that.
*/
/* For cases with no rtcp-mux: RTP must be an even port,
* and RTCP port is always the next one to that.
*/
/* Now only get first possible port for RTP.
* Then additionally make sure that the RTCP port can also be engaged, if needed.
*/
__auto_type spl = get_any_port_link(spec);
if (!spl.links.length) {
ilog(LOG_ERR, "Failure while trying to get a port from the list");
goto fail;
}
/* Now only get first possible port for RTP.
* Then additionally make sure that the RTCP port can also be engaged, if needed.
*/
__auto_type spl = get_any_port_link(spec);
if (!spl.links.length) {
ilog(LOG_ERR, "Failure while trying to get a port from the list");
goto fail;
}
port = GPOINTER_TO_UINT(spl.links.head->data); /* RTP */
port = GPOINTER_TO_UINT(spl.links.head->data); /* RTP */
/* ports for RTP must be even, if there is an additional port for RTCP */
if (num_ports > 1 && (port & 1)) {
/* return port for RTP back and try again */
release_reserved_port(pp, &spl.links, port);
continue;
}
__auto_type splp = g_new(struct socket_port_link, 1);
*splp = spl;
t_queue_push_tail(out, splp);
/* ports for RTP must be even, if there is an additional port for RTCP */
if (num_ports > 1 && (port & 1)) {
/* return port for RTP back and try again */
release_reserved_port(pp, &spl.links, port);
continue;
}
/* find additional ports, usually it's only RTCP */
additional_port = port;
for (int i = 1; i < num_ports; i++)
{
additional_port++;
__auto_type splp = g_new(struct socket_port_link, 1);
*splp = spl;
t_queue_push_tail(out, splp);
spl = get_one_port_link(additional_port, spec);
/* find additional ports, usually it's only RTCP */
additional_port = port;
for (int i = 1; i < num_ports; i++)
{
additional_port++;
if (!spl.links.length) {
/* return previously reserved ports and try again */
release_reserved_ports(out);
/* return additional port back */
release_reserved_port(pp, &spl.links, additional_port);
goto new_cycle;
}
spl = get_one_port_link(additional_port, spec);
/* engage this port right away */
/* track for which additional ports, we have to open sockets */
splp = g_new(struct socket_port_link, 1);
*splp = spl;
t_queue_push_tail(out, splp);
if (!spl.links.length) {
/* return previously reserved ports and try again */
release_reserved_ports(out);
/* return additional port back */
release_reserved_port(pp, &spl.links, additional_port);
goto new_cycle;
}
/* engage this port right away */
/* track for which additional ports, we have to open sockets */
splp = g_new(struct socket_port_link, 1);
*splp = spl;
t_queue_push_tail(out, splp);
}
ilog(LOG_DEBUG, "Trying to bind the socket for RTP/RTCP ports (allocation attempt = '%d')",
@ -1337,10 +1326,6 @@ new_cycle:
if (open_port_link_sockets(out, spec, label))
break; // success
/* do not re-try for specifically wanted ports */
if (wanted_start_port > 0)
goto fail;
ilog(LOG_DEBUG, "Something already keeps this port, trying to take another port(s)");
}
@ -1386,7 +1371,7 @@ bool get_consecutive_ports(socket_intf_list_q *out, unsigned int num_ports, unsi
il = g_slice_alloc0(sizeof(*il));
il->local_intf = loc;
t_queue_push_tail(out, il);
if (G_LIKELY(__get_consecutive_ports(&il->list, num_ports, 0, loc->spec, label))) {
if (G_LIKELY(__get_consecutive_ports(&il->list, num_ports, loc->spec, label))) {
// success - found available ports on local interfaces, so far
continue;
} else {


+ 4
- 9
daemon/redis.c View File

@ -1379,7 +1379,6 @@ static int redis_sfds(call_t *c, struct redis_list *sfds) {
sockfamily_t *fam;
struct logical_intf *lif;
struct local_intf *loc;
socket_port_q q = TYPED_GQUEUE_INIT;
unsigned int loc_uid;
stream_fd *sfd;
int port, fd;
@ -1418,15 +1417,11 @@ static int redis_sfds(call_t *c, struct redis_list *sfds) {
if (fd != -1) {
err = "failed to open ports";
if (!__get_consecutive_ports(&q, 1, port, loc->spec, &c->callid))
__auto_type spl = get_specific_port(port, loc->spec, &c->callid);
if (!spl.links.length)
goto err;
err = "no port returned";
struct socket_port_link *spl = t_queue_pop_head(&q);
if (!spl)
goto err;
set_tos(&spl->socket, c->tos);
sfd = stream_fd_new(spl, c, loc);
g_free(spl);
set_tos(&spl.socket, c->tos);
sfd = stream_fd_new(&spl, c, loc);
}
else {
struct socket_port_link spl = {0};


+ 2
- 2
include/media_socket.h View File

@ -296,8 +296,8 @@ struct local_intf *get_any_interface_address(const struct logical_intf *lif, soc
void interfaces_exclude_port(endpoint_t *);
int is_local_endpoint(const struct intf_address *addr, unsigned int port);
bool __get_consecutive_ports(socket_port_q *out, unsigned int num_ports, unsigned int wanted_start_port,
struct intf_spec *spec, const str *);
struct socket_port_link get_specific_port(unsigned int port,
struct intf_spec *spec, const str *label);
bool get_consecutive_ports(socket_intf_list_q *out, unsigned int num_ports, unsigned int num_intfs,
struct call_media *media);
stream_fd *stream_fd_new(struct socket_port_link *, call_t *call, struct local_intf *lif);


Loading…
Cancel
Save