Browse Source

MT#55283 use typed GQueue for ICE lists

Change-Id: Ieb4168cc7959347940831b5b83dce82ba1fe1965
pull/1776/head
Richard Fuchs 2 years ago
parent
commit
cbaa0c106a
6 changed files with 69 additions and 69 deletions
  1. +51
    -56
      daemon/ice.c
  2. +1
    -1
      daemon/janus.c
  3. +4
    -5
      daemon/sdp.c
  4. +1
    -1
      include/call.h
  5. +6
    -6
      include/ice.h
  6. +6
    -0
      include/types.h

+ 51
- 56
daemon/ice.c View File

@ -59,7 +59,7 @@ static struct ice_candidate_pair *__pair_lookup(struct ice_agent *, struct ice_c
const struct local_intf *ifa);
static void __recalc_pair_prios(struct ice_agent *ag);
static void __role_change(struct ice_agent *ag, int new_controlling);
static void __get_complete_components(GQueue *out, struct ice_agent *ag, GTree *t, unsigned int);
static void __get_complete_components(candidate_pair_q *out, struct ice_agent *ag, GTree *t, unsigned int);
static void __agent_schedule(struct ice_agent *ag, unsigned long);
static void __agent_schedule_abs(struct ice_agent *ag, const struct timeval *tv);
static void __agent_deschedule(struct ice_agent *ag);
@ -303,8 +303,8 @@ static void __new_stun_transaction(struct ice_candidate_pair *pair) {
/* agent must be locked */
static void __all_pairs_list(struct ice_agent *ag) {
g_queue_clear(&ag->all_pairs_list);
g_tree_get_values(&ag->all_pairs_list, ag->all_pairs);
t_queue_clear(&ag->all_pairs_list);
g_tree_get_values(&ag->all_pairs_list.q, ag->all_pairs);
}
static void __tree_coll_callback(void *oo, void *nn) {
@ -334,7 +334,7 @@ static struct ice_candidate_pair *__pair_candidate(struct stream_fd *sfd, struct
__do_ice_pair_priority(pair);
__new_stun_transaction(pair);
g_queue_push_tail(&ag->candidate_pairs, pair);
t_queue_push_tail(&ag->candidate_pairs, pair);
g_hash_table_insert(ag->pair_hash, pair, pair);
g_tree_insert_coll(ag->all_pairs, pair, pair, __tree_coll_callback);
@ -490,14 +490,13 @@ void ice_restart(struct ice_agent *ag) {
/* called with the call lock held in W, hence agent doesn't need to be locked */
void ice_update(struct ice_agent *ag, struct stream_params *sp, bool allow_reset) {
GList *l;
struct ice_candidate *cand, *dup;
struct call_media *media;
struct call *call;
int recalc = 0;
unsigned int comps;
struct packet_stream *components[MAX_COMPONENTS], *ps;
GQueue *candidates;
candidate_q *candidates;
struct stream_fd *sfd;
if (!ag)
@ -533,13 +532,13 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp, bool allow_reset
/* get our component streams */
ZERO(components);
comps = 0;
for (l = media->streams.head; l; l = l->next)
for (GList *l = media->streams.head; l; l = l->next)
components[comps++] = l->data;
if (comps == 2 && (MEDIA_ISSET(media, RTCP_MUX) || !proto_is_rtp(media->protocol)))
components[1] = NULL;
comps = 0;
for (l = candidates->head; l; l = l->next) {
for (__auto_type l = candidates->head; l; l = l->next) {
if (ag->remote_candidates.length >= MAX_ICE_CANDIDATES) {
ilogs(ice, LOG_WARNING, "Maxmimum number of ICE candidates exceeded");
break;
@ -598,7 +597,7 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp, bool allow_reset
__copy_cand(call, dup, cand);
g_hash_table_insert(ag->candidate_hash, dup, dup);
g_hash_table_insert(ag->cand_prio_hash, GUINT_TO_POINTER(dup->priority), dup);
g_queue_push_tail(&ag->remote_candidates, dup);
t_queue_push_tail(&ag->remote_candidates, dup);
}
g_hash_table_insert(ag->foundation_hash, dup, dup);
@ -641,17 +640,17 @@ pair:
}
static void ice_candidate_free(void *p) {
g_slice_free1(sizeof(struct ice_candidate), p);
static void ice_candidate_free(struct ice_candidate *p) {
g_slice_free1(sizeof(*p), p);
}
void ice_candidates_free(GQueue *q) {
g_queue_clear_full(q, ice_candidate_free);
void ice_candidates_free(candidate_q *q) {
t_queue_clear_full(q, ice_candidate_free);
}
static void ice_candidate_pair_free(void *p) {
static void ice_candidate_pair_free(struct ice_candidate_pair *p) {
g_slice_free1(sizeof(struct ice_candidate_pair), p);
}
static void ice_candidate_pairs_free(GQueue *q) {
g_queue_clear_full(q, ice_candidate_pair_free);
static void ice_candidate_pairs_free(candidate_pair_q *q) {
t_queue_clear_full(q, ice_candidate_pair_free);
}
@ -679,14 +678,14 @@ static void __ice_agent_free_components(struct ice_agent *ag) {
return;
}
g_queue_clear(&ag->triggered);
t_queue_clear(&ag->triggered);
g_hash_table_destroy(ag->candidate_hash);
g_hash_table_destroy(ag->cand_prio_hash);
g_hash_table_destroy(ag->pair_hash);
g_hash_table_destroy(ag->transaction_hash);
g_hash_table_destroy(ag->foundation_hash);
g_tree_destroy(ag->all_pairs);
g_queue_clear(&ag->all_pairs_list);
t_queue_clear(&ag->all_pairs_list);
g_tree_destroy(ag->nominated_pairs);
g_tree_destroy(ag->succeeded_pairs);
g_tree_destroy(ag->valid_pairs);
@ -835,20 +834,19 @@ static int __component_find(const void *a, const void *b) {
static struct ice_candidate_pair *__get_pair_by_component(GTree *t, unsigned int component) {
return g_tree_find_first(t, __component_find, GUINT_TO_POINTER(component));
}
static void __get_pairs_by_component(GQueue *out, GTree *t, unsigned int component) {
g_tree_find_all(out, t, __component_find, GUINT_TO_POINTER(component));
static void __get_pairs_by_component(candidate_pair_q *out, GTree *t, unsigned int component) {
g_tree_find_all(&out->q, t, __component_find, GUINT_TO_POINTER(component));
}
static void __get_complete_succeeded_pairs(GQueue *out, struct ice_agent *ag) {
static void __get_complete_succeeded_pairs(candidate_pair_q *out, struct ice_agent *ag) {
__get_complete_components(out, ag, ag->succeeded_pairs, ICE_PAIR_SUCCEEDED);
}
static void __get_complete_valid_pairs(GQueue *out, struct ice_agent *ag) {
static void __get_complete_valid_pairs(candidate_pair_q *out, struct ice_agent *ag) {
__get_complete_components(out, ag, ag->valid_pairs, ICE_PAIR_VALID);
}
static void __nominate_pairs(struct ice_agent *ag) {
GQueue complete;
GList *l;
candidate_pair_q complete;
struct ice_candidate_pair *pair;
ilogs(ice, LOG_DEBUG, "Start nominating ICE pairs");
@ -858,22 +856,21 @@ static void __nominate_pairs(struct ice_agent *ag) {
__get_complete_succeeded_pairs(&complete, ag);
for (l = complete.head; l; l = l->next) {
for (__auto_type l = complete.head; l; l = l->next) {
pair = l->data;
ilogs(ice, LOG_DEBUG, "Nominating ICE pair "PAIR_FORMAT, PAIR_FMT(pair));
PAIR_CLEAR(pair, IN_PROGRESS);
PAIR_SET2(pair, NOMINATED, TO_USE);
pair->retransmits = 0;
__new_stun_transaction(pair);
g_queue_push_tail(&ag->triggered, pair);
t_queue_push_tail(&ag->triggered, pair);
}
g_queue_clear(&complete);
t_queue_clear(&complete);
}
/* call must be locked R or W, agent must not be locked */
static void __do_ice_checks(struct ice_agent *ag) {
GList *l;
struct ice_candidate_pair *pair, *highest = NULL, *frozen = NULL, *valid;
struct stream_fd *sfd;
GQueue retransmits = G_QUEUE_INIT;
@ -903,7 +900,7 @@ static void __do_ice_checks(struct ice_agent *ag) {
}
/* triggered checks are preferred */
pair = g_queue_pop_head(&ag->triggered);
pair = t_queue_pop_head(&ag->triggered);
if (pair) {
__DBG("running triggered check on " PAIR_FORMAT, PAIR_FMT(pair));
PAIR_CLEAR(pair, TRIGGERED);
@ -912,7 +909,7 @@ static void __do_ice_checks(struct ice_agent *ag) {
}
/* find the highest-priority non-frozen non-in-progress pair */
for (l = ag->all_pairs_list.head; l; l = l->next) {
for (__auto_type l = ag->all_pairs_list.head; l; l = l->next) {
pair = l->data;
__DBG("considering checking " PAIR_FORMAT, PAIR_FMT(pair));
@ -1084,7 +1081,7 @@ static struct ice_candidate_pair *__learned_candidate(struct ice_agent *ag, stru
goto pair;
}
g_queue_push_tail(&ag->remote_candidates, cand);
t_queue_push_tail(&ag->remote_candidates, cand);
g_hash_table_insert(ag->candidate_hash, cand, cand);
g_hash_table_insert(ag->cand_prio_hash, GUINT_TO_POINTER(cand->priority), cand);
g_hash_table_insert(ag->foundation_hash, cand, cand);
@ -1109,7 +1106,7 @@ static void __trigger_check(struct ice_candidate_pair *pair) {
if (PAIR_CLEAR(pair, FAILED))
PAIR_CLEAR(pair, IN_PROGRESS);
if (ag->triggered.length < 4 * MAX_ICE_CANDIDATES && !PAIR_SET(pair, TRIGGERED))
g_queue_push_tail(&ag->triggered, pair);
t_queue_push_tail(&ag->triggered, pair);
mutex_unlock(&ag->lock);
__agent_schedule(ag, 0);
@ -1119,7 +1116,6 @@ static void __trigger_check(struct ice_candidate_pair *pair) {
/* also regenerates all_pairs_list */
static void __recalc_pair_prios(struct ice_agent *ag) {
struct ice_candidate_pair *pair;
GList *l;
GQueue nominated, valid, succ, all;
ilogs(ice, LOG_DEBUG, "Recalculating all ICE pair priorities");
@ -1129,7 +1125,7 @@ static void __recalc_pair_prios(struct ice_agent *ag) {
g_tree_find_remove_all(&valid, ag->valid_pairs);
g_tree_find_remove_all(&all, ag->all_pairs);
for (l = ag->candidate_pairs.head; l; l = l->next) {
for (__auto_type l = ag->candidate_pairs.head; l; l = l->next) {
pair = l->data;
__do_ice_pair_priority(pair);
/* this changes the packets, so we must keep these from being seen as retransmits */
@ -1162,22 +1158,21 @@ static void __role_change(struct ice_agent *ag, int new_controlling) {
}
/* initializes "out" */
static void __get_complete_components(GQueue *out, struct ice_agent *ag, GTree *t, unsigned int flag) {
GQueue compo1 = G_QUEUE_INIT;
GList *l;
static void __get_complete_components(candidate_pair_q *out, struct ice_agent *ag, GTree *t, unsigned int flag) {
candidate_pair_q compo1 = TYPED_GQUEUE_INIT;
struct ice_candidate_pair *pair1, *pairX;
struct ice_candidate *cand;
unsigned int i;
__get_pairs_by_component(&compo1, t, 1);
g_queue_init(out);
t_queue_init(out);
for (l = compo1.head; l; l = l->next) {
for (__auto_type l = compo1.head; l; l = l->next) {
pair1 = l->data;
g_queue_clear(out);
g_queue_push_tail(out, pair1);
t_queue_clear(out);
t_queue_push_tail(out, pair1);
for (i = 2; i <= ag->active_components; i++) {
cand = __foundation_lookup(ag, &pair1->remote_candidate->foundation, i);
@ -1188,7 +1183,7 @@ static void __get_complete_components(GQueue *out, struct ice_agent *ag, GTree *
goto next_foundation;
if (!bf_isset(&pairX->pair_flags, flag))
goto next_foundation;
g_queue_push_tail(out, pairX);
t_queue_push_tail(out, pairX);
}
goto found;
@ -1197,18 +1192,19 @@ next_foundation:
}
/* nothing found */
g_queue_clear(out);
t_queue_clear(out);
found:
g_queue_clear(&compo1);
t_queue_clear(&compo1);
}
/* call(W) or call(R)+agent must be locked - no in_lock or out_lock must be held */
static int __check_valid(struct ice_agent *ag) {
struct call_media *media;
struct packet_stream *ps;
GList *l, *k;
GQueue all_compos;
GList *l;
candidate_pair_list *k;
candidate_pair_q all_compos;
struct ice_candidate_pair *pair;
// const struct local_intf *ifa;
struct stream_fd *sfd;
@ -1272,7 +1268,7 @@ static int __check_valid(struct ice_agent *ag) {
call_media_unkernelize(media, "ICE negotiation event");
g_queue_clear(&all_compos);
t_queue_clear(&all_compos);
return 1;
}
@ -1375,7 +1371,7 @@ err:
static int __check_succeeded_complete(struct ice_agent *ag) {
GQueue complete;
candidate_pair_q complete;
int ret;
__get_complete_succeeded_pairs(&complete, ag);
@ -1388,7 +1384,7 @@ static int __check_succeeded_complete(struct ice_agent *ag) {
ilogs(ice, LOG_DEBUG, "No succeeded ICE pairs with all components yet");
ret = 0;
}
g_queue_clear(&complete);
t_queue_clear(&complete);
return ret;
}
@ -1567,21 +1563,20 @@ void ice_foundation(str *s) {
random_ice_string(s->s, ICE_FOUNDATION_LENGTH);
}
void ice_remote_candidates(GQueue *out, struct ice_agent *ag) {
GQueue all_compos;
GList *l;
void ice_remote_candidates(candidate_q *out, struct ice_agent *ag) {
candidate_pair_q all_compos;
struct ice_candidate_pair *pair;
g_queue_init(out);
t_queue_init(out);
mutex_lock(&ag->lock);
__get_complete_valid_pairs(&all_compos, ag);
mutex_unlock(&ag->lock);
for (l = all_compos.head; l; l = l->next) {
for (__auto_type l = all_compos.head; l; l = l->next) {
pair = l->data;
g_queue_push_tail(out, pair->remote_candidate);
t_queue_push_tail(out, pair->remote_candidate);
}
g_queue_clear(&all_compos);
t_queue_clear(&all_compos);
}

+ 1
- 1
daemon/janus.c View File

@ -1639,7 +1639,7 @@ static const char *janus_trickle(JsonReader *reader, struct janus_session *sessi
struct stream_params *sp = g_slice_alloc0(sizeof(*sp));
t_queue_push_tail(&streams, sp);
struct ice_candidate *cand = g_slice_alloc0(sizeof(*cand));
g_queue_push_tail(&sp->ice_candidates, cand);
t_queue_push_tail(&sp->ice_candidates, cand);
// allocate and parse candidate
str cand_str;


+ 4
- 5
daemon/sdp.c View File

@ -1569,7 +1569,7 @@ static void __sdp_ice(struct stream_params *sp, struct sdp_media *media) {
continue;
cand = g_slice_alloc(sizeof(*cand));
*cand = ac->cand_parsed;
g_queue_push_tail(&sp->ice_candidates, cand);
t_queue_push_tail(&sp->ice_candidates, cand);
}
no_cand:
@ -2694,14 +2694,13 @@ static void insert_candidates(GString *s, struct packet_stream *rtp, struct pack
insert_candidate(s, rtcp->selected_sfd, type_pref, ifa->unique_id, cand_type, flags, sdp_media);
if (flags->opmode == OP_OFFER && AGENT_ISSET(ag, CONTROLLING)) {
GQueue rc;
GList *l;
candidate_q rc;
s_dst = g_string_new("");
/* prepare remote-candidates */
g_string_append(s_dst, "a=remote-candidates:");
ice_remote_candidates(&rc, ag);
for (l = rc.head; l; l = l->next) {
for (__auto_type l = rc.head; l; l = l->next) {
if (l != rc.head)
g_string_append(s_dst, " ");
cand = l->data;
@ -2712,7 +2711,7 @@ static void insert_candidates(GString *s, struct packet_stream *rtp, struct pack
append_attr_to_gstring(s, s_dst->str, NULL, flags, (sdp_media ? sdp_media->media_type_id : MT_UNKNOWN));
g_string_free(s_dst, TRUE);
g_queue_clear(&rc);
t_queue_clear(&rc);
}
return;
}


+ 1
- 1
include/call.h View File

@ -328,7 +328,7 @@ struct stream_params {
struct dtls_fingerprint fingerprint;
unsigned int sp_flags;
struct codec_store codecs;
GQueue ice_candidates; /* slice-alloc'd */
candidate_q ice_candidates; /* slice-alloc'd */
str ice_ufrag;
str ice_pwd;
int ptime;


+ 6
- 6
include/ice.h View File

@ -118,16 +118,16 @@ struct ice_agent {
mutex_t lock; /* for elements below. and call must be locked in R */
/* lock order: in_lock first, then agent->lock */
GQueue remote_candidates;
GQueue candidate_pairs; /* for storage */
GQueue triggered;
candidate_q remote_candidates;
candidate_pair_q candidate_pairs; /* for storage */
candidate_pair_q triggered;
GHashTable *candidate_hash;
GHashTable *cand_prio_hash;
GHashTable *pair_hash;
GHashTable *transaction_hash;
GHashTable *foundation_hash;
GTree *all_pairs;
GQueue all_pairs_list; /* sorted through gtree */
candidate_pair_q all_pairs_list; /* sorted through gtree */
GTree *nominated_pairs; /* nominated by peer */
GTree *succeeded_pairs; /* checked by us */
GTree *valid_pairs; /* succeeded and nominated */
@ -160,8 +160,8 @@ void ice_update(struct ice_agent *, struct stream_params *, bool allow_restart);
void ice_shutdown(struct ice_agent **);
void ice_restart(struct ice_agent *);
void ice_candidates_free(GQueue *);
void ice_remote_candidates(GQueue *, struct ice_agent *);
void ice_candidates_free(candidate_q *);
void ice_remote_candidates(candidate_q *, struct ice_agent *);
void ice_thread_run(void *);


+ 6
- 0
include/types.h View File

@ -15,4 +15,10 @@ TYPED_GQUEUE(sdp_sessions, struct sdp_session)
struct stream_params;
TYPED_GQUEUE(sdp_streams, struct stream_params)
struct ice_candidate;
TYPED_GQUEUE(candidate, struct ice_candidate)
struct ice_candidate_pair;
TYPED_GQUEUE(candidate_pair, struct ice_candidate_pair)
#endif

Loading…
Cancel
Save