/* 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 = ag->media; struct packet_stream *ps; GList *l, *k, *m; GQueue all_compos; struct ice_candidate_pair *pair; // const struct local_intf *ifa; struct stream_fd *sfd; if (!ag) { ilog(LOG_ERR, "ice ag is NULL"); return 0; } __get_complete_valid_pairs(&all_compos, ag); if (!all_compos.length) { ilog(LOG_DEBUG, "ICE not completed yet"); return 0; } pair = all_compos.head->data; ilog(LOG_DEBUG, "ICE completed, using pair "PAIR_FORMAT, PAIR_FMT(pair)); AGENT_SET(ag, COMPLETED); for (l = media->streams.head, k = all_compos.head; l && k; l = l->next, k = k->next) { ps = l->data; pair = k->data; mutex_lock(&ps->out_lock); if (memcmp(&ps->endpoint, &pair->remote_candidate->endpoint, sizeof(ps->endpoint))) { ilog(LOG_INFO, "ICE negotiated: peer for component %u is %s", ps->component, endpoint_print_buf(&pair->remote_candidate->endpoint)); ps->endpoint = pair->remote_candidate->endpoint; } mutex_unlock(&ps->out_lock); for (m = ps->sfds.head; m; m = m->next) { sfd = m->data; if (sfd->local_intf != pair->local_intf) continue; ps->selected_sfd = sfd; if (ps->component == 1) ilog(LOG_INFO, "ICE negotiated: local interface %s", sockaddr_print_buf(&pair->local_intf->spec->local_address.addr)); } } call_media_unkernelize(media); g_queue_clear(&all_compos); return 1; }
/* 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 = ag->media; struct packet_stream *ps; GList *l, *k; GQueue all_compos; struct ice_candidate_pair *pair; struct interface_address *ifa; if (!ag) { ilog(LOG_ERR, "ice ag is NULL"); return 0; } __get_complete_valid_pairs(&all_compos, ag); if (!all_compos.length) { ilog(LOG_DEBUG, "ICE not completed yet"); return 0; } pair = all_compos.head->data; ilog(LOG_DEBUG, "ICE completed, using pair "PAIR_FORMAT, PAIR_FMT(pair)); AGENT_SET(ag, COMPLETED); ifa = g_atomic_pointer_get(&media->local_address); if (ifa != pair->local_address && g_atomic_pointer_compare_and_exchange(&media->local_address, ifa, pair->local_address)) ilog(LOG_INFO, "ICE negotiated: local interface %s", smart_ntop_buf(&pair->local_address->addr)); for (l = media->streams.head, k = all_compos.head; l && k; l = l->next, k = k->next) { ps = l->data; pair = k->data; mutex_lock(&ps->out_lock); if (memcmp(&ps->endpoint, &pair->remote_candidate->endpoint, sizeof(ps->endpoint))) { ilog(LOG_INFO, "ICE negotiated: peer for component %u is %s", ps->component, smart_ntop_ep_buf(&pair->remote_candidate->endpoint)); ps->endpoint = pair->remote_candidate->endpoint; } mutex_unlock(&ps->out_lock); } call_media_unkernelize(media); g_queue_clear(&all_compos); return 1; }
/* agent must NOT be locked */ static void __role_change(struct ice_agent *ag, int new_controlling) { if (new_controlling && !AGENT_SET(ag, CONTROLLING)) ; else if (!new_controlling && AGENT_CLEAR(ag, CONTROLLING)) ; else return; ilog(LOG_DEBUG, "ICE role change, now %s", new_controlling ? "controlling" : "controlled"); /* recalc priorities and resort list */ mutex_lock(&ag->lock); __recalc_pair_prios(ag); mutex_unlock(&ag->lock); }
static void __nominate_pairs(struct ice_agent *ag) { GQueue complete; GList *l; struct ice_candidate_pair *pair; ilog(LOG_DEBUG, "Start nominating ICE pairs"); AGENT_SET(ag, NOMINATING); ZERO(ag->start_nominating); __get_complete_succeeded_pairs(&complete, ag); for (l = complete.head; l; l = l->next) { pair = l->data; ilog(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); } g_queue_clear(&complete); }