Пример #1
0
/**
 * Forming Candidate Pairs
 */
static int candpairs_form(struct icem *icem)
{
	struct le *le;
	int err = 0;

	if (list_isempty(&icem->lcandl))
		return ENOENT;

	for (le = icem->lcandl.head; le; le = le->next) {

		struct cand *lcand = le->data;
		struct le *rle;

		for (rle = icem->rcandl.head; rle; rle = rle->next) {

			struct cand *rcand = rle->data;

			if (lcand->compid != rcand->compid)
				continue;

			if (sa_af(&lcand->addr) != sa_af(&rcand->addr))
				continue;

			err |= icem_candpair_alloc(NULL, icem, lcand, rcand);
		}
	}

	return err;
}
Пример #2
0
/*
 * 7.2.2.  Additional Procedures for Lite Implementations
 */
static int handle_stun_lite(struct icem *icem,
                            struct icem_comp *comp, const struct sa *src,
                            bool use_cand)
{
    struct cand *lcand, *rcand;
    struct candpair *cp;
    int err;

    if (!use_cand)
        return 0;

    rcand = icem_cand_find(&icem->rcandl, comp->id, src);
    if (!rcand) {
        DEBUG_WARNING("lite: could not find remote candidate\n");
        return 0;
    }

    /* find the local host candidate with the same component */
    lcand = icem_cand_find(&icem->lcandl, comp->id, NULL);
    if (!lcand) {
        DEBUG_WARNING("lite: could not find local candidate\n");
        return 0;
    }

    /* search validlist for existing candpair's */
    if (icem_candpair_find(&icem->validl, lcand, rcand))
        return 0;

    err = icem_candpair_alloc(&cp, icem, lcand, rcand);
    if (err) {
        DEBUG_WARNING("lite: failed to created candidate pair\n");
        return err;
    }

    icem_candpair_make_valid(cp);
    cp->nominated = true;

    return 0;
}
Пример #3
0
/**
 * Forming Candidate Pairs
 */
static int candpairs_form(struct icem *icem)
{
	struct le *le;
	int err = 0;

	if (list_isempty(&icem->lcandl))
		return ENOENT;

	if (list_isempty(&icem->rcandl)) {
		DEBUG_WARNING("%s: no remote candidates\n", icem->name);
		return ENOENT;
	}

	for (le = icem->lcandl.head; le; le = le->next) {

		struct cand *lcand = le->data;
		struct le *rle;

		for (rle = icem->rcandl.head; rle; rle = rle->next) {

			struct cand *rcand = rle->data;

			if (lcand->compid != rcand->compid)
				continue;

			if (sa_af(&lcand->addr) != sa_af(&rcand->addr))
				continue;

			err = icem_candpair_alloc(NULL, icem, lcand, rcand);
			if (err)
				return err;
		}
	}

	return err;
}
Пример #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

	}
}