From bb70ad2741658ca3c6c3b7c85f50ffe4caff18a1 Mon Sep 17 00:00:00 2001 From: Richard Aas Date: Mon, 3 Feb 2014 12:26:20 +0000 Subject: [PATCH] ice: fix ICE-lite mode --- include/re_ice.h | 4 +++ src/ice/comp.c | 13 +++++++++ src/ice/connchk.c | 15 ++++++++-- src/ice/ice.h | 2 +- src/ice/icem.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++- src/ice/stunsrv.c | 72 ++++++++++++++++++++++++++++++++++++++-------- src/ice/util.c | 25 ---------------- 7 files changed, 163 insertions(+), 41 deletions(-) diff --git a/include/re_ice.h b/include/re_ice.h index 6ecdc57..2982ac0 100644 --- a/include/re_ice.h +++ b/include/re_ice.h @@ -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); diff --git a/src/ice/comp.c b/src/ice/comp.c index 2d79d27..f7af9c7 100644 --- a/src/ice/comp.c +++ b/src/ice/comp.c @@ -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); +} diff --git a/src/ice/connchk.c b/src/ice/connchk.c index 045bb5d..2f8405b 100644 --- a/src/ice/connchk.c +++ b/src/ice/connchk.c @@ -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) { diff --git a/src/ice/ice.h b/src/ice/ice.h index 2957c67..afab4cd 100644 --- a/src/ice/ice.h +++ b/src/ice/ice.h @@ -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); diff --git a/src/ice/icem.c b/src/ice/icem.c index 20f4c93..e2f4262 100644 --- a/src/ice/icem.c +++ b/src/ice/icem.c @@ -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; diff --git a/src/ice/stunsrv.c b/src/ice/stunsrv.c index dc31803..11459a1 100644 --- a/src/ice/stunsrv.c +++ b/src/ice/stunsrv.c @@ -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; diff --git a/src/ice/util.c b/src/ice/util.c index 93746f2..a6e6cca 100644 --- a/src/ice/util.c +++ b/src/ice/util.c @@ -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; -}