예제 #1
0
static void handle_success(struct icem *icem, struct ice_candpair *cp,
			   const struct sa *laddr)
{
	if (!icem_cand_find(&icem->lcandl, cp->lcand->compid, laddr)) {

		int err;

		icecomp_printf(cp->comp, "adding local PRFLX Candidate: %J\n",
			       laddr);

		err = icem_lcand_add(icem, cp->lcand,
				     ICE_CAND_TYPE_PRFLX, laddr);
		if (err) {
			DEBUG_WARNING("failed to add PRFLX: %m\n", err);
		}
	}

	cp = construct_valid_pair(icem, cp, laddr, &cp->rcand->addr);
	if (!cp) {
		DEBUG_WARNING("{%s} no valid candidate pair for %J\n",
			      icem->name, laddr);
		return;
	}

	icem_candpair_make_valid(cp);
	icem_comp_set_selected(cp->comp, cp);

	cp->nominated = true;

#if 0
	/* stop conncheck now -- conclude */
	icem_conncheck_stop(icem, 0);
#endif
}
예제 #2
0
/* 8.  Concluding ICE Processing */
static void concluding_ice(struct icem_comp *comp)
{
	struct candpair *cp;

	if (!comp || comp->concluded)
		return;

	/* pick the best candidate pair, highest priority */
	cp = icem_candpair_find_st(&comp->icem->validl, comp->id,
				   CANDPAIR_SUCCEEDED);
	if (!cp) {
		DEBUG_WARNING("{%s.%u} conclude: no valid candpair found"
			      " (validlist=%u)\n",
			      comp->icem->name, comp->id,
			      list_count(&comp->icem->validl));
		return;
	}

	icem_comp_set_selected(comp, cp);

	if (comp->icem->ice->conf.nom == ICE_NOMINATION_REGULAR) {

		/* send STUN request with USE_CAND flag via triggered qeueue */
		(void)icem_conncheck_send(cp, true, true);
		icem_conncheck_schedule_check(comp->icem);
	}

	comp->concluded = true;
}
예제 #3
0
static int handle_stun(struct ice *ice, struct icem *icem,
		       struct icem_comp *comp, const struct sa *src,
		       uint32_t prio, bool use_cand, bool tunnel)
{
	struct cand *lcand = NULL, *rcand;
	struct candpair *cp = NULL;
	int err;

	rcand = icem_cand_find(&icem->rcandl, comp->id, src);
	if (!rcand) {
		err = icem_rcand_add_prflx(&rcand, icem, comp->id, prio, src);
		if (err)
			return err;
	}

	cp = icem_candpair_find_rcand(icem, rcand);
	if (cp)
		lcand = cp->lcand;
	else
		lcand = icem_lcand_find_checklist(icem, comp->id);

	if (!lcand) {
		DEBUG_WARNING("{%s.%u} no local candidate"
			      " (checklist=%u) (src=%J)\n",
			      icem->name, comp->id,
			      list_count(&icem->checkl), src);
		return 0;
	}

	if (ICE_MODE_FULL == ice->lmode)
		triggered_check(icem, lcand, rcand);

	if (!cp) {
		cp = icem_candpair_find_rcand(icem, rcand);
		if (!cp) {
			DEBUG_WARNING("{%s.%u} candidate pair not found:"
				      " source=%J\n",
				      icem->name, comp->id, src);
			return 0;
		}
	}

#if ICE_TRACE
	icecomp_printf(comp, "Rx Binding Request from %J via %s"
		       " (candpair=%s) %s\n",
		       src, tunnel ? "Tunnel" : "Socket",
		       cp ? ice_candpair_state2name(cp->state) : "n/a",
		       use_cand ? "[USE]" : "");
#else
	(void)tunnel;
#endif

	/* 7.2.1.5.  Updating the Nominated Flag */
	if (use_cand) {
		if (ice->lrole == ROLE_CONTROLLED) {
			if (cp->state == CANDPAIR_SUCCEEDED) {
				cp->nominated = true;

				icecomp_printf(comp, "setting NOMINATED"
					       " flag on candpair [%H]\n",
					       icem_candpair_debug, cp);
			}
		}

		/* Cancel conncheck. Choose Selected Pair */
		icem_candpair_make_valid(cp);

		if (ice->conf.nom == ICE_NOMINATION_REGULAR) {
			icem_candpair_cancel(cp);
			icem_comp_set_selected(comp, cp);
		}
	}

	return 0;
}