diff --git a/include/re_ice.h b/include/re_ice.h index aa5b99a..aa4a092 100644 --- a/include/re_ice.h +++ b/include/re_ice.h @@ -56,6 +56,7 @@ enum ice_candpair_state { struct ice; struct icem; +struct turnc; /** ICE Configuration */ struct ice_conf { @@ -65,8 +66,6 @@ struct ice_conf { bool debug; /**< Enable ICE debugging */ }; -typedef void (ice_gather_h)(int err, uint16_t scode, const char *reason, - void *arg); typedef void (ice_connchk_h)(int err, bool update, void *arg); @@ -74,7 +73,7 @@ typedef void (ice_connchk_h)(int err, bool update, void *arg); 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_gather_h *gh, ice_connchk_h *chkh, void *arg); + ice_connchk_h *chkh, void *arg); struct ice_conf *icem_conf(struct icem *icem); enum ice_role icem_local_role(const struct icem *icem); void icem_set_conf(struct icem *icem, const struct ice_conf *conf); @@ -83,9 +82,7 @@ void icem_set_name(struct icem *icem, const char *name); int icem_comp_add(struct icem *icem, unsigned compid, void *sock); int icem_cand_add(struct icem *icem, unsigned compid, uint16_t lprio, const char *ifname, const struct sa *addr); -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, unsigned compid, const struct sa *raddr); @@ -104,12 +101,24 @@ struct list *icem_validl(const struct icem *icem); const struct sa *icem_cand_default(struct icem *icem, unsigned compid); const struct sa *icem_selected_laddr(const struct icem *icem, unsigned compid); void ice_candpair_set_states(struct icem *icem); +void icem_cand_redund_elim(struct icem *icem); +int icem_comps_set_default_cand(struct icem *icem); +struct stun *icem_stun(struct icem *icem); +int icem_set_turn_client(struct icem *icem, unsigned compid, + struct turnc *turnc); struct ice_cand; bool ice_remotecands_avail(const struct icem *icem); int ice_cand_encode(struct re_printf *pf, const struct ice_cand *cand); int ice_remotecands_encode(struct re_printf *pf, const struct icem *icem); +struct ice_cand *icem_cand_find(const struct list *lst, unsigned compid, + const struct sa *addr); +int icem_lcand_add(struct icem *icem, struct ice_cand *base, + enum ice_cand_type type, + const struct sa *addr); +struct ice_cand *icem_lcand_base(struct ice_cand *lcand); +const struct sa *icem_lcand_addr(const struct ice_cand *cand); extern const char ice_attr_cand[]; diff --git a/src/ice/cand.c b/src/ice/cand.c index fd53138..3a9d0f7 100644 --- a/src/ice/cand.c +++ b/src/ice/cand.c @@ -258,6 +258,18 @@ struct ice_cand *icem_lcand_find_checklist(const struct icem *icem, } +struct ice_cand *icem_lcand_base(struct ice_cand *lcand) +{ + return lcand ? lcand->base : NULL; +} + + +const struct sa *icem_lcand_addr(const struct ice_cand *cand) +{ + return cand ? &cand->addr : NULL; +} + + int icem_cands_debug(struct re_printf *pf, const struct list *lst) { struct le *le; diff --git a/src/ice/comp.c b/src/ice/comp.c index 94000e9..1e5c69f 100644 --- a/src/ice/comp.c +++ b/src/ice/comp.c @@ -68,7 +68,6 @@ static void destructor(void *arg) struct icem_comp *comp = arg; tmr_cancel(&comp->tmr_ka); - mem_deref(comp->ct_gath); mem_deref(comp->turnc); mem_deref(comp->cp_sel); mem_deref(comp->def_lcand); @@ -286,3 +285,21 @@ int icecomp_debug(struct re_printf *pf, const struct icem_comp *comp) comp->def_rcand ? &comp->def_rcand->addr : NULL, comp->concluded); } + + +int icem_set_turn_client(struct icem *icem, unsigned compid, + struct turnc *turnc) +{ + struct icem_comp *comp; + + comp = icem_comp_find(icem, compid); + if (!comp) + return ENOENT; + + comp->turnc = mem_deref(comp->turnc); + + if (turnc) + comp->turnc = mem_ref(turnc); + + return 0; +} diff --git a/src/ice/gather.c b/src/ice/gather.c deleted file mode 100644 index c514ace..0000000 --- a/src/ice/gather.c +++ /dev/null @@ -1,258 +0,0 @@ -/** - * @file gather.c ICE Candidate Gathering - * - * Copyright (C) 2010 Creytiv.com - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ice.h" - - -#define DEBUG_MODULE "icegath" -#define DEBUG_LEVEL 5 -#include - - -static void call_gather_handler(int err, struct icem *icem, uint16_t scode, - const char *reason) -{ - struct le *le; - - /* No more pending requests? */ - if (icem->nstun != 0) - return; - - if (!icem->gh) - return; - - if (err) - goto out; - - icem_cand_redund_elim(icem); - - for (le = icem->compl.head; le; le = le->next) { - - struct icem_comp *comp = le->data; - - err |= icem_comp_set_default_cand(comp); - } - - out: - icem->gh(err, scode, reason, icem->arg); - - icem->gh = NULL; -} - - -static void stun_resp_handler(int err, uint16_t scode, const char *reason, - const struct stun_msg *msg, void *arg) -{ - struct icem_comp *comp = arg; - struct icem *icem = comp->icem; - struct stun_attr *attr; - struct ice_cand *lcand; - - --icem->nstun; - - if (err || scode > 0) { - DEBUG_WARNING("{%s.%u} STUN Request failed: %m\n", - icem->name, comp->id, err); - goto out; - } - - lcand = icem_cand_find(&icem->lcandl, comp->id, NULL); - if (!lcand) - goto out; - - attr = stun_msg_attr(msg, STUN_ATTR_XOR_MAPPED_ADDR); - if (!attr) - attr = stun_msg_attr(msg, STUN_ATTR_MAPPED_ADDR); - if (!attr) { - DEBUG_WARNING("no Mapped Address in Response\n"); - err = EPROTO; - goto out; - } - - err = icem_lcand_add(icem, lcand->base, ICE_CAND_TYPE_SRFLX, - &attr->v.sa); - - out: - call_gather_handler(err, icem, scode, reason); -} - - -/** Gather Server Reflexive address */ -static int send_binding_request(struct icem *icem, struct icem_comp *comp) -{ - int err; - - if (comp->ct_gath) - return EALREADY; - - err = stun_request(&comp->ct_gath, icem->stun, icem->proto, - comp->sock, &icem->stun_srv, 0, - STUN_METHOD_BINDING, - NULL, false, 0, - stun_resp_handler, comp, 1, - STUN_ATTR_SOFTWARE, stun_software); - if (err) - return err; - - ++icem->nstun; - - return 0; -} - - -static void turnc_handler(int err, uint16_t scode, const char *reason, - const struct sa *relay, const struct sa *mapped, - const struct stun_msg *msg, void *arg) -{ - struct icem_comp *comp = arg; - struct icem *icem = comp->icem; - struct ice_cand *lcand; - (void)msg; - - --icem->nstun; - - /* TURN failed, so we destroy the client */ - if (err || scode) { - comp->turnc = mem_deref(comp->turnc); - } - - if (err) { - DEBUG_WARNING("{%s.%u} TURN Client error: %m\n", - icem->name, comp->id, err); - goto out; - } - - if (scode) { - DEBUG_WARNING("{%s.%u} TURN Client error: %u %s\n", - icem->name, comp->id, scode, reason); - err = send_binding_request(icem, comp); - if (err) - goto out; - return; - } - - lcand = icem_cand_find(&icem->lcandl, comp->id, NULL); - if (!lcand) - goto out; - - if (!sa_cmp(relay, &lcand->base->addr, SA_ALL)) { - err = icem_lcand_add(icem, lcand->base, - ICE_CAND_TYPE_RELAY, relay); - } - - if (mapped) { - err |= icem_lcand_add(icem, lcand->base, - ICE_CAND_TYPE_SRFLX, mapped); - } - else { - err |= send_binding_request(icem, comp); - } - - out: - call_gather_handler(err, icem, scode, reason); -} - - -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; -} - - -static int start_gathering(struct icem *icem, const struct sa *stun_srv, - const char *username, const char *password) -{ - struct le *le; - int err = 0; - - if (icem->lmode != ICE_MODE_FULL) - return EINVAL; - - if (list_isempty(&icem->compl)) { - DEBUG_WARNING("gathering: no components for" - " mediastream '%s'\n", icem->name); - return ENOENT; - } - - sa_cpy(&icem->stun_srv, stun_srv); - - /* for each component */ - for (le = icem->compl.head; le; le = le->next) { - - struct icem_comp *comp = le->data; - - if (username && password) { - err |= cand_gather_relayed(icem, comp, - username, password); - } - else - err |= send_binding_request(icem, comp); - } - - return err; -} - - -/** - * Gather Server Reflexive candidates using STUN Server - * - * @param icem ICE Media object - * @param stun_srv STUN Server network address - * - * @return 0 if success, otherwise errorcode - */ -int icem_gather_srflx(struct icem *icem, const struct sa *stun_srv) -{ - if (!icem || !stun_srv) - return EINVAL; - - return start_gathering(icem, stun_srv, NULL, NULL); -} - - -/** - * Gather Relayed and Server Reflexive candidates using TURN Server - * - * @param icem ICE Media object - * @param stun_srv TURN Server network address - * @param username TURN Server username - * @param password TURN Server password - * - * @return 0 if success, otherwise errorcode - */ -int icem_gather_relay(struct icem *icem, const struct sa *stun_srv, - const char *username, const char *password) -{ - if (!icem || !stun_srv || !username || !password) - return EINVAL; - - return start_gathering(icem, stun_srv, username, password); -} diff --git a/src/ice/ice.h b/src/ice/ice.h index a6580f4..b61d362 100644 --- a/src/ice/ice.h +++ b/src/ice/ice.h @@ -46,7 +46,6 @@ struct icem_comp { unsigned id; /**< Component ID */ bool concluded; /**< Concluded flag */ struct turnc *turnc; /**< TURN Client */ - struct stun_ctrans *ct_gath; /**< STUN Transaction for gathering */ struct tmr tmr_ka; /**< Keep-alive timer */ }; @@ -55,7 +54,6 @@ struct icem { struct ice_conf conf; /**< ICE Configuration */ struct stun *stun; /**< STUN Transport */ struct sa stun_srv; /**< STUN Server IP address and port */ - int nstun; /**< Number of pending STUN candidates */ struct list lcandl; /**< List of local candidates */ struct list rcandl; /**< List of remote candidates */ struct list checkl; /**< Check List of cand pairs (sorted) */ @@ -74,7 +72,6 @@ struct icem { char *lpwd; /**< Local Password */ char *rufrag; /**< Remote Username fragment */ char *rpwd; /**< Remote Password */ - ice_gather_h *gh; /**< Gather handler */ ice_connchk_h *chkh; /**< Connectivity check handler */ void *arg; /**< Handler argument */ char name[32]; /**< Name of the media stream */ @@ -118,17 +115,12 @@ struct ice_candpair { int icem_lcand_add_base(struct icem *icem, unsigned compid, uint16_t lprio, const char *ifname, enum ice_transp transp, const struct sa *addr); -int icem_lcand_add(struct icem *icem, struct ice_cand *base, - enum ice_cand_type type, - const struct sa *addr); int icem_rcand_add(struct icem *icem, enum ice_cand_type type, unsigned compid, uint32_t prio, const struct sa *addr, const struct sa *rel_addr, const struct pl *foundation); int icem_rcand_add_prflx(struct ice_cand **rcp, struct icem *icem, unsigned compid, uint32_t prio, const struct sa *addr); -struct ice_cand *icem_cand_find(const struct list *lst, unsigned compid, - const struct sa *addr); struct ice_cand *icem_lcand_find_checklist(const struct icem *icem, unsigned compid); int icem_cands_debug(struct re_printf *pf, const struct list *lst); @@ -173,7 +165,6 @@ int icem_stund_recv(struct icem_comp *comp, const struct sa *src, /* ICE media */ -void icem_cand_redund_elim(struct icem *icem); void icem_printf(struct icem *icem, const char *fmt, ...); diff --git a/src/ice/icem.c b/src/ice/icem.c index cc87bad..b2361c9 100644 --- a/src/ice/icem.c +++ b/src/ice/icem.c @@ -78,7 +78,6 @@ static void icem_destructor(void *data) * @param tiebrk Tie-breaker value, must be same for all media streams * @param lufrag Local username fragment * @param lpwd Local password - * @param gh Gather handler * @param chkh Connectivity check handler * @param arg Handler argument * @@ -88,7 +87,7 @@ 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_gather_h *gh, ice_connchk_h *chkh, void *arg) + ice_connchk_h *chkh, void *arg) { struct icem *icem; int err = 0; @@ -119,8 +118,6 @@ int icem_alloc(struct icem **icemp, icem->layer = layer; icem->proto = proto; icem->state = ICE_CHECKLIST_NULL; - icem->nstun = 0; - icem->gh = gh; icem->chkh = chkh; icem->arg = arg; @@ -565,6 +562,31 @@ int icem_lite_set_default_candidates(struct icem *icem) } +int icem_comps_set_default_cand(struct icem *icem) +{ + struct le *le; + int err = 0; + + if (!icem) + 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; +} + + +struct stun *icem_stun(struct icem *icem) +{ + return icem ? icem->stun : NULL; +} + + void icem_printf(struct icem *icem, const char *fmt, ...) { va_list ap; diff --git a/src/ice/mod.mk b/src/ice/mod.mk index 974ef42..54aefbe 100644 --- a/src/ice/mod.mk +++ b/src/ice/mod.mk @@ -9,7 +9,6 @@ SRCS += ice/candpair.c SRCS += ice/chklist.c SRCS += ice/comp.c SRCS += ice/connchk.c -SRCS += ice/gather.c SRCS += ice/icem.c SRCS += ice/icesdp.c SRCS += ice/icestr.c