Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ice: add candidate sdp mdns support #917

Merged
merged 12 commits into from
Aug 29, 2023
15 changes: 15 additions & 0 deletions src/ice/connchk.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,14 @@ static void pace_timeout(void *arg)
}


static void rcand_wait_timeout(void *arg)
{
struct icem *icem = arg;

icem_conncheck_start(icem);
}


/**
* Scheduling Checks
*
Expand All @@ -414,6 +422,13 @@ int icem_conncheck_start(struct icem *icem)
if (!icem)
return EINVAL;

if (icem->rcand_wait) {
icem_printf(icem, "conncheck_start: "
"waiting mDNS for remote candidate...\n");
tmr_start(&icem->tmr_rcand, 100, rcand_wait_timeout, icem);
return 0;
}

err = icem_checklist_form(icem);
if (err)
return err;
Expand Down
2 changes: 2 additions & 0 deletions src/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct icem {
bool rmode_lite; /**< Remote mode is Lite */
enum ice_role lrole; /**< Local role */
struct tmr tmr_pace; /**< Timer for pacing STUN requests */
struct tmr tmr_rcand; /**< Timer for remote candidate wait */
int proto; /**< Transport protocol */
int layer; /**< Protocol layer */
enum ice_checkl_state state; /**< State of the checklist */
Expand All @@ -70,6 +71,7 @@ struct icem {
ice_connchk_h *chkh; /**< Connectivity check handler */
void *arg; /**< Handler argument */
char name[32]; /**< Name of the media stream */
bool rcand_wait; /**< Waiting for remote candidate */
};

/** Defines a candidate */
Expand Down
2 changes: 2 additions & 0 deletions src/ice/icem.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ static void icem_destructor(void *data)
{
struct icem *icem = data;

tmr_cancel(&icem->tmr_rcand);
tmr_cancel(&icem->tmr_pace);
list_flush(&icem->compl);
list_flush(&icem->validl);
Expand Down Expand Up @@ -105,6 +106,7 @@ int icem_alloc(struct icem **icemp, enum ice_role role, int proto, int layer,
icem->conf = conf_default;

tmr_init(&icem->tmr_pace);
tmr_init(&icem->tmr_rcand);
list_init(&icem->lcandl);
list_init(&icem->rcandl);
list_init(&icem->checkl);
Expand Down
109 changes: 105 additions & 4 deletions src/ice/icesdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef WIN32
#include <netdb.h>
#endif

#include <string.h>
#include <re_types.h>
#include <re_fmt.h>
Expand All @@ -14,6 +18,7 @@
#include <re_net.h>
#include <re_stun.h>
#include <re_ice.h>
#include <re_main.h>
#include "ice.h"


Expand All @@ -34,6 +39,19 @@ static const char rel_addr_str[] = "raddr";
static const char rel_port_str[] = "rport";


struct rcand {
struct icem *icem;
enum ice_cand_type type;
unsigned cid;
uint32_t prio;
uint32_t port;
struct sa caddr;
struct sa rel_addr;
struct pl foundation;
char domain[128];
};


/* Encode SDP Attributes */


Expand Down Expand Up @@ -186,6 +204,62 @@ static int media_pwd_decode(struct icem *icem, const char *value)
}


static int getaddr_rcand(void *arg)
{
struct rcand *rcand = arg;
struct addrinfo *res, *res0 = NULL;
int err;

err = getaddrinfo(rcand->domain, NULL, NULL, &res0);
if (err)
return EADDRNOTAVAIL;

for (res = res0; res; res = res->ai_next) {

err = sa_set_sa(&rcand->caddr, res->ai_addr);
if (err)
continue;

break;
}

sa_set_port(&rcand->caddr, rcand->port);

freeaddrinfo(res);

return 0;
}


static void delayed_rcand(int err, void *arg)
{
struct rcand *rcand = arg;

if (err)
goto out;

/* add only if not exist */
if (icem_cand_find(&rcand->icem->rcandl, rcand->cid, &rcand->caddr))
goto out;

icem_rcand_add(rcand->icem, rcand->type, rcand->cid, rcand->prio,
&rcand->caddr, &rcand->rel_addr, &rcand->foundation);

out:
rcand->icem->rcand_wait = false;
mem_deref(rcand);
}


static void rcand_dealloc(void *arg)
{
struct rcand *rcand = arg;

mem_deref(rcand->icem);
mem_deref((char *)rcand->foundation.p);
}


static int cand_decode(struct icem *icem, const char *val)
{
struct pl foundation, compid, transp, prio, addr, port, cand_type;
Expand Down Expand Up @@ -233,18 +307,45 @@ static int cand_decode(struct icem *icem, const char *val)
}
}

(void)pl_strcpy(&cand_type, type, sizeof(type));
cid = pl_u32(&compid);

/* check for mdns .local address */
if (pl_strstr(&addr, ".local") != NULL) {
/* try non blocking getaddr mdns resolution */
icem_printf(icem, "mDNS remote cand: %r\n", &addr);
struct rcand *rcand =
mem_zalloc(sizeof(struct rcand), rcand_dealloc);
if (!rcand)
return ENOMEM;

rcand->icem = mem_ref(icem);
rcand->type = ice_cand_name2type(type);
rcand->cid = cid;
rcand->prio = pl_u32(&prio);
rcand->port = pl_u32(&port);
rcand->rel_addr = rel_addr;

pl_dup(&rcand->foundation, &foundation);
(void)pl_strcpy(&addr, rcand->domain, sizeof(rcand->domain));

icem->rcand_wait = true;

err = re_thread_async(getaddr_rcand, delayed_rcand, rcand);
if (err)
mem_deref(rcand);

return err;
}

err = sa_set(&caddr, &addr, pl_u32(&port));
if (err)
return err;

cid = pl_u32(&compid);

/* add only if not exist */
if (icem_cand_find(&icem->rcandl, cid, &caddr))
return 0;

(void)pl_strcpy(&cand_type, type, sizeof(type));

return icem_rcand_add(icem, ice_cand_name2type(type), cid,
pl_u32(&prio), &caddr, &rel_addr, &foundation);
}
Expand Down