Browse Source

MT#63317 rework endpoint_map hunting

Store the current (last) used endpoint map in the media object. This can
then be directly used when port latching is requested.

Remove and close sockets from endpoint map if fewer ports are needed.

Change-Id: I58aab82f82ecc3b0a7fc7a781394c8d77e715ecf
pull/2018/head
Richard Fuchs 2 months ago
parent
commit
0ebc75d229
2 changed files with 49 additions and 53 deletions
  1. +47
    -52
      daemon/call.c
  2. +2
    -1
      include/call.h

+ 47
- 52
daemon/call.c View File

@ -767,16 +767,41 @@ static int __media_want_interfaces(struct call_media *media) {
want_interfaces = 1;
return want_interfaces;
}
static void __endpoint_map_truncate(struct endpoint_map *em, unsigned int num_intfs) {
static bool __endpoint_map_truncate(struct endpoint_map *em, unsigned int num_intfs, unsigned int num_ports) {
if (num_ports > em->num_ports)
return false;
while (em->intf_sfds.length > num_intfs) {
struct sfd_intf_list *il = t_queue_pop_tail(&em->intf_sfds);
free_sfd_intf_list(il);
free_release_sfd_intf_list(il);
}
if (em->num_ports == num_ports)
return true;
for (__auto_type l = em->intf_sfds.head; l; l = l->next) {
__auto_type il = l->data;
while (il->list.length > num_ports) {
__auto_type p = t_queue_pop_tail(&il->list);
stream_fd_release(p);
}
}
return true;
}
// XXX turn this into a hash lookup
static struct endpoint_map *__hunt_endpoint_map(struct call_media *media, unsigned int num_ports,
const struct endpoint *ep, const sdp_ng_flags *flags, bool always_reuse,
unsigned int want_interfaces)
unsigned int want_interfaces, bool port_latching)
{
if (port_latching) {
struct endpoint_map *em = media->endpoint_map;
if (em && em->num_ports >= num_ports && em->intf_sfds.length == want_interfaces)
return em;
}
for (__auto_type l = media->endpoint_maps.tail; l; l = l->prev) {
struct endpoint_map *em = l->data;
if (em->logical_intf != media->logical_intf)
@ -800,7 +825,6 @@ static struct endpoint_map *__hunt_endpoint_map(struct call_media *media, unsign
em->endpoint = *ep;
em->wildcard = 0;
}
__endpoint_map_truncate(em, want_interfaces);
return em;
}
if (!ep) /* creating wildcard map */
@ -817,41 +841,13 @@ static struct endpoint_map *__hunt_endpoint_map(struct call_media *media, unsign
if (em->num_ports >= num_ports && em->intf_sfds.length >= want_interfaces) {
if (is_addr_unspecified(&em->endpoint.address))
em->endpoint.address = ep->address;
__endpoint_map_truncate(em, want_interfaces);
return em;
}
/* endpoint matches, but not enough ports. flush existing ports
* and allocate a new set. */
__C_DBG("endpoint matches, doesn't have enough ports");
t_queue_clear_full(&em->intf_sfds, free_sfd_intf_list);
return em;
}
return NULL;
}
static struct endpoint_map *__latch_endpoint_map(struct call_media *media)
{
// simply look for the endpoint map matching the current port
if (!media->streams.length)
return NULL;
struct packet_stream *first_ps = media->streams.head->data;
if (!first_ps->sfds.length)
return NULL;
stream_fd *matcher = first_ps->sfds.head->data;
for (__auto_type l = media->endpoint_maps.tail; l; l = l->prev) {
struct endpoint_map *em = l->data;
if (!em->intf_sfds.length)
continue;
struct sfd_intf_list *em_il = em->intf_sfds.head->data;
if (!em_il->list.length)
continue;
stream_fd *first = em_il->list.head->data;
if (first == matcher)
return em;
}
return NULL;
}
static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigned int num_ports,
const struct endpoint *ep, const sdp_ng_flags *flags, bool always_reuse)
{
@ -859,6 +855,9 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne
socket_intf_list_q intf_sockets = TYPED_GQUEUE_INIT;
unsigned int want_interfaces = __media_want_interfaces(media);
if (num_ports > 16)
return NULL;
bool port_latching = false;
if (flags && flags->port_latching)
port_latching = true;
@ -867,36 +866,32 @@ static struct endpoint_map *__get_endpoint_map(struct call_media *media, unsigne
else if (!MEDIA_ISSET(media, RECV) && (!flags || !flags->no_port_latching))
port_latching = true;
struct endpoint_map *em = NULL;
if (port_latching)
em = __latch_endpoint_map(media);
if (!em)
em = __hunt_endpoint_map(media, num_ports, ep, flags, always_reuse, want_interfaces);
struct endpoint_map *em = __hunt_endpoint_map(media, num_ports, ep, flags, always_reuse,
want_interfaces, port_latching);
if (em) {
if (em->intf_sfds.length)
if (__endpoint_map_truncate(em, want_interfaces, num_ports)) {
media->endpoint_map = em;
return em;
// fall through
}
else {
__C_DBG("allocating new %sendpoint map", ep ? "" : "wildcard ");
em = uid_alloc(&media->call->endpoint_maps);
if (ep)
em->endpoint = *ep;
else
em->wildcard = 1;
em->logical_intf = media->logical_intf;
t_queue_init(&em->intf_sfds);
t_queue_push_tail(&media->endpoint_maps, em);
}
}
__C_DBG("allocating new %sendpoint map", ep ? "" : "wildcard ");
em = uid_alloc(&media->call->endpoint_maps);
if (ep)
em->endpoint = *ep;
else
em->wildcard = 1;
em->logical_intf = media->logical_intf;
t_queue_init(&em->intf_sfds);
t_queue_push_tail(&media->endpoint_maps, em);
em->num_ports = num_ports;
if (num_ports > 16)
return NULL;
if (!get_consecutive_ports(&intf_sockets, num_ports, want_interfaces, media))
return NULL;
media->endpoint_map = em;
__C_DBG("allocating stream_fds for %u ports", num_ports);
MEDIA_CLEAR(media, PUBLIC);


+ 2
- 1
include/call.h View File

@ -390,7 +390,7 @@ struct stream_params {
struct endpoint_map {
unsigned int unique_id;
struct endpoint endpoint;
unsigned int num_ports;
unsigned int num_ports; // per interface
struct logical_intf *logical_intf;
sfd_intf_list_q intf_sfds; /* list of struct sfd_intf_list - contains stream_fd list */
unsigned int wildcard:1;
@ -520,6 +520,7 @@ struct call_media {
unsigned int media_rec_slot;
packet_stream_q streams; /* normally RTP + RTCP */
struct endpoint_map *endpoint_map;
endpoint_map_q endpoint_maps;
struct ssrc_hash ssrc_hash_in;
struct ssrc_hash ssrc_hash_out;


Loading…
Cancel
Save