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; want_interfaces = 1;
return want_interfaces; 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) { while (em->intf_sfds.length > num_intfs) {
struct sfd_intf_list *il = t_queue_pop_tail(&em->intf_sfds); 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, 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, 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) { for (__auto_type l = media->endpoint_maps.tail; l; l = l->prev) {
struct endpoint_map *em = l->data; struct endpoint_map *em = l->data;
if (em->logical_intf != media->logical_intf) 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->endpoint = *ep;
em->wildcard = 0; em->wildcard = 0;
} }
__endpoint_map_truncate(em, want_interfaces);
return em; return em;
} }
if (!ep) /* creating wildcard map */ 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 (em->num_ports >= num_ports && em->intf_sfds.length >= want_interfaces) {
if (is_addr_unspecified(&em->endpoint.address)) if (is_addr_unspecified(&em->endpoint.address))
em->endpoint.address = ep->address; em->endpoint.address = ep->address;
__endpoint_map_truncate(em, want_interfaces);
return em; 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; 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, 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) 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; socket_intf_list_q intf_sockets = TYPED_GQUEUE_INIT;
unsigned int want_interfaces = __media_want_interfaces(media); unsigned int want_interfaces = __media_want_interfaces(media);
if (num_ports > 16)
return NULL;
bool port_latching = false; bool port_latching = false;
if (flags && flags->port_latching) if (flags && flags->port_latching)
port_latching = true; 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)) else if (!MEDIA_ISSET(media, RECV) && (!flags || !flags->no_port_latching))
port_latching = true; 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) {
if (em->intf_sfds.length)
if (__endpoint_map_truncate(em, want_interfaces, num_ports)) {
media->endpoint_map = em;
return 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; em->num_ports = num_ports;
if (num_ports > 16)
return NULL;
if (!get_consecutive_ports(&intf_sockets, num_ports, want_interfaces, media)) if (!get_consecutive_ports(&intf_sockets, num_ports, want_interfaces, media))
return NULL; return NULL;
media->endpoint_map = em;
__C_DBG("allocating stream_fds for %u ports", num_ports); __C_DBG("allocating stream_fds for %u ports", num_ports);
MEDIA_CLEAR(media, PUBLIC); MEDIA_CLEAR(media, PUBLIC);


+ 2
- 1
include/call.h View File

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


Loading…
Cancel
Save