int icem_lcand_add_base(struct icem *icem, uint8_t compid, uint16_t lprio, const char *ifname, enum ice_transp transp, const struct sa *addr) { struct icem_comp *comp; struct cand *cand; int err; comp = icem_comp_find(icem, compid); if (!comp) return ENOENT; err = cand_alloc(&cand, icem, CAND_TYPE_HOST, compid, ice_calc_prio(CAND_TYPE_HOST, lprio, compid), ifname, transp, addr); if (err) return err; /* the base is itself */ cand->base = cand; sa_set_port(&cand->addr, comp->lport); return 0; }
int icem_candpair_alloc(struct candpair **cpp, struct icem *icem, struct cand *lcand, struct cand *rcand) { struct candpair *cp; struct icem_comp *comp; if (!icem || !lcand || !rcand) return EINVAL; comp = icem_comp_find(icem, lcand->compid); if (!comp) return ENOENT; cp = mem_zalloc(sizeof(*cp), candpair_destructor); if (!cp) return ENOMEM; cp->icem = icem; cp->comp = comp; cp->lcand = mem_ref(lcand); cp->rcand = mem_ref(rcand); cp->state = CANDPAIR_FROZEN; cp->ertt = -1; cp->def = comp->def_lcand == lcand && comp->def_rcand == rcand; candpair_set_pprio(cp); list_add_sorted(&icem->checkl, cp); if (cpp) *cpp = cp; return 0; }
/** * Get the Remote address of the Selected Candidate pair, if available * * @param icem ICE Media object * @param compid Component ID * * @return Remote address if available, otherwise NULL */ const struct sa *icem_selected_raddr(const struct icem *icem, uint8_t compid) { const struct icem_comp *comp = icem_comp_find(icem, compid); if (!comp || !comp->cp_sel) return NULL; return &comp->cp_sel->rcand->addr; }
/** * Get the Local address of the Selected Candidate pair, if available * * @param icem ICE Media object * @param compid Component ID * * @return Local address if available, otherwise NULL */ const struct sa *icem_selected_laddr(const struct icem *icem, unsigned compid) { const struct icem_comp *comp = icem_comp_find(icem, compid); if (!comp || !comp->cp_sel) return NULL; return &comp->cp_sel->lcand->addr; }
/** * Get the Default Candidate * * @param icem ICE Media object * @param compid Component ID * * @return Default Candidate address if set, otherwise NULL */ const struct sa *icem_cand_default(struct icem *icem, uint8_t compid) { const struct icem_comp *comp = icem_comp_find(icem, compid); if (!comp || !comp->def_lcand) return NULL; return &comp->def_lcand->addr; }
/** * Add a new candidate to the ICE Media object * * @param icem ICE Media object * @param compid Component ID * @param lprio Local priority * @param ifname Name of the network interface * @param addr Local network address * * @return 0 if success, otherwise errorcode */ int icem_cand_add(struct icem *icem, unsigned compid, uint16_t lprio, const char *ifname, const struct sa *addr) { if (!icem_comp_find(icem, compid)) return ENOENT; return icem_lcand_add_base(icem, compid, lprio, ifname, ICE_TRANSP_UDP, addr); }
/** * Add a new component to the ICE Media object * * @param icem ICE Media object * @param compid Component ID * @param sock Application protocol socket * * @return 0 if success, otherwise errorcode */ int icem_comp_add(struct icem *icem, unsigned compid, void *sock) { struct icem_comp *comp; int err; if (!icem) return EINVAL; if (icem_comp_find(icem, compid)) return EALREADY; err = icem_comp_alloc(&comp, icem, compid, sock); if (err) return err; list_append(&icem->compl, &comp->le, comp); return 0; }
/** * Add a TURN Channel for the selected remote address * * @param icem ICE Media object * @param compid Component ID * @param raddr Remote network address * * @return 0 if success, otherwise errorcode */ int icem_add_chan(struct icem *icem, unsigned compid, const struct sa *raddr) { struct icem_comp *comp; if (!icem) return EINVAL; comp = icem_comp_find(icem, compid); if (!comp) return ENOENT; if (comp->turnc) { DEBUG_NOTICE("{%s.%u} Add TURN Channel to peer %J\n", comp->icem->name, comp->id, raddr); return turnc_add_chan(comp->turnc, raddr, NULL, NULL); } return 0; }
/** * Verifying ICE Support and set default remote candidate * * @param icem ICE Media * @param compid Component ID * @param raddr Address of default remote candidate * * @return True if ICE is supported, otherwise false */ bool icem_verify_support(struct icem *icem, unsigned compid, const struct sa *raddr) { struct ice_cand *rcand; bool match; if (!icem) return false; rcand = icem_cand_find(&icem->rcandl, compid, raddr); match = rcand != NULL; if (!match) icem->mismatch = true; if (rcand) { icem_comp_set_default_rcand(icem_comp_find(icem, compid), rcand); } return match; }
int icem_rcand_add_prflx(struct cand **rcp, struct icem *icem, uint8_t compid, uint32_t prio, const struct sa *addr) { struct cand *rcand; int err; if (!icem || !addr) return EINVAL; rcand = mem_zalloc(sizeof(*rcand), cand_destructor); if (!rcand) return ENOMEM; list_append(&icem->rcandl, &rcand->le, rcand); rcand->type = CAND_TYPE_PRFLX; rcand->compid = compid; rcand->prio = prio; rcand->addr = *addr; err = re_sdprintf(&rcand->foundation, "%08x", rand_u32()); if (err) goto out; icecomp_printf(icem_comp_find(icem, compid), "added PeerReflexive remote candidate" " with priority %u (%J)\n", prio, addr); out: if (err) mem_deref(rcand); else if (rcp) *rcp = rcand; return err; }