implement experimental passthrough relay mode

pull/6/head
Richard Fuchs 12 years ago
parent b132d8089b
commit aa5bae9777

@ -441,6 +441,8 @@ static void determine_handler(struct packet_stream *in, const struct packet_stre
if (PS_ISSET(in, HAS_HANDLER))
return;
if (MEDIA_ISSET(in->media, PASSTHRU))
goto noop;
if (!in->media->protocol)
goto err;
@ -465,6 +467,7 @@ done:
err:
ilog(LOG_WARNING, "Unknown transport protocol encountered");
noop:
in->handler = &__sh_noop;
goto done;
}
@ -1566,6 +1569,29 @@ static int __init_streams(struct call_media *A, struct call_media *B, const stru
return 0;
}
static void __ice_offer(const struct sdp_ng_flags *flags, struct call_media *this,
struct call_media *other)
{
if (!flags)
return;
/* we offer ICE by default */
if (flags->opmode == OP_OFFER) {
if (!MEDIA_ISSET(this, INITIALIZED))
MEDIA_SET(this, ICE);
}
if (flags->ice_remove)
MEDIA_CLEAR(this, ICE);
/* special case: if doing ICE on both sides and ice_force is not set, we cannot
* be sure that media will pass through us, so we have to disable certain features */
if (MEDIA_ISSET(this, ICE) && MEDIA_ISSET(other, ICE) && !flags->ice_force) {
ilog(LOG_DEBUG, "enabling passthrough mode");
MEDIA_SET(this, PASSTHRU);
MEDIA_SET(other, PASSTHRU);
}
}
/* generates SDES parametes for outgoing SDP, which is our media "out" direction */
static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_media *this,
struct call_media *other)
@ -1576,7 +1602,7 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi
if (!flags)
return;
if (!this->protocol || !this->protocol->srtp) {
if (!this->protocol || !this->protocol->srtp || MEDIA_ISSET(this, PASSTHRU)) {
cp->crypto_suite = NULL;
MEDIA_CLEAR(this, DTLS);
MEDIA_CLEAR(this, SDES);
@ -1764,7 +1790,7 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
/* copy parameters advertised by the sender of this message */
bf_copy_same(&other_media->media_flags, &sp->sp_flags,
SP_FLAG_RTCP_MUX | SP_FLAG_ASYMMETRIC);
SHARED_FLAG_RTCP_MUX | SHARED_FLAG_ASYMMETRIC | SHARED_FLAG_ICE);
crypto_params_copy(&other_media->sdes_in.params, &sp->crypto);
other_media->sdes_in.tag = sp->sdes_tag;
@ -1789,6 +1815,9 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
&& other_media->fingerprint.hash_func)
MEDIA_SET(other_media, DTLS);
/* ICE negotiation */
__ice_offer(flags, media, other_media);
/* control rtcp-mux */
__rtcp_mux_logic(flags, media, other_media);

@ -76,6 +76,7 @@ struct call_monologue;
#define SHARED_FLAG_RTCP_MUX 0x00000010
#define SHARED_FLAG_SETUP_ACTIVE 0x00000020
#define SHARED_FLAG_SETUP_PASSIVE 0x00000040
#define SHARED_FLAG_ICE 0x00000080
/* struct stream_params */
#define SP_FLAG_NO_RTCP 0x00010000
@ -86,6 +87,7 @@ struct call_monologue;
#define SP_FLAG_ASYMMETRIC SHARED_FLAG_ASYMMETRIC
#define SP_FLAG_SETUP_ACTIVE SHARED_FLAG_SETUP_ACTIVE
#define SP_FLAG_SETUP_PASSIVE SHARED_FLAG_SETUP_PASSIVE
#define SP_FLAG_ICE SHARED_FLAG_ICE
/* struct packet_stream */
#define PS_FLAG_RTP 0x00010000
@ -112,6 +114,7 @@ struct call_monologue;
#define MEDIA_FLAG_SETUP_ACTIVE SHARED_FLAG_SETUP_ACTIVE
#define MEDIA_FLAG_SETUP_PASSIVE SHARED_FLAG_SETUP_PASSIVE
#define MEDIA_FLAG_PASSTHRU 0x00100000
#define MEDIA_FLAG_ICE SHARED_FLAG_ICE
/* access macros */
#define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f)

@ -1031,6 +1031,10 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
sp->fingerprint.hash_func->num_bytes);
}
/* a=candidate */
if (attr_get_by_id(&media->attributes, ATTR_CANDIDATE))
SP_SET(sp, ICE);
/* determine RTCP endpoint */
if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX)) {
@ -1356,23 +1360,31 @@ static int process_media_attributes(struct sdp_chopper *chop, struct sdp_media *
case ATTR_ICE:
case ATTR_ICE_UFRAG:
case ATTR_CANDIDATE:
if (MEDIA_ISSET(media, PASSTHRU))
break;
if (!flags->ice_remove && !flags->ice_force)
break;
goto strip;
case ATTR_RTCP:
case ATTR_RTCP_MUX:
case ATTR_EXTMAP:
case ATTR_CRYPTO:
case ATTR_INACTIVE:
case ATTR_SENDONLY:
case ATTR_RECVONLY:
case ATTR_SENDRECV:
goto strip;
case ATTR_EXTMAP:
case ATTR_CRYPTO:
case ATTR_FINGERPRINT:
case ATTR_SETUP:
if (MEDIA_ISSET(media, PASSTHRU))
break;
goto strip;
case ATTR_MID:
if (MEDIA_ISSET(media, PASSTHRU))
break;
a = attr_get_by_id(&sdp->session->attributes, ATTR_GROUP);
if (a && a->u.group.semantics == GROUP_BUNDLE)
goto strip;
@ -1499,7 +1511,7 @@ static void insert_dtls(struct call_media *media, struct sdp_chopper *chop) {
const char *actpass;
struct call *call = media->call;
if (!call->dtls_cert || !MEDIA_ISSET(media, DTLS))
if (!call->dtls_cert || !MEDIA_ISSET(media, DTLS) || MEDIA_ISSET(media, PASSTHRU))
return;
hf = call->dtls_cert->fingerprint.hash_func;
@ -1538,7 +1550,7 @@ static void insert_crypto(struct call_media *media, struct sdp_chopper *chop) {
struct crypto_params *cp = &media->sdes_out.params;
unsigned long long ull;
if (!cp->crypto_suite || !MEDIA_ISSET(media, SDES))
if (!cp->crypto_suite || !MEDIA_ISSET(media, SDES) || MEDIA_ISSET(media, PASSTHRU))
return;
p = b64_buf;
@ -1616,12 +1628,14 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
goto error;
}
if (process_session_attributes(chop, &session->attributes, flags))
goto error;
if (!MEDIA_ISSET(call_media, PASSTHRU)) {
if (process_session_attributes(chop, &session->attributes, flags))
goto error;
if (do_ice) {
copy_up_to_end_of(chop, &session->s);
chopper_append_c(chop, "a=ice-lite\r\n");
if (do_ice) {
copy_up_to_end_of(chop, &session->s);
chopper_append_c(chop, "a=ice-lite\r\n");
}
}
media_index = 1;
@ -1696,7 +1710,7 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
insert_crypto(call_media, chop);
insert_dtls(call_media, chop);
if (do_ice) {
if (do_ice && !MEDIA_ISSET(call_media, PASSTHRU)) {
if (!call_media->ice_ufrag.s) {
create_random_ice_string(call, &call_media->ice_ufrag, 8);
create_random_ice_string(call, &call_media->ice_pwd, 28);

Loading…
Cancel
Save