ice: fix ICE-lite mode

This commit is contained in:
Richard Aas 2014-02-03 12:26:20 +00:00
parent 6896e6bcfe
commit bb70ad2741
7 changed files with 163 additions and 41 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}