예제 #1
0
파일: ice.c 프로젝트: Zodiac-Evil/rtpengine
/* 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));

}
예제 #2
0
파일: ice.c 프로젝트: gnufreex/rtpengine
/* 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));

}
예제 #3
0
파일: ice.c 프로젝트: Zodiac-Evil/rtpengine
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);
}
예제 #4
0
파일: ice.c 프로젝트: gnufreex/rtpengine
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);
}