ice: add SDP encode/decode of ICE candidate attr
This commit is contained in:
parent
48ab5ad8db
commit
4d174e571f
4 changed files with 150 additions and 4 deletions
|
@ -31,6 +31,13 @@ enum ice_cand_type {
|
||||||
ICE_CAND_TYPE_RELAY /**< Relayed candidate */
|
ICE_CAND_TYPE_RELAY /**< Relayed candidate */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** ICE TCP protocol type */
|
||||||
|
enum ice_tcptype {
|
||||||
|
ICE_TCP_ACTIVE, /**< Active TCP client */
|
||||||
|
ICE_TCP_PASSIVE, /**< Passive TCP server */
|
||||||
|
ICE_TCP_SO /**< Simultaneous-open TCP client/server */
|
||||||
|
};
|
||||||
|
|
||||||
struct ice;
|
struct ice;
|
||||||
struct icem;
|
struct icem;
|
||||||
|
|
||||||
|
@ -108,3 +115,20 @@ enum ice_cand_type ice_cand_name2type(const char *name);
|
||||||
|
|
||||||
uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
|
uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
|
||||||
uint8_t compid);
|
uint8_t compid);
|
||||||
|
|
||||||
|
|
||||||
|
/** Defines an SDP candidate attribute */
|
||||||
|
struct ice_cand_attr {
|
||||||
|
char foundation[32]; /**< Foundation string */
|
||||||
|
uint8_t compid; /**< Component ID (1-255) */
|
||||||
|
int proto; /**< Transport protocol */
|
||||||
|
uint32_t prio; /**< Priority of this candidate */
|
||||||
|
struct sa addr; /**< Transport address */
|
||||||
|
enum ice_cand_type type; /**< Candidate type */
|
||||||
|
struct sa rel_addr; /**< Related transport address (optional) */
|
||||||
|
enum ice_tcptype tcptype; /**< TCP candidate type (TCP-only) */
|
||||||
|
};
|
||||||
|
|
||||||
|
int ice_cand_attr_encode(struct re_printf *pf,
|
||||||
|
const struct ice_cand_attr *cand);
|
||||||
|
int ice_cand_attr_decode(struct ice_cand_attr *cand, const char *val);
|
||||||
|
|
|
@ -34,7 +34,7 @@ enum candpair_state {
|
||||||
|
|
||||||
enum ice_transp {
|
enum ice_transp {
|
||||||
ICE_TRANSP_NONE = -1,
|
ICE_TRANSP_NONE = -1,
|
||||||
ICE_TRANSP_UDP
|
ICE_TRANSP_UDP = IPPROTO_UDP
|
||||||
};
|
};
|
||||||
|
|
||||||
/** ICE protocol values */
|
/** ICE protocol values */
|
||||||
|
|
121
src/ice/icesdp.c
121
src/ice/icesdp.c
|
@ -11,6 +11,7 @@
|
||||||
#include <re_list.h>
|
#include <re_list.h>
|
||||||
#include <re_tmr.h>
|
#include <re_tmr.h>
|
||||||
#include <re_sa.h>
|
#include <re_sa.h>
|
||||||
|
#include <re_net.h>
|
||||||
#include <re_stun.h>
|
#include <re_stun.h>
|
||||||
#include <re_ice.h>
|
#include <re_ice.h>
|
||||||
#include "ice.h"
|
#include "ice.h"
|
||||||
|
@ -317,3 +318,123 @@ int icem_sdp_decode(struct icem *icem, const char *name, const char *value)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *ice_tcptype_name(enum ice_tcptype tcptype)
|
||||||
|
{
|
||||||
|
switch (tcptype) {
|
||||||
|
|
||||||
|
case ICE_TCP_ACTIVE: return "active";
|
||||||
|
case ICE_TCP_PASSIVE: return "passive";
|
||||||
|
case ICE_TCP_SO: return "so";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static enum ice_tcptype ice_tcptype_resolve(const struct pl *pl)
|
||||||
|
{
|
||||||
|
if (0 == pl_strcasecmp(pl, "active")) return ICE_TCP_ACTIVE;
|
||||||
|
if (0 == pl_strcasecmp(pl, "passive")) return ICE_TCP_PASSIVE;
|
||||||
|
if (0 == pl_strcasecmp(pl, "so")) return ICE_TCP_SO;
|
||||||
|
|
||||||
|
return (enum ice_tcptype)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ice_cand_attr_encode(struct re_printf *pf,
|
||||||
|
const struct ice_cand_attr *cand)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (!cand)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err |= re_hprintf(pf, "%s %u %s %u %j %u typ %s",
|
||||||
|
cand->foundation, cand->compid,
|
||||||
|
net_proto2name(cand->proto), cand->prio,
|
||||||
|
&cand->addr, sa_port(&cand->addr),
|
||||||
|
ice_cand_type2name(cand->type));
|
||||||
|
|
||||||
|
if (sa_isset(&cand->rel_addr, SA_ADDR))
|
||||||
|
err |= re_hprintf(pf, " raddr %j", &cand->rel_addr);
|
||||||
|
|
||||||
|
if (sa_isset(&cand->rel_addr, SA_PORT))
|
||||||
|
err |= re_hprintf(pf, " rport %u", sa_port(&cand->rel_addr));
|
||||||
|
|
||||||
|
if (cand->proto == IPPROTO_TCP) {
|
||||||
|
err |= re_hprintf(pf, " tcptype %s",
|
||||||
|
ice_tcptype_name(cand->tcptype));
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ice_cand_attr_decode(struct ice_cand_attr *cand, const char *val)
|
||||||
|
{
|
||||||
|
struct pl pl_fnd, pl_compid, pl_transp, pl_prio, pl_addr, pl_port;
|
||||||
|
struct pl pl_type, pl_raddr, pl_rport, pl_opt = PL_INIT;
|
||||||
|
size_t len;
|
||||||
|
char type[8];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!cand || !val)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
memset(cand, 0, sizeof(*cand));
|
||||||
|
|
||||||
|
len = str_len(val);
|
||||||
|
|
||||||
|
err = re_regex(val, len,
|
||||||
|
"[^ ]+ [0-9]+ [a-z]+ [0-9]+ [^ ]+ [0-9]+ typ [a-z]+"
|
||||||
|
"[^]*",
|
||||||
|
&pl_fnd, &pl_compid, &pl_transp, &pl_prio,
|
||||||
|
&pl_addr, &pl_port, &pl_type, &pl_opt);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
(void)pl_strcpy(&pl_fnd, cand->foundation, sizeof(cand->foundation));
|
||||||
|
|
||||||
|
if (0 == pl_strcasecmp(&pl_transp, "UDP"))
|
||||||
|
cand->proto = IPPROTO_UDP;
|
||||||
|
else if (0 == pl_strcasecmp(&pl_transp, "TCP"))
|
||||||
|
cand->proto = IPPROTO_TCP;
|
||||||
|
else
|
||||||
|
cand->proto = 0;
|
||||||
|
|
||||||
|
err = sa_set(&cand->addr, &pl_addr, pl_u32(&pl_port));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
cand->compid = pl_u32(&pl_compid);
|
||||||
|
cand->prio = pl_u32(&pl_prio);
|
||||||
|
|
||||||
|
(void)pl_strcpy(&pl_type, type, sizeof(type));
|
||||||
|
|
||||||
|
cand->type = ice_cand_name2type(type);
|
||||||
|
|
||||||
|
/* optional */
|
||||||
|
|
||||||
|
if (0 == re_regex(pl_opt.p, pl_opt.l, "raddr [^ ]+ rport [0-9]+",
|
||||||
|
&pl_raddr, &pl_rport)) {
|
||||||
|
|
||||||
|
err = sa_set(&cand->rel_addr, &pl_raddr, pl_u32(&pl_rport));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cand->proto == IPPROTO_TCP) {
|
||||||
|
|
||||||
|
struct pl tcptype;
|
||||||
|
|
||||||
|
err = re_regex(pl_opt.p, pl_opt.l, "tcptype [^ ]+",
|
||||||
|
&tcptype);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
cand->tcptype = ice_tcptype_resolve(&tcptype);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int type_prio(enum ice_cand_type type)
|
static uint32_t type_prio(enum ice_cand_type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ static int type_prio(enum ice_cand_type type)
|
||||||
uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
|
uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
|
||||||
uint8_t compid)
|
uint8_t compid)
|
||||||
{
|
{
|
||||||
return (uint32_t)type_prio(type)<<24 | local<<8 | (256 - compid);
|
return type_prio(type)<<24 | (uint32_t)local<<8 | (256 - compid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,8 +66,9 @@ uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
|
||||||
uint64_t ice_calc_pair_prio(uint32_t g, uint32_t d)
|
uint64_t ice_calc_pair_prio(uint32_t g, uint32_t d)
|
||||||
{
|
{
|
||||||
const uint64_t m = min(g, d);
|
const uint64_t m = min(g, d);
|
||||||
|
const uint64_t x = max(g, d);
|
||||||
|
|
||||||
return (m<<32) + 2*max(g, d) + (g>d?1:0);
|
return (m<<32) + 2*x + (g>d?1:0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue