diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index ce780c1cf..ed34c634a 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -389,23 +389,6 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr if (desc->ice_pwd[0] != '\0') belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("ice-pwd",desc->ice_pwd)); if (desc->ice_ufrag[0] != '\0') belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("ice-ufrag",desc->ice_ufrag)); - /* insert DTLS session attribute if needed */ - if ((desc->dtls_role != SalDtlsRoleInvalid) && (strlen(desc->dtls_fingerprint)>0)) { - switch(desc->dtls_role) { - case SalDtlsRoleIsClient: - belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("setup","active")); - break; - case SalDtlsRoleIsServer: - belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("setup","passive")); - break; - case SalDtlsRoleUnset: - default: - belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("setup","actpass")); - break; - } - belle_sdp_session_description_add_attribute(session_desc, belle_sdp_attribute_create("fingerprint",desc->dtls_fingerprint)); - } - if (desc->rtcp_xr.enabled == TRUE) { belle_sdp_session_description_add_attribute(session_desc, create_rtcp_xr_attribute(&desc->rtcp_xr)); } @@ -777,20 +760,10 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, } else if (strncmp(value, "passive", 7) == 0) { stream->dtls_role = SalDtlsRoleIsServer; } - - if (stream->dtls_role != SalDtlsRoleInvalid || md->dtls_role != SalDtlsRoleInvalid) { + if (stream->dtls_role != SalDtlsRoleInvalid) { attribute=belle_sdp_media_description_get_attribute(media_desc,"fingerprint"); - if (attribute && (value=belle_sdp_attribute_get_value(attribute))!=NULL){ - strncpy(stream->dtls_fingerprint, value, sizeof(stream->dtls_fingerprint)-1); - } else { - /* no valid stream attributes, get them from session */ - if (stream->dtls_role == SalDtlsRoleInvalid) stream->dtls_role = md->dtls_role; - strncpy(stream->dtls_fingerprint, md->dtls_fingerprint, strlen(md->dtls_fingerprint)+1); - } + strncpy(stream->dtls_fingerprint, belle_sdp_attribute_get_value(attribute),sizeof(stream->dtls_fingerprint)); } - } else { /* no setup attribute found in the stream, get the one from the session */ - stream->dtls_role = md->dtls_role; - strncpy(stream->dtls_fingerprint, md->dtls_fingerprint, strlen(md->dtls_fingerprint)+1); } } @@ -849,26 +822,30 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S desc->dir=SalStreamInactive; } - /* Read dtls specific session attributes if any (setup and fingerprint - rfc5763) */ - /* Presence of a valid dtls offer(setup and fingerprint attribute) is set in media Description by a dtls_fingerprint string longer than 0 - * and a dtls_role != SalDtlsRoleInvalid */ - desc->dtls_role = SalDtlsRoleInvalid; - desc->dtls_fingerprint[0] = '\0'; + /*DTLS attributes can be defined at session level.*/ value=belle_sdp_session_description_get_attribute_value(session_desc,"setup"); if (value){ + SalDtlsRole session_role; if (strncmp(value, "actpass", 7) == 0) { - desc->dtls_role = SalDtlsRoleUnset; + session_role = SalDtlsRoleUnset; } else if (strncmp(value, "active", 6) == 0) { - desc->dtls_role = SalDtlsRoleIsClient; + session_role = SalDtlsRoleIsClient; } else if (strncmp(value, "passive", 7) == 0) { - desc->dtls_role = SalDtlsRoleIsServer; + session_role = SalDtlsRoleIsServer; } + value=belle_sdp_session_description_get_attribute_value(session_desc,"fingerprint"); + if (value){ + int i; + /*copy dtls attributes to every streams, might be overwritten stream by stream*/ + for (i=0;istreams[i].dtls_fingerprint, value, sizeof(desc->streams[i].dtls_fingerprint)); + desc->streams[i].dtls_role=session_role; + } + } + } - value=belle_sdp_session_description_get_attribute_value(session_desc,"fingerprint"); - if (value){ - strncpy(desc->dtls_fingerprint, value, sizeof(desc->dtls_fingerprint)-1); - } + /* Get ICE remote ufrag and remote pwd, and ice_lite flag */ value=belle_sdp_session_description_get_attribute_value(session_desc,"ice-ufrag"); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index f5aff970d..8cd0c1352 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -438,7 +438,22 @@ static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, } return 0; } +static void setup_dtls_keys(LinphoneCall *call, SalMediaDescription *md){ + int i; + for(i=0; inb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + /* if media encryption is set to DTLS check presence of fingerprint in the call which shall have been set at stream init but it may have failed when retrieving certificate resulting in no fingerprint present and then DTLS not usable */ + if (sal_stream_description_has_dtls(&md->streams[i]) == TRUE) { + strncpy(md->streams[i].dtls_fingerprint, call->dtls_certificate_fingerprint, sizeof(md->streams[i].dtls_fingerprint)); /* get the self fingerprint from call(it's computed at stream init) */ + md->streams[i].dtls_role = SalDtlsRoleUnset; /* if we are offering, SDP will have actpass setup attribute when role is unset, if we are responding the result mediadescription will be set to SalDtlsRoleIsClient */ + } else { + md->streams[i].dtls_fingerprint[0] = '\0'; + md->streams[i].dtls_role = SalDtlsRoleInvalid; + } + } + +} static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){ LinphoneCore *lc=call->core; int i,j; @@ -675,16 +690,8 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * l = make_codec_list(lc, &codec_hints, lc->codecs_conf.video_codecs); md->streams[i].payloads = l; } - setup_encryption_keys(call,md); - /* if media encryption is set to DTLS check presence of fingerprint in the call which shall have been set at stream init but it may have failed when retrieving certificate resulting in no fingerprint present and then DTLS not usable */ - if ((call->params->media_encryption==LinphoneMediaEncryptionDTLS) && (call->dtls_certificate_fingerprint!= NULL)) { - memcpy(md->dtls_fingerprint, call->dtls_certificate_fingerprint, strlen((const char *)(call->dtls_certificate_fingerprint))); /* get the self fingerprint from call(it's computed at stream init) */ - md->dtls_role = SalDtlsRoleUnset; /* if we are offering, SDP will have actpass setup attribute when role is unset, if we are responding the result mediadescription will be set to SalDtlsRoleIsClient */ - } else { - md->dtls_fingerprint[0] = '\0'; - md->dtls_role = SalDtlsRoleInvalid; - } + setup_dtls_keys(call,md); setup_rtcp_fb(call, md); setup_rtcp_xr(call, md); @@ -2434,10 +2441,6 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b /* DTLS engine was already initialised during stream init. Before starting it we must be sure that the role(client or server) is set. * Role may have already been set to server if we initiate the call and already received a packet from peer, in that case do nothing */ SalDtlsRole salRole = stream->dtls_role; - if (salRole==SalDtlsRoleInvalid) { /* it's invalid in streams[0] but check also at session level */ - salRole = call->resultdesc->dtls_role; - } - if (salRole!=SalDtlsRoleInvalid) { /* if DTLS is available at both end points */ /* give the peer certificate fingerprint to dtls context */ SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op); @@ -2582,10 +2585,6 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu if (sal_stream_description_has_dtls(vstream) == TRUE) { /*DTLS*/ SalDtlsRole salRole = vstream->dtls_role; - if (salRole==SalDtlsRoleInvalid) { /* it's invalid in streams[0] but check also at session level */ - salRole = call->resultdesc->dtls_role; - } - if (salRole!=SalDtlsRoleInvalid) { /* if DTLS is available at both end points */ /* give the peer certificate fingerprint to dtls context */ SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 9baedd158..a74105963 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -394,6 +394,21 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, result->rtp_ssrc=local_offer->rtp_ssrc; strncpy(result->rtcp_cname,local_offer->rtcp_cname,sizeof(result->rtcp_cname)); + // Handle dtls session attribute: if both local and remote have a dtls fingerprint and a dtls setup, get the remote fingerprint into the result + if ((local_offer->dtls_role!=SalDtlsRoleInvalid) && (remote_answer->dtls_role!=SalDtlsRoleInvalid) + &&(strlen(local_offer->dtls_fingerprint)>0) && (strlen(remote_answer->dtls_fingerprint)>0)) { + strncpy(result->dtls_fingerprint, remote_answer->dtls_fingerprint,sizeof(result->dtls_fingerprint)); + if (remote_answer->dtls_role==SalDtlsRoleIsClient) { + result->dtls_role = SalDtlsRoleIsServer; + } else { + result->dtls_role = SalDtlsRoleIsClient; + } + } else { + result->dtls_fingerprint[0] = '\0'; + result->dtls_role = SalDtlsRoleInvalid; + } + + } @@ -449,6 +464,20 @@ static void initiate_incoming(const SalStreamDescription *local_cap, result->rtp_ssrc=local_cap->rtp_ssrc; strncpy(result->rtcp_cname,local_cap->rtcp_cname,sizeof(result->rtcp_cname)); + // Handle dtls stream attribute: if both local and remote have a dtls fingerprint and a dtls setup, add the local fingerprint to the answer + // Note: local description usually stores dtls config at session level which means it apply to all streams, check this too + if (((local_cap->dtls_role!=SalDtlsRoleInvalid)) && (remote_offer->dtls_role!=SalDtlsRoleInvalid) + && (strlen(local_cap->dtls_fingerprint)>0) && (strlen(remote_offer->dtls_fingerprint)>0)) { + strncpy(result->dtls_fingerprint, local_cap->dtls_fingerprint,sizeof(result->dtls_fingerprint)); + if (remote_offer->dtls_role==SalDtlsRoleUnset) { + result->dtls_role = SalDtlsRoleIsClient; + } + } else { + result->dtls_fingerprint[0] = '\0'; + result->dtls_role = SalDtlsRoleInvalid; + } + + } @@ -484,21 +513,6 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, result->rtcp_xr.enabled = FALSE; } - // Handle dtls session attribute: if both local and remote have a dtls fingerprint and a dtls setup, get the remote fingerprint into the result - if ((local_offer->dtls_role!=SalDtlsRoleInvalid) && (remote_answer->dtls_role!=SalDtlsRoleInvalid) - &&(strlen(local_offer->dtls_fingerprint)>0) && (strlen(remote_answer->dtls_fingerprint)>0)) { - strcpy(result->dtls_fingerprint, remote_answer->dtls_fingerprint); - if (remote_answer->dtls_role==SalDtlsRoleIsClient) { - result->dtls_role = SalDtlsRoleIsServer; - } else { - result->dtls_role = SalDtlsRoleIsClient; - } - } else { - result->dtls_fingerprint[0] = '\0'; - result->dtls_role = SalDtlsRoleInvalid; - } - - return 0; } @@ -553,24 +567,6 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities }else ms_warning("Unknown protocol for mline %i, declining",i); if (ls){ initiate_incoming(ls,rs,&result->streams[i],one_matching_codec); - - // Handle dtls stream attribute: if both local and remote have a dtls fingerprint and a dtls setup, add the local fingerprint to the answer - // Note: local description usually stores dtls config at session level which means it apply to all streams, check this too - if (((ls->dtls_role!=SalDtlsRoleInvalid) || (local_capabilities->dtls_role!=SalDtlsRoleInvalid)) && (rs->dtls_role!=SalDtlsRoleInvalid) - && ((strlen(ls->dtls_fingerprint)>0) || (strlen(local_capabilities->dtls_fingerprint)>0)) && (strlen(rs->dtls_fingerprint)>0)) { - if (strlen(ls->dtls_fingerprint)>0) { /* get the fingerprint in stream description */ - strcpy(result->streams[i].dtls_fingerprint, ls->dtls_fingerprint); - } else { /* get the fingerprint in session description */ - strcpy(result->streams[i].dtls_fingerprint, local_capabilities->dtls_fingerprint); - } - if (rs->dtls_role==SalDtlsRoleUnset) { - result->streams[i].dtls_role = SalDtlsRoleIsClient; - } - } else { - result->streams[i].dtls_fingerprint[0] = '\0'; - result->streams[i].dtls_role = SalDtlsRoleInvalid; - } - // Handle media RTCP XR attribute memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr)); if (rs->rtcp_xr.enabled == TRUE) { @@ -611,18 +607,6 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities strcpy(result->name,local_capabilities->name); - // Handle dtls session attribute: if both local and remote have a dtls fingerprint and a dtls setup, add the local fingerprint to the answer - if ((local_capabilities->dtls_role!=SalDtlsRoleInvalid) && (remote_offer->dtls_role!=SalDtlsRoleInvalid) - &&(strlen(local_capabilities->dtls_fingerprint)>0) && (strlen(remote_offer->dtls_fingerprint)>0)) { - strcpy(result->dtls_fingerprint, local_capabilities->dtls_fingerprint); - if (remote_offer->dtls_role==SalDtlsRoleUnset) { - result->dtls_role = SalDtlsRoleIsClient; - } - } else { - result->dtls_fingerprint[0] = '\0'; - result->dtls_role = SalDtlsRoleInvalid; - } - // Handle session RTCP XR attribute memset(&result->rtcp_xr, 0, sizeof(result->rtcp_xr)); if (remote_offer->rtcp_xr.enabled == TRUE) { diff --git a/include/sal/sal.h b/include/sal/sal.h index 4eedb23ab..0b7775b9b 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -260,8 +260,6 @@ typedef struct SalMediaDescription{ bool_t ice_lite; bool_t ice_completed; bool_t pad[2]; - char dtls_fingerprint[256]; - SalDtlsRole dtls_role; } SalMediaDescription; typedef struct SalMessage{ diff --git a/mediastreamer2 b/mediastreamer2 index 07a8b5693..8d120b3c1 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 07a8b569317d23e9442882be267d6640498a7b5e +Subproject commit 8d120b3c118625b827834d1e53b93185d335c3df