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