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