/* * 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; }
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 } }
/** * 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; } }