Browse Source

MT#56521 support offering legacy non-RFC OSRTP

Change-Id: I65990fd43015f7827f74722741ddae724f3a7642
pull/1614/head
Richard Fuchs 3 years ago
parent
commit
817d9b9875
5 changed files with 207 additions and 29 deletions
  1. +16
    -4
      README.md
  2. +5
    -0
      daemon/call_interfaces.c
  3. +57
    -25
      daemon/sdp.c
  4. +1
    -0
      include/call_interfaces.h
  5. +128
    -0
      t/auto-daemon-tests.pl

+ 16
- 4
README.md View File

@ -986,10 +986,22 @@ Optionally included keys are:
Similar to `SDES` but controls OSRTP behaviour. Default behaviour is to pass through
OSRTP negotiations. Supported options:
- `offer`
When processing a non-OSRTP offer, convert it to an OSRTP offer. Will result
in RTP/SRTP transcoding if the OSRTP offer is accepted.
- `offer` or `offer-RFC`
When processing a non-OSRTP offer, convert it to an OSRTP offer. Will
result in RTP/SRTP transcoding if the OSRTP offer is accepted. The
transport protocol should be a non-SRTP (plain RTP) protocol such as
RTP/AVP.
- `offer-legacy`
Convert a regular offer to a legacy, non-RFC "best effort" SRTP offer,
which involves duplicating each SDP media section in the output,
advertised once as plain RTP and once as SRTP. The transport protocol
should be set to an SRTP protocol such as RTP/SAVP. To enable full
interoperability with endpoints which support this usage, the flag
`accept-legacy` (see below) should also be given in all signalling
exchanges.
- `accept-RFC`


+ 5
- 0
daemon/call_interfaces.c View File

@ -591,7 +591,12 @@ INLINE void ng_osrtp_option(struct sdp_ng_flags *out, str *s, void *dummy) {
out->osrtp_accept_rfc = 1;
out->osrtp_accept_legacy = 1;
break;
case CSH_LOOKUP("offer-legacy"):
out->osrtp_offer_legacy = 1;
break;
case CSH_LOOKUP("offer"):
case CSH_LOOKUP("offer-RFC"):
case CSH_LOOKUP("offer-rfc"):
out->osrtp_offer = 1;
break;
default:


+ 57
- 25
daemon/sdp.c View File

@ -1558,38 +1558,39 @@ static void sp_free(void *p) {
// associating offer/answer media sections directly with each other, instead of requiring
// the indexing to be in order and instead of requiring all sections between monologue and sdp_media
// lists to be matching.
static void legacy_osrtp_accept(struct stream_params *sp, GQueue *streams, GList *media_link,
// returns: discard this `sp` yes/no
static bool legacy_osrtp_accept(struct stream_params *sp, GQueue *streams, GList *media_link,
struct sdp_ng_flags *flags, unsigned int *num)
{
if (!streams->tail)
return;
return false;
if (!media_link || !media_link->prev)
return;
return false;
struct stream_params *last = streams->tail->data;
if (!flags->osrtp_accept_legacy)
return;
return false;
// protocols must be known
if (!sp->protocol)
return;
return false;
if (!last->protocol)
return;
return false;
// types must match
if (sp->type_id != last->type_id)
return;
return false;
// we must be looking at a SRTP media section
if (!sp->protocol->rtp)
return;
return false;
if (!sp->protocol->srtp)
return;
return false;
// previous one must be a plain RTP section
if (!last->protocol->rtp)
return;
return false;
if (last->protocol->srtp)
return;
return false;
// is this a non-rejected SRTP section?
if (sp->rtp_endpoint.port) {
@ -1602,7 +1603,19 @@ static void legacy_osrtp_accept(struct stream_params *sp, GQueue *streams, GList
prev_media->legacy_osrtp = 1;
sp->index--;
(*num)--;
return false;
}
// or is it a rejected SRTP with a non-rejected RTP counterpart?
if (!sp->rtp_endpoint.port && last->rtp_endpoint.port) {
// just throw the rejected SRTP section away
struct sdp_media *media = media_link->data;
media->legacy_osrtp = 1;
sp_free(sp);
return true;
}
return false;
}
/* XXX split this function up */
@ -1730,7 +1743,8 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl
sp->protocol = &transport_protocols[sp->protocol->osrtp_proto];
}
legacy_osrtp_accept(sp, streams, k, flags, &num);
if (legacy_osrtp_accept(sp, streams, k, flags, &num))
continue;
// a=mid
attr = attr_get_by_id(&media->attributes, ATTR_MID);
@ -2454,6 +2468,8 @@ static void insert_dtls(GString *s, struct call_media *media, struct dtls_connec
const char *actpass;
struct call *call = media->call;
if (!media->protocol || !media->protocol->srtp)
return;
if (!call->dtls_cert || !MEDIA_ISSET(media, DTLS) || MEDIA_ISSET(media, PASSTHRU))
return;
@ -2558,6 +2574,8 @@ static void insert_crypto1(GString *s, struct call_media *media, struct crypto_p
g_string_append(s, "\r\n");
}
static void insert_crypto(GString *s, struct call_media *media, struct sdp_ng_flags *flags) {
if (!media->protocol || !media->protocol->srtp)
return;
for (GList *l = media->sdes_out.head; l; l = l->next)
insert_crypto1(s, media, l->data, flags);
}
@ -2791,7 +2809,7 @@ static const char *replace_sdp_media_section(struct sdp_chopper *chop, struct ca
is_active = false;
next:
print_sdp_media_section(chop->output, call_media, sdp_media,flags, rtp_ps_link, is_active,
print_sdp_media_section(chop->output, call_media, sdp_media, flags, rtp_ps_link, is_active,
attr_get_by_id(&sdp_media->attributes, ATTR_END_OF_CANDIDATES));
return NULL;
@ -2940,20 +2958,34 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu
if (!rtp_ps_link)
goto error;
// generate rejected m= line for accepted legacy OSRTP
if (MEDIA_ISSET(call_media, LEGACY_OSRTP)
&& call_media->protocol
&& call_media->protocol->srtp)
{
chopper_append_c(chop, "m=");
chopper_append_str(chop, &call_media->type);
if (call_media->protocol && call_media->protocol->srtp) {
const struct transport_protocol *prtp
= &transport_protocols[call_media->protocol->rtp_proto];
chopper_append_c(chop, " 0 ");
chopper_append_c(chop, prtp->name);
chopper_append_c(chop, " ");
chopper_append_str(chop, &call_media->format_str);
chopper_append_c(chop, "\r\n");
if (MEDIA_ISSET(call_media, LEGACY_OSRTP)) {
// generate rejected m= line for accepted legacy OSRTP
chopper_append_c(chop, "m=");
chopper_append_str(chop, &call_media->type);
chopper_append_c(chop, " 0 ");
chopper_append_c(chop, prtp->name);
chopper_append_c(chop, " ");
chopper_append_str(chop, &call_media->format_str);
chopper_append_c(chop, "\r\n");
}
else if (flags->osrtp_offer_legacy && flags->opmode == OP_OFFER) {
// generate duplicate plain RTP media section for OSRTP offer:
// save current chopper state, save actual protocol,
// print SDP section, restore chopper and protocl
struct sdp_chopper chop_copy = *chop;
const struct transport_protocol *proto = call_media->protocol;
call_media->protocol = prtp;
err = replace_sdp_media_section(chop, call_media, sdp_media,
rtp_ps_link, flags,
keep_zero_address);
*chop = chop_copy;
call_media->protocol = proto;
if (err)
goto error;
}
}
err = replace_sdp_media_section(chop, call_media, sdp_media, rtp_ps_link, flags,


+ 1
- 0
include/call_interfaces.h View File

@ -141,6 +141,7 @@ struct sdp_ng_flags {
osrtp_accept_legacy:1,
osrtp_accept_rfc:1,
osrtp_offer:1,
osrtp_offer_legacy:1,
reset:1,
egress:1,
siprec:1,


+ 128
- 0
t/auto-daemon-tests.pl View File

@ -259,6 +259,134 @@ SDP
new_call;
offer('add legacy OSRTP offer, reject',
{ flags => [ 'OSRTP-offer-legacy' ], 'transport-protocol' => 'RTP/SAVP' }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 198.51.100.24
t=0 0
m=audio 6012 RTP/AVP 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
m=audio PORT RTP/SAVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
a=crypto:1 AEAD_AES_256_GCM inline:CRYPTO256S
a=crypto:2 AEAD_AES_128_GCM inline:CRYPTO128S
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:5 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:6 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:7 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=setup:actpass
a=fingerprint:sha-256 FINGERPRINT256
a=tls-id:TLS_ID
SDP
answer('add legacy OSRTP offer, reject', { flags => [ 'OSRTP-accept-legacy' ] }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 198.51.100.24
t=0 0
m=audio 6014 RTP/AVP 8
m=audio 0 RTP/SAVP 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
new_call;
offer('add legacy OSRTP offer, accept',
{ flags => [ 'OSRTP-offer-legacy' ], 'transport-protocol' => 'RTP/SAVP' }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 198.51.100.24
t=0 0
m=audio 6020 RTP/AVP 8
----------------------------------
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
m=audio PORT RTP/SAVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
a=crypto:1 AEAD_AES_256_GCM inline:CRYPTO256S
a=crypto:2 AEAD_AES_128_GCM inline:CRYPTO128S
a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256
a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256
a=crypto:5 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192
a=crypto:6 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192
a=crypto:7 AES_CM_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:8 AES_CM_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128
a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128
a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128
a=setup:actpass
a=fingerprint:sha-256 FINGERPRINT256
a=tls-id:TLS_ID
SDP
answer('add legacy OSRTP offer, accept', { flags => [ 'OSRTP-accept-legacy' ] }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 198.51.100.24
t=0 0
m=audio 0 RTP/AVP 8
m=audio 6016 RTP/SAVP 8
a=crypto:1 AEAD_AES_256_GCM inline:53P5CsePy3hFUcuqsizkCnTE+4OKa1cOGa2WXHjoN19ifpweerTLaj+9vxc
----------------------------------
v=0
o=- 1545997027 1 IN IP4 172.17.0.2
s=tester
c=IN IP4 203.0.113.1
t=0 0
m=audio PORT RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
if ($amr_tests) {
new_call;


Loading…
Cancel
Save