Browse Source

various fixes related to ICE negotation and rtcp-mux

closes #92
changes/24/1624/1
Richard Fuchs 11 years ago
parent
commit
c0fab9b47d
2 changed files with 51 additions and 29 deletions
  1. +10
    -2
      daemon/call.c
  2. +41
    -27
      daemon/ice.c

+ 10
- 2
daemon/call.c View File

@ -146,6 +146,7 @@ const char * get_tag_type_text(enum tag_type t) {
}
static void determine_handler(struct packet_stream *in, const struct packet_stream *out);
static void __call_media_state_machine(struct call_media *m);
static int __k_null(struct rtpengine_srtp *s, struct packet_stream *);
static int __k_srtp_encrypt(struct rtpengine_srtp *s, struct packet_stream *);
@ -645,7 +646,7 @@ static int stream_packet(struct stream_fd *sfd, str *s, struct sockaddr_in6 *fsi
if (!stun_ret)
goto unlock_out;
if (stun_ret == 1) {
call_stream_state_machine(stream);
__call_media_state_machine(media);
mutex_lock(&stream->in_lock); /* for the jump */
goto kernel_check;
}
@ -1904,6 +1905,13 @@ enum call_stream_state call_stream_state_machine(struct packet_stream *ps) {
return CSS_RUNNING;
}
static void __call_media_state_machine(struct call_media *m) {
GList *l;
for (l = m->streams.head; l; l = l->next)
call_stream_state_machine(l->data);
}
static int __init_stream(struct packet_stream *ps) {
struct call_media *media = ps->media;
struct call *call = ps->call;
@ -2472,7 +2480,6 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams,
/* control rtcp-mux */
__rtcp_mux_logic(flags, media, other_media);
/* XXX update ICE if rtcp-mux changes */
/* SDES and DTLS */
__generate_crypto(flags, media, other_media);
@ -2548,6 +2555,7 @@ init:
/* we are now ready to fire up ICE if so desired and requested */
ice_update(other_media->ice_agent, sp);
ice_update(media->ice_agent, NULL); /* this is in case rtcp-mux has changed */
}
return 0;


+ 41
- 27
daemon/ice.c View File

@ -317,8 +317,9 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
int recalc = 0;
unsigned int comps;
struct packet_stream *components[MAX_COMPONENTS], *ps;
GQueue *candidates;
if (!ag || !sp)
if (!ag)
return;
media = ag->media;
@ -326,19 +327,25 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
__role_change(ag, MEDIA_ISSET(media, ICE_CONTROLLING));
/* check for ICE restarts */
if (ag->ufrag[0].s && sp->ice_ufrag.s && str_cmp_str(&ag->ufrag[0], &sp->ice_ufrag))
__ice_restart(ag);
else if (ag->pwd[0].s && sp->ice_pwd.s && str_cmp_str(&ag->pwd[0], &sp->ice_pwd))
__ice_restart(ag);
else if (ag->local_interface != media->interface)
__ice_restart(ag);
/* update remote info */
if (sp->ice_ufrag.s)
call_str_cpy(call, &ag->ufrag[0], &sp->ice_ufrag);
if (sp->ice_pwd.s)
call_str_cpy(call, &ag->pwd[0], &sp->ice_pwd);
if (sp) {
/* check for ICE restarts */
if (ag->ufrag[0].s && sp->ice_ufrag.s && str_cmp_str(&ag->ufrag[0], &sp->ice_ufrag))
__ice_restart(ag);
else if (ag->pwd[0].s && sp->ice_pwd.s && str_cmp_str(&ag->pwd[0], &sp->ice_pwd))
__ice_restart(ag);
else if (ag->local_interface != media->interface)
__ice_restart(ag);
/* update remote info */
if (sp->ice_ufrag.s)
call_str_cpy(call, &ag->ufrag[0], &sp->ice_ufrag);
if (sp->ice_pwd.s)
call_str_cpy(call, &ag->pwd[0], &sp->ice_pwd);
candidates = &sp->ice_candidates;
}
else /* this is a dummy update in case rtcp-mux has changed */
candidates = &ag->remote_candidates;
/* get our component streams */
ZERO(components);
@ -349,7 +356,7 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
components[1] = NULL;
comps = 0;
for (l = sp->ice_candidates.head; l; l = l->next) {
for (l = candidates->head; l; l = l->next) {
if (ag->remote_candidates.length >= MAX_ICE_CANDIDATES) {
ilog(LOG_WARNING, "Maxmimum number of ICE candidates exceeded");
break;
@ -360,15 +367,16 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
/* skip invalid */
if (!cand->component_id || cand->component_id > G_N_ELEMENTS(components))
continue;
/* skip if we don't have a candidate of our own */
ps = components[cand->component_id - 1];
if (!ps)
continue;
comps = MAX(comps, cand->component_id);
if (ps) /* only count active components */
comps = MAX(comps, cand->component_id);
/* check for duplicates */
dup = g_hash_table_lookup(ag->candidate_hash, cand);
if (!sp && dup) /* this isn't a real update, so only check pairings */
goto pair;
/* check for duplicates */
if (dup) {
/* if this is peer reflexive, we've learned it through STUN.
* otherwise it's simply one we've seen before. */
@ -410,6 +418,9 @@ void ice_update(struct ice_agent *ag, struct stream_params *sp) {
g_hash_table_insert(ag->foundation_hash, dup, dup);
pair:
if (!ps)
continue;
for (k = ag->local_interface->list.head; k; k = k->next) {
/* skip duplicates here also */
if (__pair_lookup(ag, dup, k->data))
@ -1088,8 +1099,10 @@ int ice_request(struct packet_stream *ps, struct sockaddr_in6 *src, struct in6_a
g_tree_insert(ag->nominated_pairs, pair, pair);
if (PAIR_ISSET(pair, SUCCEEDED))
if (PAIR_ISSET(pair, SUCCEEDED)) {
PAIR_SET(pair, VALID);
g_tree_insert(ag->valid_pairs, pair, pair);
}
if (!AGENT_ISSET(ag, CONTROLLING))
ret = __check_valid(ag);
@ -1129,7 +1142,7 @@ static int __check_succeeded_complete(struct ice_agent *ag) {
int ice_response(struct packet_stream *ps, struct sockaddr_in6 *src, struct in6_addr *dst,
struct stun_attrs *attrs, u_int32_t transaction[3])
{
struct ice_candidate_pair *pair;
struct ice_candidate_pair *pair, *opair;
struct ice_agent *ag;
struct call_media *media = ps->media;
const char *err;
@ -1222,20 +1235,21 @@ int ice_response(struct packet_stream *ps, struct sockaddr_in6 *src, struct in6_
cand = __foundation_lookup(ag, &pair->remote_candidate->foundation, component);
if (!cand)
continue;
pair = __pair_lookup(ag, cand, ifa);
if (!pair)
opair = __pair_lookup(ag, cand, ifa);
if (!opair)
continue;
if (PAIR_ISSET(pair, FAILED))
if (PAIR_ISSET(opair, FAILED))
continue;
if (!PAIR_CLEAR(pair, FROZEN))
if (!PAIR_CLEAR(opair, FROZEN))
continue;
ilog(LOG_DEBUG, "Unfreezing related ICE pair "PAIR_FORMAT, PAIR_FMT(pair));
ilog(LOG_DEBUG, "Unfreezing related ICE pair "PAIR_FORMAT, PAIR_FMT(opair));
}
/* if this was previously nominated by the peer, it's now valid */
if (PAIR_ISSET(pair, NOMINATED)) {
PAIR_SET(pair, VALID);
g_tree_insert(ag->valid_pairs, pair, pair);
if (!AGENT_ISSET(ag, CONTROLLING))


Loading…
Cancel
Save