|
|
|
|
@ -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,
|
|
|
|
|
|