adding rtp/savpf transforms and tests

git.mgm/mediaproxy-ng/github/master
Richard Fuchs 13 years ago
parent 1f20801856
commit 3c9daae60d

@ -234,6 +234,30 @@ static int call_savp2avp_rtp(str *s, struct streamrelay *r) {
static int call_savp2avp_rtcp(str *s, struct streamrelay *r) { static int call_savp2avp_rtcp(str *s, struct streamrelay *r) {
return rtcp_savp2avp(s, &r->other->crypto.in); return rtcp_savp2avp(s, &r->other->crypto.in);
} }
static int call_avpf2savp_rtcp(str *s, struct streamrelay *r) {
int ret;
ret = rtcp_avpf2avp(s);
if (ret)
return ret;
return rtcp_avp2savp(s, &r->crypto.out);
}
static int call_savpf2avp_rtcp(str *s, struct streamrelay *r) {
int ret;
ret = rtcp_savp2avp(s, &r->other->crypto.in);
if (ret)
return ret;
return rtcp_avpf2avp(s);
}
static int call_savpf2savp_rtcp(str *s, struct streamrelay *r) {
int ret;
ret = rtcp_savp2avp(s, &r->other->crypto.in);
if (ret)
return ret;
ret = rtcp_avpf2avp(s);
if (ret)
return ret;
return rtcp_avp2savp(s, &r->crypto.out);
}
static stream_handler determine_handler(struct streamrelay *in) { static stream_handler determine_handler(struct streamrelay *in) {
@ -252,6 +276,7 @@ static stream_handler determine_handler(struct streamrelay *in) {
goto dummy; goto dummy;
case PROTO_RTP_SAVP: case PROTO_RTP_SAVP:
case PROTO_RTP_SAVPF:
return in->rtcp ? call_avp2savp_rtcp return in->rtcp ? call_avp2savp_rtcp
: call_avp2savp_rtp; : call_avp2savp_rtp;
@ -266,6 +291,9 @@ static stream_handler determine_handler(struct streamrelay *in) {
return in->rtcp ? call_savp2avp_rtcp return in->rtcp ? call_savp2avp_rtcp
: call_savp2avp_rtp; : call_savp2avp_rtp;
case PROTO_RTP_SAVPF:
goto dummy;
default: default:
abort(); abort();
} }
@ -277,6 +305,32 @@ static stream_handler determine_handler(struct streamrelay *in) {
goto dummy; goto dummy;
return call_avpf2avp; return call_avpf2avp;
case PROTO_RTP_SAVP:
return in->rtcp ? call_avpf2savp_rtcp
: call_avp2savp_rtp;
case PROTO_RTP_SAVPF:
return in->rtcp ? call_avp2savp_rtcp
: call_avp2savp_rtp;
default:
abort();
}
case PROTO_RTP_SAVPF:
switch (in->peer_advertised.protocol) {
case PROTO_RTP_AVP:
return in->rtcp ? call_savpf2avp_rtcp
: call_savp2avp_rtp;
case PROTO_RTP_AVPF:
return in->rtcp ? call_savp2avp_rtcp
: call_savp2avp_rtp;
case PROTO_RTP_SAVP:
if (!in->rtcp)
goto dummy;
return call_savpf2savp_rtcp;
default: default:
abort(); abort();
} }

@ -335,7 +335,7 @@ static inline int check_session_keys(struct crypto_context *c) {
return 0; return 0;
error: error:
mylog(LOG_ERROR, "Error generating SRTP session keys"); mylog(LOG_ERROR, "Error generating SRTCP session keys");
return -1; return -1;
} }

@ -1258,7 +1258,7 @@ static int generate_crypto(struct sdp_media *media, struct sdp_ng_flags *flags,
struct sdp_chopper *chop) struct sdp_chopper *chop)
{ {
int id; int id;
struct crypto_context *c; struct crypto_context *c, *src = NULL;
char b64_buf[64]; char b64_buf[64];
char *p; char *p;
int state = 0, save = 0; int state = 0, save = 0;
@ -1268,8 +1268,25 @@ static int generate_crypto(struct sdp_media *media, struct sdp_ng_flags *flags,
return 0; return 0;
id = ATTR_CRYPTO; id = ATTR_CRYPTO;
if (g_hash_table_lookup(media->attributes.id_hash, &id)) if (g_hash_table_lookup(media->attributes.id_hash, &id)) {
/* SRTP <> SRTP case, copy from other stream
* and leave SDP untouched */
src = &rtp->other->crypto.in;
mutex_lock(&rtp->up->up->lock);
c = &rtp->crypto.out;
if (!c->crypto_suite)
*c = *src;
mutex_unlock(&rtp->up->up->lock);
mutex_lock(&rtcp->up->up->lock);
c = &rtcp->crypto.out;
if (!c->crypto_suite)
*c = *src;
mutex_unlock(&rtcp->up->up->lock);
return 0; return 0;
}
mutex_lock(&rtp->up->up->lock); mutex_lock(&rtp->up->up->lock);

@ -266,6 +266,7 @@ sub rtcp_avp {
my $sr = rtcp_sr(); my $sr = rtcp_sr();
my $exp = $sr; my $exp = $sr;
$$recv{name} eq 'RTP/SAVP' and $exp = rtcp_encrypt($sr, $ctx_o, 'in'); $$recv{name} eq 'RTP/SAVP' and $exp = rtcp_encrypt($sr, $ctx_o, 'in');
$$recv{name} eq 'RTP/SAVPF' and $exp = rtcp_encrypt($sr, $ctx_o, 'in');
return ($sr, $exp); return ($sr, $exp);
} }
@ -275,6 +276,7 @@ sub rtcp_savp {
my $enc = rtcp_encrypt($sr, $ctx, 'out'); my $enc = rtcp_encrypt($sr, $ctx, 'out');
my $exp = $enc; my $exp = $enc;
$$recv{name} eq 'RTP/AVP' and $exp = $sr; $$recv{name} eq 'RTP/AVP' and $exp = $sr;
$$recv{name} eq 'RTP/AVPF' and $exp = $sr;
return ($enc, $exp); return ($enc, $exp);
} }
@ -284,9 +286,23 @@ sub rtcp_avpf {
my $fb = rtcp_rtpfb(); my $fb = rtcp_rtpfb();
my $exp = $sr; my $exp = $sr;
$$recv{name} eq 'RTP/AVPF' and $exp .= $fb; $$recv{name} eq 'RTP/AVPF' and $exp .= $fb;
$$recv{name} eq 'RTP/SAVP' and $exp = rtcp_encrypt($sr, $ctx_o, 'in');
$$recv{name} eq 'RTP/SAVPF' and $exp = rtcp_encrypt($sr . $fb, $ctx_o, 'in');
return ($sr . $fb, $exp); return ($sr . $fb, $exp);
} }
sub rtcp_savpf {
my ($recv, $ctx, $ctx_o) = @_;
my $sr = rtcp_sr();
my $fb = rtcp_rtpfb();
my $enc = rtcp_encrypt($sr . $fb, $ctx, 'out');
my $exp = $enc;
$$recv{name} eq 'RTP/AVP' and $exp = $sr;
$$recv{name} eq 'RTP/AVPF' and $exp = $sr . $fb;
$$recv{name} eq 'RTP/SAVP' and $exp = rtcp_encrypt($sr, $ctx_o, 'in');
return ($enc, $exp);
}
sub rtp { sub rtp {
my ($ctx) = @_; my ($ctx) = @_;
my $seq = $$ctx{rtp_seqnum} || (int(rand(0xfffff)) + 1); my $seq = $$ctx{rtp_seqnum} || (int(rand(0xfffff)) + 1);
@ -301,6 +317,7 @@ sub rtp_avp {
my $pack = rtp($ctx); my $pack = rtp($ctx);
my $exp = $pack; my $exp = $pack;
$$recv{name} eq 'RTP/SAVP' and $exp = rtp_encrypt($pack, $ctx_o, 'in'); $$recv{name} eq 'RTP/SAVP' and $exp = rtp_encrypt($pack, $ctx_o, 'in');
$$recv{name} eq 'RTP/SAVPF' and $exp = rtp_encrypt($pack, $ctx_o, 'in');
return ($pack, $exp); return ($pack, $exp);
} }
@ -310,6 +327,7 @@ sub rtp_savp {
my $enc = rtp_encrypt($pack, $ctx, 'out'); my $enc = rtp_encrypt($pack, $ctx, 'out');
my $exp = $enc; my $exp = $enc;
$$recv{name} eq 'RTP/AVP' and $exp = $pack; $$recv{name} eq 'RTP/AVP' and $exp = $pack;
$$recv{name} eq 'RTP/AVPF' and $exp = $pack;
return ($enc, $exp); return ($enc, $exp);
} }
@ -353,12 +371,12 @@ sub do_rtp {
warn("no rtp reply received, ports $$outputs[$b][$j][0] and $$outputs[$a][$j][0]"); warn("no rtp reply received, ports $$outputs[$b][$j][0] and $$outputs[$a][$j][0]");
$KEEPGOING or undef($c); $KEEPGOING or undef($c);
} }
$repl eq $expect or die hexdump($repl, $expect); $repl eq $expect or die hexdump($repl, $expect) . " $$trans[$a]{name} > $$trans[$b]{name}";
($payload, $expect) = $$trans[$a]{rtcp_func}($$trans[$b], $tcx, $tcx_o); ($payload, $expect) = $$trans[$a]{rtcp_func}($$trans[$b], $tcx, $tcx_o);
$dst = $$pr{sockaddr}($$outputs[$b][$j][0] + 1, $addr); $dst = $$pr{sockaddr}($$outputs[$b][$j][0] + 1, $addr);
$repl = send_receive($$cfds[$a][$j], $$cfds[$b][$j], $payload, $dst); $repl = send_receive($$cfds[$a][$j], $$cfds[$b][$j], $payload, $dst);
$repl eq $expect or die hexdump($repl, $expect); $repl eq $expect or die hexdump($repl, $expect) . " $$trans[$a]{name} > $$trans[$b]{name}";
} }
} }
} }
@ -395,11 +413,11 @@ my @transports = (
rtp_func => \&rtp_avp, rtp_func => \&rtp_avp,
rtcp_func => \&rtcp_avp, rtcp_func => \&rtcp_avp,
}, },
# { {
# name => 'RTP/AVPF', name => 'RTP/AVPF',
# rtp_func => &rtp_avpf, rtp_func => \&rtp_avp,
# rtcp_func => \&rtcp_avpf, rtcp_func => \&rtcp_avpf,
# }, },
{ {
name => 'RTP/SAVP', name => 'RTP/SAVP',
sdp_media_params => \&savp_sdp, sdp_media_params => \&savp_sdp,
@ -407,6 +425,13 @@ my @transports = (
rtp_func => \&rtp_savp, rtp_func => \&rtp_savp,
rtcp_func => \&rtcp_savp, rtcp_func => \&rtcp_savp,
}, },
{
name => 'RTP/SAVPF',
sdp_media_params => \&savp_sdp,
sdp_parse_func => \&savp_crypto,
rtp_func => \&rtp_savp,
rtcp_func => \&rtcp_savpf,
},
); );
sub callid { sub callid {

Loading…
Cancel
Save