Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static void stunc_resp_handler(int err, uint16_t scode, const char *reason,
			       const struct stun_msg *msg, void *arg)
{
	struct ice_candpair *cp = arg;
	struct icem *icem = cp->icem;
	struct stun_attr *attr;

	(void)reason;

#if ICE_TRACE
	icecomp_printf(cp->comp, "Rx %H <--- %H '%u %s'%H\n",
		       icem_cand_print, cp->lcand,
		       icem_cand_print, cp->rcand,
		       scode, reason, print_err, &err);
#endif

	if (err) {
		icem_candpair_failed(cp, err, scode);
		goto out;
	}

	switch (scode) {

	case 0: /* Success case */
		attr = stun_msg_attr(msg, STUN_ATTR_XOR_MAPPED_ADDR);
		if (!attr) {
			DEBUG_WARNING("no XOR-MAPPED-ADDR in response\n");
			icem_candpair_failed(cp, EBADMSG, 0);
			break;
		}

		handle_success(icem, cp, &attr->v.sa);
		break;

	case 487: /* Role Conflict */
		ice_switch_local_role(icem);
		(void)icem_conncheck_send(cp, false, true);
		break;

	default:
		DEBUG_WARNING("{%s.%u} STUN Response: %u %s\n",
			      icem->name, cp->comp->id, scode, reason);
		icem_candpair_failed(cp, err, scode);
		break;
	}

 out:
	pace_next(icem);
}
Exemplo n.º 3
0
static void do_check(struct ice_candpair *cp)
{
	int err;

	err = icem_conncheck_send(cp, false, false);
	if (err) {
		icem_candpair_failed(cp, err, 0);

		if (err == ENOMEM) {
			abort_ice(cp->icem, err);
		}
		else {
			pace_next(cp->icem);
		}
	}
}
Exemplo n.º 4
0
static void triggered_check(struct icem *icem, struct cand *lcand,
			    struct cand *rcand)
{
	struct candpair *cp = NULL;
	int err;

	if (lcand && rcand)
		cp = icem_candpair_find(&icem->checkl, lcand, rcand);

	if (cp) {
		icecomp_printf(cp->comp,
			       "triggered_check: found CandidatePair on"
			       " checklist in state: %H\n",
			       icem_candpair_debug, cp);

		switch (cp->state) {

#if 0
			/* TODO: I am not sure why we should cancel the
			 *       pending Connectivity check here. this
			 *       can lead to a deadlock situation where
			 *       both agents are stuck on sending
			 *       triggered checks on the same candidate pair
			 */
		case CANDPAIR_INPROGRESS:
			icem_candpair_cancel(cp);
			/*@fallthrough@*/
#endif

		case CANDPAIR_FAILED:
			icem_candpair_set_state(cp, CANDPAIR_WAITING);
			/*@fallthrough@*/

		case CANDPAIR_FROZEN:
		case CANDPAIR_WAITING:
			err = icem_conncheck_send(cp, false, true);
			if (err) {
				DEBUG_WARNING("triggered check failed\n");
			}
			break;

		case CANDPAIR_SUCCEEDED:
		default:
			break;
		}
	}
	else {

#if 0
		err = icem_candpair_alloc(&cp, icem, lcand, rcand);
		if (err) {
			DEBUG_WARNING("failed to allocate candpair:"
				      " lcand=%p rcand=%p (%m)\n",
				      lcand, rcand, err);
			return;
		}

		icem_candpair_prio_order(&icem->checkl);

		icem_candpair_set_state(cp, CANDPAIR_WAITING);

		(void)icem_conncheck_send(cp, false, true);
#endif

	}
}