diff --git a/daemon/call.c b/daemon/call.c index 56a4807ba..74477d0db 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2912,7 +2912,7 @@ static int __media_init_from_flags(struct call_media *other_media, struct call_m bf_copy_same(&other_media->media_flags, &sp->sp_flags, SHARED_FLAG_RTCP_MUX | SHARED_FLAG_ASYMMETRIC | SHARED_FLAG_UNIDIRECTIONAL | SHARED_FLAG_ICE | SHARED_FLAG_TRICKLE_ICE | SHARED_FLAG_ICE_LITE_PEER | - SHARED_FLAG_RTCP_FB | SHARED_FLAG_LEGACY_OSRTP); + SHARED_FLAG_RTCP_FB | SHARED_FLAG_LEGACY_OSRTP | SHARED_FLAG_LEGACY_OSRTP_REV); // duplicate the entire queue of offered crypto params crypto_params_sdes_queue_clear(&other_media->sdes_in); diff --git a/daemon/sdp.c b/daemon/sdp.c index 77a53e181..1c9a98a08 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1580,39 +1580,49 @@ static bool legacy_osrtp_accept(struct stream_params *sp, GQueue *streams, GList if (sp->type_id != last->type_id) return false; - // we must be looking at a SRTP media section + // we must be looking at RTP pairs if (!sp->protocol->rtp) return false; - if (!sp->protocol->srtp) - return false; - - // previous one must be a plain RTP section if (!last->protocol->rtp) return false; - if (last->protocol->srtp) - return false; - // is this a non-rejected SRTP section? - if (sp->rtp_endpoint.port) { - // looks ok. remove the previous one and only retain this one. mark it as such. - g_queue_pop_tail(streams); - sp_free(last); - - SP_SET(sp, LEGACY_OSRTP); - struct sdp_media *prev_media = media_link->prev->data; - prev_media->legacy_osrtp = 1; - sp->index--; - (*num)--; - return false; - } + // see if this is SRTP and the previous was RTP + if (sp->protocol->srtp && !last->protocol->srtp) { + // is this a non-rejected SRTP section? + if (sp->rtp_endpoint.port) { + // looks ok. remove the previous one and only retain this one. mark it as such. + g_queue_pop_tail(streams); + sp_free(last); + + SP_SET(sp, LEGACY_OSRTP); + struct sdp_media *prev_media = media_link->prev->data; + 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; + // 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; + } + } + // or is it reversed? this being RTP and the previous was SRTP + else if (!sp->protocol->srtp && last->protocol->srtp) { + // if the SRTP one is not rejected, throw away the RTP one and mark the SRTP one + if (last->rtp_endpoint.port) { + SP_SET(last, LEGACY_OSRTP); + SP_SET(last, LEGACY_OSRTP_REV); + + struct sdp_media *media = media_link->data; + media->legacy_osrtp = 1; + sp_free(sp); + return true; + } } return false; @@ -2958,10 +2968,14 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu if (!rtp_ps_link) goto error; - if (call_media->protocol && call_media->protocol->srtp) { - const struct transport_protocol *prtp - = &transport_protocols[call_media->protocol->rtp_proto]; - if (MEDIA_ISSET(call_media, LEGACY_OSRTP)) { + const struct transport_protocol *prtp = NULL; + if (call_media->protocol && call_media->protocol->srtp) + prtp = &transport_protocols[call_media->protocol->rtp_proto]; + + if (prtp) { + if (MEDIA_ISSET(call_media, LEGACY_OSRTP) + && !MEDIA_ISSET(call_media, LEGACY_OSRTP_REV)) + { // generate rejected m= line for accepted legacy OSRTP chopper_append_c(chop, "m="); chopper_append_str(chop, &call_media->type); @@ -2993,6 +3007,19 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologu if (err) goto error; + if (prtp && MEDIA_ISSET(call_media, LEGACY_OSRTP) + && MEDIA_ISSET(call_media, LEGACY_OSRTP_REV)) + { + // 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"); + } + media_index++; m = m->next; } diff --git a/include/call.h b/include/call.h index 050237ddc..e5382f6ab 100644 --- a/include/call.h +++ b/include/call.h @@ -114,6 +114,7 @@ enum { #define SHARED_FLAG_UNIDIRECTIONAL 0x00001000 #define SHARED_FLAG_RTCP_FB 0x00002000 #define SHARED_FLAG_LEGACY_OSRTP 0x00004000 +#define SHARED_FLAG_LEGACY_OSRTP_REV 0x00008000 /* struct stream_params */ #define SP_FLAG_NO_RTCP 0x00010000 @@ -132,6 +133,7 @@ enum { #define SP_FLAG_ICE_LITE_PEER SHARED_FLAG_ICE_LITE_PEER #define SP_FLAG_RTCP_FB SHARED_FLAG_RTCP_FB #define SP_FLAG_LEGACY_OSRTP SHARED_FLAG_LEGACY_OSRTP +#define SP_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV /* struct packet_stream */ #define PS_FLAG_RTP 0x00010000 @@ -187,6 +189,7 @@ enum { #define MEDIA_FLAG_BLACKHOLE 0x20000000 #define MEDIA_FLAG_REORDER_FORCED 0x40000000 #define MEDIA_FLAG_LEGACY_OSRTP SHARED_FLAG_LEGACY_OSRTP +#define MEDIA_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV /* access macros */ #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index abb8f4088..4e6ce3bcb 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -124,6 +124,141 @@ a=tls-id:TLS_ID SDP +new_call; + +offer('legacy reversed OSRTP offer, accept', + { flags => [ 'OSRTP-accept' ], 'transport-protocol' => 'RTP/AVP' }, < [ 'OSRTP-accept' ] }, < 'nonew' }, < [ 'OSRTP-accept' ] }, <