-
Notifications
You must be signed in to change notification settings - Fork 84
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
3,961 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/** | ||
* @file re_ice.h Interface to Interactive Connectivity Establishment (ICE) | ||
* | ||
* Copyright (C) 2010 Alfred E. Heggestad | ||
*/ | ||
|
||
|
||
/** ICE Configuration */ | ||
struct trice_conf { | ||
bool debug; /**< Enable ICE debugging */ | ||
bool trace; /**< Enable tracing of Connectivity | ||
checks */ | ||
bool ansi; /**< Enable ANSI colors for debug | ||
output */ | ||
bool enable_prflx; /**< Enable Peer-Reflexive candidates */ | ||
bool optimize_loopback_pairing;/**< Reduce candidate pairs when | ||
using loopback addresses */ | ||
}; | ||
|
||
struct trice; | ||
struct ice_lcand; | ||
struct ice_candpair; | ||
struct stun_conf; | ||
|
||
|
||
typedef bool (ice_cand_recv_h)(struct ice_lcand *lcand, | ||
int proto, void *sock, const struct sa *src, | ||
struct mbuf *mb, void *arg); | ||
|
||
|
||
/** Local candidate */ | ||
struct ice_lcand { | ||
struct ice_cand_attr attr; /**< Base class (inheritance) */ | ||
struct le le; /**< List element */ | ||
|
||
/* Base-address only set for SRFLX, PRFLX, RELAY */ | ||
struct sa base_addr; /* IP-address of "base" candidate (optional) */ | ||
|
||
struct udp_sock *us; | ||
struct udp_helper *uh; | ||
struct tcp_sock *ts; /* TCP for simultaneous-open or passive. */ | ||
char ifname[32]; /**< Network interface, for diagnostics */ | ||
int layer; | ||
ice_cand_recv_h *recvh; | ||
void *arg; | ||
|
||
// todo: remove | ||
struct trice *icem; /* parent */ | ||
|
||
struct { | ||
size_t n_tx; | ||
size_t n_rx; | ||
} stats; | ||
}; | ||
|
||
/** Remote candidate */ | ||
struct ice_rcand { | ||
struct ice_cand_attr attr; /**< Base class (inheritance) */ | ||
struct le le; /**< List element */ | ||
}; | ||
|
||
|
||
/** Defines a candidate pair */ | ||
struct ice_candpair { | ||
struct le le; /**< List element */ | ||
struct ice_lcand *lcand; /**< Local candidate */ | ||
struct ice_rcand *rcand; /**< Remote candidate */ | ||
enum ice_candpair_state state;/**< Candidate pair state */ | ||
uint64_t pprio; /**< Pair priority */ | ||
//bool def; /**< Default flag */ | ||
bool valid; /**< Valid flag */ | ||
bool nominated; /**< Nominated flag */ | ||
bool estab; | ||
bool trigged; | ||
int err; /**< Saved error code, if failed */ | ||
uint16_t scode; /**< Saved STUN code, if failed */ | ||
|
||
struct tcp_conn *tc; | ||
|
||
struct ice_tcpconn *conn; /* the TCP-connection used */ | ||
}; | ||
|
||
|
||
typedef void (trice_estab_h)(struct ice_candpair *pair, | ||
const struct stun_msg *msg, void *arg); | ||
|
||
|
||
typedef void (trice_failed_h)(int err, uint16_t scode, | ||
struct ice_candpair *pair, void *arg); | ||
|
||
|
||
int trice_alloc(struct trice **icemp, const struct trice_conf *conf, | ||
enum ice_role role, const char *lufrag, const char *lpwd); | ||
int trice_set_remote_ufrag(struct trice *icem, const char *rufrag); | ||
int trice_set_remote_pwd(struct trice *icem, const char *rpwd); | ||
int trice_set_software(struct trice *icem, const char *sw); | ||
int trice_set_role(struct trice *trice, enum ice_role role); | ||
enum ice_role trice_local_role(const struct trice *icem); | ||
int trice_debug(struct re_printf *pf, const struct trice *icem); | ||
struct trice_conf *trice_conf(struct trice *icem); | ||
|
||
|
||
/* Candidates (common) */ | ||
int trice_cand_print(struct re_printf *pf, const struct ice_cand_attr *cand); | ||
enum ice_tcptype ice_tcptype_reverse(enum ice_tcptype type); | ||
const char *ice_tcptype_name(enum ice_tcptype tcptype); | ||
enum ice_cand_type ice_cand_type_base(enum ice_cand_type type); | ||
|
||
|
||
/* Local candidates */ | ||
int trice_lcand_add(struct ice_lcand **lcandp, struct trice *icem, | ||
unsigned compid, int proto, uint32_t prio, | ||
const struct sa *addr, const struct sa *base_addr, | ||
enum ice_cand_type type, const struct sa *rel_addr, | ||
enum ice_tcptype tcptype, | ||
void *sock, int layer); | ||
struct list *trice_lcandl(const struct trice *icem); | ||
struct ice_lcand *trice_lcand_find(struct trice *icem, | ||
enum ice_cand_type type, | ||
unsigned compid, int proto, | ||
const struct sa *addr); | ||
struct ice_lcand *trice_lcand_find2(const struct trice *icem, | ||
enum ice_cand_type type, int af); | ||
void *trice_lcand_sock(struct trice *icem, const struct ice_lcand *lcand); | ||
void trice_lcand_recv_packet(struct ice_lcand *lcand, | ||
const struct sa *src, struct mbuf *mb); | ||
|
||
|
||
/* Remote candidate */ | ||
struct list *trice_rcandl(const struct trice *icem); | ||
int trice_rcand_add(struct ice_rcand **rcandp, struct trice *icem, | ||
unsigned compid, const char *foundation, int proto, | ||
uint32_t prio, const struct sa *addr, | ||
enum ice_cand_type type, enum ice_tcptype tcptype); | ||
struct ice_rcand *trice_rcand_find(struct trice *icem, unsigned compid, | ||
int proto, const struct sa *addr); | ||
|
||
|
||
/* ICE Candidate pairs */ | ||
struct list *trice_checkl(const struct trice *icem); | ||
struct list *trice_validl(const struct trice *icem); | ||
struct ice_candpair *trice_candpair_find_state(const struct list *lst, | ||
enum ice_candpair_state state); | ||
int trice_candpair_debug(struct re_printf *pf, const struct ice_candpair *cp); | ||
int trice_candpairs_debug(struct re_printf *pf, bool ansi_output, | ||
const struct list *list); | ||
|
||
|
||
/* ICE checklist */ | ||
void trice_checklist_set_waiting(struct trice *icem); | ||
int trice_checklist_start(struct trice *icem, struct stun *stun, | ||
uint32_t interval, | ||
trice_estab_h *estabh, trice_failed_h *failh, | ||
void *arg); | ||
void trice_checklist_stop(struct trice *icem); | ||
bool trice_checklist_isrunning(const struct trice *icem); | ||
bool trice_checklist_iscompleted(const struct trice *icem); | ||
|
||
|
||
/* ICE Conncheck */ | ||
int trice_conncheck_send(struct trice *icem, struct ice_candpair *pair, | ||
bool use_cand); | ||
|
||
/* Port range */ | ||
int trice_set_port_range(struct trice *trice, | ||
uint16_t min_port, uint16_t max_port); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
ICE-NOTES: | ||
--------- | ||
|
||
|
||
|
||
---------------------------------- | ||
Application layer: | ||
|
||
- Can handle any modes (Full, Ice, Trickle) | ||
- Can implement any nomination-type (regular, aggressive) | ||
- Can encode/decode SDP attributes | ||
- Must gather all candidates (including STUN/TURN servers) | ||
- Application can choose the Default Local Candidate | ||
- Application can choose the Default Remote Candidate | ||
- Can measure RTT end-to-end | ||
- Can apply a STUN consent timer on top of ICE | ||
- the application should have the freedom to choose any selected candidate-pair | ||
- can install Keep-Alive timer (Binding Indication) for any pairs | ||
- can install a consent timer for any pair | ||
|
||
|
||
---------------------------------- | ||
ICE layer: | ||
|
||
- All modes (Full-ICE and Trickle-ICE) are implemented | ||
- ICE-lite is NOT supported | ||
- agnostic to modes (Full, Trickle) | ||
- agnostic to nomination-type (regular, aggressive) | ||
- SDP encoding and decoding of ICE-relavant attributes | ||
- can handle between 1 and 2 components per media-stream | ||
- gathering: No candidate gathering, must be done in App | ||
- agnostic to transport protocol (should handle both UDP and TCP) | ||
- rel-addr (related address) is supported, but it is not used in the logic | ||
- ICE-stack does not choose the Default Local Candidate | ||
- ICE-stack does not choose the Default Remote Candidate | ||
- no TURN client | ||
- Each local candidate can have its own listen address/port. Yes | ||
- Support for UDP-transport | ||
- Support for TCP-transport | ||
- Support for IPv4 and IPv6 | ||
- modular design with building blocks. | ||
- check all components before calling estabh ? no. | ||
- no support for "default" candidate/candidate-pair | ||
- component object: NO | ||
- selected pair: NO | ||
- must be able to support custom UDP/TCP-transport via helpers | ||
|
||
|
||
---------------------------------- | ||
Interop: | ||
|
||
OK - Firefox 31.0 | ||
OK - Firefox 35.0 | ||
OK - Firefox 36.0 | ||
OK - Chrome 41 | ||
OK - Chrome 58 | ||
|
||
|
||
TODO: | ||
|
||
done - remove ICE-lite mode | ||
done - remove rel-addr from ICE-code | ||
done - interop testing with Chrome | ||
done - interop testing with Firefox - seems to be working with 31.0 | ||
done - Firefox: test with trickling candidates over Websock | ||
done - add support for TCP-candidates (test with Chrome) | ||
done - make a new test-client (reicec) and test on a public server | ||
done - do we need to support LITE at all? No. | ||
done - split EOC flag into local_eoc and remote_eoc | ||
done - send trigged request from stunsrv | ||
done - new module "icesdp" for SDP encoding/decoding | ||
done - add a new module "shim" (RFC 4571) | ||
- ICE module should be Conncheck-only, no data-transport | ||
- test_ice_tcp: S-O not working on Linux | ||
done - check when adding PRFLX that EOC-flag is set/unset (not needed) | ||
done - move use_cand flag to checklist_start/send_conncheck ? | ||
- verify that APP can grab udp/tcp-sock | ||
- consider moving pacing-logic to application? | ||
|
||
|
||
|
||
|
||
Architecture Diagram: | ||
-------------------- | ||
|
||
|
||
|
||
``` | ||
.-------. .-------. | ||
| App | | App | | ||
'-------' '-------' | ||
| | \ | ||
| .--------. | | | ||
+--------+ STUN +--------+ | | ||
| '--------' | | "ICE-layer" | ||
| .-------. | | ||
| | SHIM | | | ||
| '-------' | | ||
| | / | ||
.-------. .-------. | ||
| UDP | | TCP | | ||
'-------' '-------' | ||
| | | ||
! ! | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/** | ||
* @file cand.c Common ICE Candidates | ||
* | ||
* Copyright (C) 2010 Alfred E. Heggestad | ||
*/ | ||
#include <string.h> | ||
#include <re_types.h> | ||
#include <re_fmt.h> | ||
#include <re_mem.h> | ||
#include <re_mbuf.h> | ||
#include <re_list.h> | ||
#include <re_tmr.h> | ||
#include <re_sa.h> | ||
#include <re_net.h> | ||
#include <re_sys.h> | ||
#include <re_stun.h> | ||
#include <re_udp.h> | ||
#include <re_tcp.h> | ||
#include <re_ice.h> | ||
#include <re_trice.h> | ||
#include "trice.h" | ||
|
||
|
||
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 "???"; | ||
} | ||
} | ||
|
||
|
||
/* | ||
Local Remote | ||
Candidate Candidate | ||
--------------------------- | ||
tcp-so tcp-so | ||
tcp-active tcp-passive | ||
tcp-passive tcp-active | ||
*/ | ||
enum ice_tcptype ice_tcptype_reverse(enum ice_tcptype type) | ||
{ | ||
switch (type) { | ||
|
||
case ICE_TCP_SO: return ICE_TCP_SO; | ||
case ICE_TCP_ACTIVE: return ICE_TCP_PASSIVE; | ||
case ICE_TCP_PASSIVE: return ICE_TCP_ACTIVE; | ||
default: return (enum ice_tcptype)-1; | ||
} | ||
} | ||
|
||
|
||
enum ice_cand_type ice_cand_type_base(enum ice_cand_type type) | ||
{ | ||
switch (type) { | ||
|
||
case ICE_CAND_TYPE_HOST: return ICE_CAND_TYPE_HOST; | ||
case ICE_CAND_TYPE_SRFLX: return ICE_CAND_TYPE_HOST; | ||
case ICE_CAND_TYPE_PRFLX: return ICE_CAND_TYPE_HOST; | ||
case ICE_CAND_TYPE_RELAY: return ICE_CAND_TYPE_RELAY; | ||
default: return type; | ||
} | ||
} | ||
|
||
|
||
int trice_cand_print(struct re_printf *pf, const struct ice_cand_attr *cand) | ||
{ | ||
int err = 0; | ||
|
||
if (!cand) | ||
return 0; | ||
|
||
err |= re_hprintf(pf, "%s|%s", ice_cand_type2name(cand->type), | ||
net_proto2name(cand->proto)); | ||
|
||
if (cand->proto == IPPROTO_TCP) { | ||
|
||
err |= re_hprintf(pf, ".%s", ice_tcptype_name(cand->tcptype)); | ||
} | ||
|
||
err |= re_hprintf(pf, "|%J", &cand->addr); | ||
|
||
return err; | ||
} |
Oops, something went wrong.