/* agent must NOT be locked, but call must be locked in R */ static void __do_ice_check(struct ice_candidate_pair *pair) { struct sockaddr_in6 dst; struct packet_stream *ps = pair->packet_stream; struct ice_agent *ag = pair->agent; u_int32_t prio, transact[3]; if (PAIR_ISSET(pair, SUCCEEDED) && !PAIR_ISSET(pair, TO_USE)) return; if (!ag->pwd[0].s) return; ZERO(dst); dst.sin6_port = htons(pair->remote_candidate->endpoint.port); dst.sin6_addr = pair->remote_candidate->endpoint.ip46; dst.sin6_family = AF_INET6; prio = ice_priority(ICT_PRFLX, pair->local_address->preference, pair->remote_candidate->component_id); mutex_lock(&ag->lock); pair->retransmit = g_now; if (!PAIR_SET(pair, IN_PROGRESS)) { PAIR_CLEAR2(pair, FROZEN, FAILED); pair->retransmit_ms = STUN_RETRANSMIT_INTERVAL; pair->retransmits = 0; } else if (pair->retransmits > STUN_MAX_RETRANSMITS) { __fail_pair(pair); mutex_unlock(&ag->lock); return; } else { pair->retransmit_ms *= 2; pair->retransmits++; } timeval_add_usec(&pair->retransmit, pair->retransmit_ms * 1000); __agent_schedule_abs(pair->agent, &pair->retransmit); memcpy(transact, pair->stun_transaction, sizeof(transact)); pair->was_controlling = AGENT_ISSET(ag, CONTROLLING); pair->was_nominated = PAIR_ISSET(pair, TO_USE); mutex_unlock(&ag->lock); ilog(LOG_DEBUG, "Sending %sICE/STUN request for candidate pair "PAIR_FORMAT" from %s to %s", PAIR_ISSET(pair, TO_USE) ? "nominating " : "", PAIR_FMT(pair), smart_ntop_buf(&pair->local_address->addr), smart_ntop_ep_buf(&pair->remote_candidate->endpoint)); stun_binding_request(&dst, transact, &ag->pwd[0], ag->ufrag, AGENT_ISSET(ag, CONTROLLING), tie_breaker, prio, &pair->local_address->addr, ps->sfd->fd.fd, PAIR_ISSET(pair, TO_USE)); }
/* agent must NOT be locked, but call must be locked in R */ static void __do_ice_check(struct ice_candidate_pair *pair) { struct stream_fd *sfd = pair->sfd; struct ice_agent *ag = pair->agent; u_int32_t prio, transact[3]; if (PAIR_ISSET(pair, SUCCEEDED) && !PAIR_ISSET(pair, TO_USE)) return; if (!ag->pwd[0].s) return; prio = ice_priority(ICT_PRFLX, pair->local_intf->unique_id, pair->remote_candidate->component_id); mutex_lock(&ag->lock); pair->retransmit = g_now; if (!PAIR_SET(pair, IN_PROGRESS)) { PAIR_CLEAR2(pair, FROZEN, FAILED); pair->retransmit_ms = STUN_RETRANSMIT_INTERVAL; pair->retransmits = 0; } else if (pair->retransmits > STUN_MAX_RETRANSMITS) { __fail_pair(pair); mutex_unlock(&ag->lock); return; } else { pair->retransmit_ms *= 2; pair->retransmits++; } timeval_add_usec(&pair->retransmit, pair->retransmit_ms * 1000); __agent_schedule_abs(pair->agent, &pair->retransmit); memcpy(transact, pair->stun_transaction, sizeof(transact)); pair->was_controlling = AGENT_ISSET(ag, CONTROLLING); pair->was_nominated = PAIR_ISSET(pair, TO_USE); mutex_unlock(&ag->lock); ilog(LOG_DEBUG, "Sending %sICE/STUN request for candidate pair "PAIR_FORMAT" from %s to %s", PAIR_ISSET(pair, TO_USE) ? "nominating " : "", PAIR_FMT(pair), sockaddr_print_buf(&pair->local_intf->spec->local_address.addr), endpoint_print_buf(&pair->remote_candidate->endpoint)); stun_binding_request(&pair->remote_candidate->endpoint, transact, &ag->pwd[0], ag->ufrag, AGENT_ISSET(ag, CONTROLLING), tie_breaker, prio, &sfd->socket, PAIR_ISSET(pair, TO_USE)); }
static u_int64_t __ice_pair_priority(struct interface_address *ifa, struct ice_candidate *cand, int controlling) { u_int64_t g, d; g = ice_priority(ICT_HOST, ifa->preference, cand->component_id); d = cand->priority; if (!controlling) { u_int64_t t = g; g = d; d = t; } return (MIN(g,d) << 32) + (MAX(g,d) << 1) + (g > d ? 1 : 0); }
static u_int64_t __ice_pair_priority(const struct local_intf *ifa, struct ice_candidate *cand, int controlling) { u_int64_t g, d; g = ice_priority(ICT_HOST, ifa->unique_id, cand->component_id); d = cand->priority; if (!controlling) { u_int64_t t = g; g = d; d = t; } return (MIN(g,d) << 32) + (MAX(g,d) << 1) + (g > d ? 1 : 0); }