/** * Add a new ICE Media object to the ICE Session * * @param icemp Pointer to allocated ICE Media object * @param ice ICE Session * @param proto Transport protocol * @param layer Protocol stack layer * @param gh Gather handler * @param chkh Connectivity check handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int icem_alloc(struct icem **icemp, struct ice *ice, int proto, int layer, ice_gather_h *gh, ice_connchk_h *chkh, void *arg) { struct icem *icem; int err = 0; if (!ice) return EINVAL; if (proto != IPPROTO_UDP) return EPROTONOSUPPORT; icem = mem_zalloc(sizeof(*icem), icem_destructor); if (!icem) return ENOMEM; tmr_init(&icem->tmr_pace); list_init(&icem->lcandl); list_init(&icem->rcandl); list_init(&icem->checkl); list_init(&icem->validl); icem->ice = ice; icem->layer = layer; icem->proto = proto; icem->state = CHECKLIST_NULL; icem->nstun = 0; icem->gh = gh; icem->chkh = chkh; icem->arg = arg; if (ICE_MODE_FULL == ice->lmode) { err = stun_alloc(&icem->stun, NULL, NULL, NULL); if (err) goto out; /* Update STUN Transport */ stun_conf(icem->stun)->rto = ice->conf.rto; stun_conf(icem->stun)->rc = ice->conf.rc; } if (err) goto out; list_append(&ice->ml, &icem->le, icem); out: if (err) mem_deref(icem); else if (icemp) *icemp = icem; return err; }
void icem_set_conf(struct icem *icem, const struct ice_conf *conf) { if (!icem || !conf) return; icem->conf = *conf; if (icem->stun) { /* Update STUN Transport */ stun_conf(icem->stun)->rto = icem->conf.rto; stun_conf(icem->stun)->rc = icem->conf.rc; } }
/** * Allocate a new ICE Session * * @param icep Pointer to allocated ICE Session object * @param mode ICE Mode; Full-mode or Lite-mode * @param offerer True if we are SDP offerer, otherwise false * * @return 0 if success, otherwise errorcode */ int ice_alloc(struct ice **icep, enum ice_mode mode, bool offerer) { struct ice *ice; int err = 0; if (!icep) return EINVAL; ice = mem_zalloc(sizeof(*ice), ice_destructor); if (!ice) return ENOMEM; list_init(&ice->ml); ice->conf = conf_default; ice->lmode = mode; ice->tiebrk = rand_u64(); rand_str(ice->lufrag, sizeof(ice->lufrag)); rand_str(ice->lpwd, sizeof(ice->lpwd)); ice_determine_role(ice, offerer); if (ICE_MODE_FULL == ice->lmode) { err = stun_alloc(&ice->stun, NULL, NULL, NULL); if (err) goto out; /* Update STUN Transport */ stun_conf(ice->stun)->rto = ice->conf.rto; stun_conf(ice->stun)->rc = ice->conf.rc; } out: if (err) mem_deref(ice); else *icep = ice; return err; }
static int cand_gather_relayed(struct icem *icem, struct icem_comp *comp, const char *username, const char *password) { const int layer = icem->layer - 10; /* below ICE stack */ int err; if (comp->turnc) return EALREADY; err = turnc_alloc(&comp->turnc, stun_conf(icem->stun), icem->proto, comp->sock, layer, &icem->stun_srv, username, password, 60, turnc_handler, comp); if (err) return err; ++icem->nstun; return 0; }
/** * Add a new ICE Media object to the ICE Session * * @param icemp Pointer to allocated ICE Media object * @param mode ICE mode * @param role Local ICE role * @param proto Transport protocol * @param layer Protocol stack layer * @param tiebrk Tie-breaker value, must be same for all media streams * @param lufrag Local username fragment * @param lpwd Local password * @param chkh Connectivity check handler * @param arg Handler argument * * @return 0 if success, otherwise errorcode */ int icem_alloc(struct icem **icemp, enum ice_mode mode, enum ice_role role, int proto, int layer, uint64_t tiebrk, const char *lufrag, const char *lpwd, ice_connchk_h *chkh, void *arg) { struct icem *icem; int err = 0; if (!icemp || !tiebrk || !lufrag || !lpwd) return EINVAL; if (str_len(lufrag) < 4 || str_len(lpwd) < 22) { DEBUG_WARNING("alloc: lufrag/lpwd is too short\n"); return EINVAL; } if (proto != IPPROTO_UDP) return EPROTONOSUPPORT; icem = mem_zalloc(sizeof(*icem), icem_destructor); if (!icem) return ENOMEM; icem->conf = conf_default; tmr_init(&icem->tmr_pace); list_init(&icem->lcandl); list_init(&icem->rcandl); list_init(&icem->checkl); list_init(&icem->validl); icem->layer = layer; icem->proto = proto; icem->state = ICE_CHECKLIST_NULL; icem->chkh = chkh; icem->arg = arg; if (err) goto out; icem->lmode = mode; icem->tiebrk = tiebrk; err |= str_dup(&icem->lufrag, lufrag); err |= str_dup(&icem->lpwd, lpwd); if (err) goto out; ice_determine_role(icem, role); if (ICE_MODE_FULL == icem->lmode) { err = stun_alloc(&icem->stun, NULL, NULL, NULL); if (err) goto out; /* Update STUN Transport */ stun_conf(icem->stun)->rto = icem->conf.rto; stun_conf(icem->stun)->rc = icem->conf.rc; } out: if (err) mem_deref(icem); else if (icemp) *icemp = icem; return err; }