예제 #1
0
파일: stunsrv.c 프로젝트: singalen/libre
/*
 * 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;
}
예제 #2
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

	}
}
예제 #3
0
/**
 * Constructing a Valid Pair
 *
 * @return The valid pair
 */
static struct ice_candpair *construct_valid_pair(struct icem *icem,
					     struct ice_candpair *cp,
					     const struct sa *mapped,
					     const struct sa *dest)
{
	struct ice_cand *lcand, *rcand;
	struct ice_candpair *cp2;
	int err;

	lcand = icem_cand_find(&icem->lcandl, cp->lcand->compid, mapped);
	rcand = icem_cand_find(&icem->rcandl, cp->rcand->compid, dest);

	if (!lcand) {
		DEBUG_WARNING("no such local candidate: %J\n", mapped);
		return NULL;
	}
	if (!rcand) {
		DEBUG_WARNING("no such remote candidate: %J\n", dest);
		return NULL;
	}

	/* New candidate? -- implicit success */
	if (lcand != cp->lcand || rcand != cp->rcand) {

		if (lcand != cp->lcand) {
			icecomp_printf(cp->comp,
				       "New local candidate for mapped %J\n",
				       mapped);
		}
		if (rcand != cp->rcand) {
			icecomp_printf(cp->comp,
				       "New remote candidate for dest %J\n",
				       dest);
		}

		/* The original candidate pair is set to 'Failed' because
		 * the implicitly discovered pair is 'better'.
		 * This happens for UAs behind NAT where the original
		 * pair is of type 'host' and the implicit pair is 'srflx'
		 */

		icem_candpair_make_valid(cp);

		cp2 = icem_candpair_find(&icem->validl, lcand, rcand);
		if (cp2)
			return cp2;

		err = icem_candpair_clone(&cp2, cp, lcand, rcand);
		if (err)
			return NULL;

		icem_candpair_make_valid(cp2);
		/*icem_candpair_failed(cp, EINTR, 0);*/

		return cp2;
	}
	else {
		/* Add to VALID LIST, the pair that generated the check */
		icem_candpair_make_valid(cp);

		return cp;
	}
}