Бесплатная поддержка для создания предложения SRTP из входящего 3P CC ПРИГЛАСИТЕ? - PullRequest
0 голосов
/ 30 апреля 2020

Я использую Freeswitch ESL (Event Socket Library) в Node.js Когда я получаю приглашение на SIP. js от конечной точки sip класса c, содержимое SDP является обычным RTP. Мне нужно иметь возможность подключить конечную точку RTP к конечной точке SRTP с помощью Freeswitch в середине. Для этого нам нужно иметь возможность создать конечную точку на Freeswitch без SDP (3P CC INVITE), но мы хотим, чтобы эта конечная точка возвращала SRTP SDP, а не RTP SDP.

Основной вопрос: Поддерживает ли Freeswitch создание предложения SRTP из входящего 3P CC INVITE?

Я полагаю, что эта часть обрабатывает 3P CC INVITE в Freeswitch 1.8.5: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/mod/endpoints/mod_sofia/sofia.c

if (sofia_test_pflag(profile, PFLAG_3PCC)) {
    if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc=yes cannot work with bypass or proxy media, hanging up.\n");
        switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
        switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
    } else {
        switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
        switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
        switch_core_media_prepare_codecs(session, 1);
        switch_channel_set_state(channel, CS_HIBERNATE);
        switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
        sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);

        if (sofia_use_soa(tech_pvt)) {
            nua_respond(tech_pvt->nh, SIP_200_OK,
                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                        SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
                        SOATAG_REUSE_REJECTED(1),
                        SOATAG_AUDIO_AUX("cn telephone-event"),
                        TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
        } else {
            nua_respond(tech_pvt->nh, SIP_200_OK,
                        NUTAG_MEDIA_ENABLE(0),
                        SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
                        SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
        }
    }
}

Возможно, можно использовать тот же шаблон, который они использовали для mod_verto: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/mod/endpoints/mod_verto/mod_verto.c

Эта функция switch_core_media_gen_local_sdp , кажется, один для создания RTP SDP: https://github.com/signalwire/freeswitch/blob/v1.8.5/src/switch_core_media.c Как мы можем вместо этого изменить его на SRTP SDP?

static const char *get_media_profile_name(switch_core_session_t *session, int secure)
{
    switch_assert(session);

    if (switch_channel_test_flag(session->channel, CF_AVPF)) {
        if (switch_channel_test_flag(session->channel, CF_DTLS) || secure) {
            if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
                return "UDP/TLS/RTP/SAVPF";
            } else {
                return "RTP/SAVPF";
            }
        } else {
            if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) {
                return "UDP/AVPF";
            } else {
                return "RTP/AVPF";
            }
        }
    }

    if (secure) {
        return "RTP/SAVP";
    }

    return "RTP/AVP";

}

Существует 3 условия для включения SRTP:

session->channel->flags['CF_AVPF']
(session->channel->flags['CF_DTLS'] || secure)
session->channel->flags['CF_AVPF_MOZ']

Условия установки флага CF_AVPF вызывают switch_core_session_set_ice или:

if (is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING) ||
    switch_channel_test_flag(session->channel, CF_3PCC)) {
    if (!switch_channel_test_flag(session->channel, CF_AVPF) &&
        switch_true(switch_channel_get_variable(session->channel, "media_webrtc"))) {
        switch_channel_set_flag(session->channel, CF_AVPF);
        switch_channel_set_flag(session->channel, CF_ICE);
        smh->mparams->rtcp_audio_interval_msec = SWITCH_RTCP_AUDIO_INTERVAL_MSEC;
        smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
    }

    if (switch_true(switch_channel_get_variable(session->channel, "add_ice_candidates"))) {
        switch_channel_set_flag(session->channel, CF_ICE);
    }

    if ( switch_rtp_has_dtls() && dtls_ok(session)) {
        if (switch_channel_test_flag(session->channel, CF_AVPF) ||
            switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls"))) {
            switch_channel_set_flag(smh->session->channel, CF_DTLS);
            switch_channel_set_flag(smh->session->channel, CF_SECURE);
            generate_local_fingerprint(smh, SWITCH_MEDIA_TYPE_AUDIO);
        }
    }
    switch_core_session_parse_crypto_prefs(session);
    switch_core_session_check_outgoing_crypto(session);
}

Условия установки флага CF_DTLS одинаковы как указано выше ( CF_AVPF ) или вызов check_ice :

if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) {
    char *p;

    engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value);

    if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) {
        *p++ = '\0';

        if (switch_channel_test_flag(smh->session->channel, CF_REINVITE) && !switch_channel_test_flag(smh->session->channel, CF_RECOVERING) &&
            !zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) {
            engine->new_dtls = 0;
        } else {
            switch_set_string(engine->remote_dtls_fingerprint.str, p);
            engine->new_dtls = 1;
            engine->new_ice = 1;
        }
    }

    generate_local_fingerprint(smh, type);
    switch_channel_set_flag(smh->session->channel, CF_DTLS);

}
* 1 044 * Существует также возможность отправить значение true для параметра secure , но условий много.

Условия для установки CF_AVPF_MOZ флаг:

if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) {
    switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
}

if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/RTP/AVPF")) {
    switch_channel_set_flag(session->channel, CF_AVPF_MOZ);
}

1 Ответ

0 голосов
/ 03 мая 2020

Попробуйте установить media_webrtc = true, это должно указывать freeswitch использовать DTLS для медиапотока, сигнализация WebRT C должна выполняться отдельно.

<action application="bridge" data="[media_webrtc=true]sofia/internal/100%${sip_profile}"/>
...