ice: fix ICE-lite mode
This commit is contained in:
parent
6896e6bcfe
commit
bb70ad2741
7 changed files with 163 additions and 41 deletions
|
@ -61,6 +61,7 @@ int icem_cand_add(struct icem *icem, uint8_t compid, uint16_t lprio,
|
|||
int icem_gather_srflx(struct icem *icem, const struct sa *stun_srv);
|
||||
int icem_gather_relay(struct icem *icem, const struct sa *stun_srv,
|
||||
const char *username, const char *password);
|
||||
int icem_lite_set_default_candidates(struct icem *icem);
|
||||
bool icem_verify_support(struct icem *icem, uint8_t compid,
|
||||
const struct sa *raddr);
|
||||
int icem_conncheck_start(struct icem *icem);
|
||||
|
@ -71,6 +72,9 @@ void icem_update(struct icem *icem);
|
|||
int icem_sdp_decode(struct icem *icem, const char *name, const char *value);
|
||||
int icem_debug(struct re_printf *pf, const struct icem *icem);
|
||||
struct list *icem_lcandl(const struct icem *icem);
|
||||
struct list *icem_rcandl(const struct icem *icem);
|
||||
struct list *icem_checkl(const struct icem *icem);
|
||||
struct list *icem_validl(const struct icem *icem);
|
||||
const struct sa *icem_cand_default(struct icem *icem, uint8_t compid);
|
||||
const struct sa *icem_selected_laddr(const struct icem *icem, uint8_t compid);
|
||||
|
||||
|
|
|
@ -271,3 +271,16 @@ void icecomp_printf(struct icem_comp *comp, const char *fmt, ...)
|
|||
(void)re_printf("{%11s.%u} %v", comp->icem->name, comp->id, fmt, &ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
int icecomp_debug(struct re_printf *pf, const struct icem_comp *comp)
|
||||
{
|
||||
if (!comp)
|
||||
return 0;
|
||||
|
||||
return re_hprintf(pf, "id=%u ldef=%J rdef=%J concluded=%d",
|
||||
comp->id,
|
||||
comp->def_lcand ? &comp->def_lcand->addr : NULL,
|
||||
comp->def_rcand ? &comp->def_rcand->addr : NULL,
|
||||
comp->concluded);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,17 @@ static void handle_success(struct icem *icem, struct candpair *cp,
|
|||
}
|
||||
|
||||
|
||||
#if ICE_TRACE
|
||||
static int print_err(struct re_printf *pf, const int *err)
|
||||
{
|
||||
if (err && *err)
|
||||
return re_hprintf(pf, " (%m)", *err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void stunc_resp_handler(int err, uint16_t scode, const char *reason,
|
||||
const struct stun_msg *msg, void *arg)
|
||||
{
|
||||
|
@ -151,10 +162,10 @@ static void stunc_resp_handler(int err, uint16_t scode, const char *reason,
|
|||
(void)reason;
|
||||
|
||||
#if ICE_TRACE
|
||||
icecomp_printf(cp->comp, "Rx %H <--- %H '%u %s' (%m)\n",
|
||||
icecomp_printf(cp->comp, "Rx %H <--- %H '%u %s'%H\n",
|
||||
icem_cand_print, cp->lcand,
|
||||
icem_cand_print, cp->rcand,
|
||||
scode, reason, err);
|
||||
scode, reason, print_err, &err);
|
||||
#endif
|
||||
|
||||
if (err) {
|
||||
|
|
|
@ -213,6 +213,7 @@ void icem_comp_set_selected(struct icem_comp *comp, struct candpair *cp);
|
|||
struct icem_comp *icem_comp_find(const struct icem *icem, uint8_t compid);
|
||||
void icem_comp_keepalive(struct icem_comp *comp, bool enable);
|
||||
void icecomp_printf(struct icem_comp *comp, const char *fmt, ...);
|
||||
int icecomp_debug(struct re_printf *pf, const struct icem_comp *comp);
|
||||
|
||||
|
||||
/* conncheck */
|
||||
|
@ -237,4 +238,3 @@ uint32_t ice_calc_prio(enum cand_type type, uint16_t local, uint8_t compid);
|
|||
uint64_t ice_calc_pair_prio(uint32_t g, uint32_t d);
|
||||
void ice_switch_local_role(struct ice *ice);
|
||||
uint32_t ice_list_unique(struct list *list, list_unique_h *uh);
|
||||
uint64_t ice_get_usec(void);
|
||||
|
|
|
@ -337,6 +337,7 @@ bool icem_mismatch(const struct icem *icem)
|
|||
*/
|
||||
int icem_debug(struct re_printf *pf, const struct icem *icem)
|
||||
{
|
||||
struct le *le;
|
||||
int err = 0;
|
||||
|
||||
if (!icem)
|
||||
|
@ -344,11 +345,18 @@ int icem_debug(struct re_printf *pf, const struct icem *icem)
|
|||
|
||||
err |= re_hprintf(pf, "----- ICE Media <%s> -----\n", icem->name);
|
||||
|
||||
err |= re_hprintf(pf, " Components: (%u)\n", list_count(&icem->compl));
|
||||
for (le = icem->compl.head; le; le = le->next) {
|
||||
struct icem_comp *comp = le->data;
|
||||
|
||||
err |= re_hprintf(pf, " %H\n", icecomp_debug, comp);
|
||||
}
|
||||
|
||||
err |= re_hprintf(pf, " Local Candidates: %H",
|
||||
icem_cands_debug, &icem->lcandl);
|
||||
err |= re_hprintf(pf, " Remote Candidates: %H",
|
||||
icem_cands_debug, &icem->rcandl);
|
||||
err |= re_hprintf(pf, " Check list: [%s]%H",
|
||||
err |= re_hprintf(pf, " Check list: [state=%s]%H",
|
||||
ice_checkl_state2name(icem->state),
|
||||
icem_candpairs_debug, &icem->checkl);
|
||||
err |= re_hprintf(pf, " Valid list: %H",
|
||||
|
@ -371,6 +379,69 @@ struct list *icem_lcandl(const struct icem *icem)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of Remote Candidates (struct cand)
|
||||
*
|
||||
* @param icem ICE Media object
|
||||
*
|
||||
* @return List of Remote Candidates
|
||||
*/
|
||||
struct list *icem_rcandl(const struct icem *icem)
|
||||
{
|
||||
return icem ? (struct list *)&icem->rcandl : NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the checklist of Candidate Pairs
|
||||
*
|
||||
* @param icem ICE Media object
|
||||
*
|
||||
* @return Checklist (struct candpair)
|
||||
*/
|
||||
struct list *icem_checkl(const struct icem *icem)
|
||||
{
|
||||
return icem ? (struct list *)&icem->checkl : NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of valid Candidate Pairs
|
||||
*
|
||||
* @param icem ICE Media object
|
||||
*
|
||||
* @return Validlist (struct candpair)
|
||||
*/
|
||||
struct list *icem_validl(const struct icem *icem)
|
||||
{
|
||||
return icem ? (struct list *)&icem->validl : NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the default local candidates, for ICE-lite mode only
|
||||
*
|
||||
* @param icem ICE Media object
|
||||
*/
|
||||
int icem_lite_set_default_candidates(struct icem *icem)
|
||||
{
|
||||
struct le *le;
|
||||
int err = 0;
|
||||
|
||||
if (icem->ice->lmode != ICE_MODE_LITE)
|
||||
return EINVAL;
|
||||
|
||||
for (le = icem->compl.head; le; le = le->next) {
|
||||
|
||||
struct icem_comp *comp = le->data;
|
||||
|
||||
err |= icem_comp_set_default_cand(comp);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void icem_printf(struct icem *icem, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
|
@ -35,10 +35,6 @@ static void triggered_check(struct icem *icem, struct cand *lcand,
|
|||
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) {
|
||||
|
||||
|
@ -93,9 +89,12 @@ static void triggered_check(struct icem *icem, struct cand *lcand,
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
/*
|
||||
* 7.2.1. Additional Procedures for Full Implementations
|
||||
*/
|
||||
static int handle_stun_full(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;
|
||||
|
@ -115,15 +114,14 @@ static int handle_stun(struct ice *ice, struct icem *icem,
|
|||
lcand = icem_lcand_find_checklist(icem, comp->id);
|
||||
|
||||
if (!lcand) {
|
||||
DEBUG_WARNING("{%s.%u} no local candidate"
|
||||
DEBUG_WARNING("{%s.%u} local candidate not found"
|
||||
" (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);
|
||||
triggered_check(icem, lcand, rcand);
|
||||
|
||||
if (!cp) {
|
||||
cp = icem_candpair_find_rcand(icem, rcand);
|
||||
|
@ -172,6 +170,50 @@ static int handle_stun(struct ice *ice, struct icem *icem,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 int stunsrv_ereply(struct icem_comp *comp, const struct sa *src,
|
||||
size_t presz, const struct stun_msg *req,
|
||||
uint16_t scode, const char *reason)
|
||||
|
@ -257,8 +299,14 @@ int icem_stund_recv(struct icem_comp *comp, const struct sa *src,
|
|||
if (attr)
|
||||
use_cand = true;
|
||||
|
||||
err = handle_stun(ice, icem, comp, src, prio_prflx,
|
||||
use_cand, presz > 0);
|
||||
if (ice->lmode == ICE_MODE_FULL) {
|
||||
err = handle_stun_full(ice, icem, comp, src, prio_prflx,
|
||||
use_cand, presz > 0);
|
||||
}
|
||||
else {
|
||||
err = handle_stun_lite(icem, comp, src, use_cand);
|
||||
}
|
||||
|
||||
if (err)
|
||||
goto badmsg;
|
||||
|
||||
|
|
|
@ -140,28 +140,3 @@ uint32_t ice_list_unique(struct list *list, list_unique_h *uh)
|
|||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/** Get time of day in [microseconds] */
|
||||
uint64_t ice_get_usec(void)
|
||||
{
|
||||
uint64_t jfs;
|
||||
|
||||
#if defined(WIN32)
|
||||
FILETIME ft;
|
||||
ULARGE_INTEGER li;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
jfs = li.QuadPart/10;
|
||||
#else
|
||||
struct timeval now;
|
||||
|
||||
if (0 != gettimeofday(&now, NULL))
|
||||
return 0;
|
||||
|
||||
jfs = 1000000UL * now.tv_sec + now.tv_usec;
|
||||
#endif
|
||||
|
||||
return jfs;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue