]> sjero.net Git - linphone/commitdiff
better srtp management
authorSimon Morlat <simon.morlat@linphone.org>
Thu, 22 Nov 2012 21:01:16 +0000 (22:01 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Thu, 22 Nov 2012 21:02:32 +0000 (22:02 +0100)
- have the choice to keep same keys accross reINVITEs
- don't restart the stream for minor changes like removal of a recv-only codec.

coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/private.h
coreapi/sal.c

index e0b0174ad55134e3f53d7356f2687145ad8952ee..d8fdd8803b081519ee04c5268c7fd77c965f3cd8 100644 (file)
@@ -208,22 +208,23 @@ static void update_media_description_from_stun(SalMediaDescription *md, const St
        
 }
 
-
-static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){
+void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
        MSList *l;
        PayloadType *pt;
+       SalMediaDescription *old_md=call->localdesc;
        int i;
        const char *me=linphone_core_get_identity(lc);
        LinphoneAddress *addr=linphone_address_new(me);
        const char *username=linphone_address_get_username (addr);
        SalMediaDescription *md=sal_media_description_new();
+       bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",0);
        
        if (call->ping_time>0) {
                linphone_core_adapt_to_network(lc,call->ping_time,&call->params);
        }
 
-       md->session_id=session_id;
-       md->session_ver=session_ver;
+       md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff));
+       md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff));
        md->nstreams=1;
        strncpy(md->addr,call->localip,sizeof(md->addr));
        strncpy(md->username,username,sizeof(md->username));
@@ -248,8 +249,6 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
        pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
        l=ms_list_append(l,pt);
        md->streams[0].payloads=l;
-       
-
 
        if (call->params.has_video){
                md->nstreams++;
@@ -263,15 +262,22 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
        
        for(i=0; i<md->nstreams; i++) {
                if (md->streams[i].proto == SalProtoRtpSavp) {
-                       md->streams[i].crypto[0].tag = 1;
-                       md->streams[i].crypto[0].algo = AES_128_SHA1_80;
-                       if (!generate_b64_crypto_key(30, md->streams[i].crypto[0].master_key))
-                               md->streams[i].crypto[0].algo = 0;
-                       md->streams[i].crypto[1].tag = 2;
-                       md->streams[i].crypto[1].algo = AES_128_SHA1_32;
-                       if (!generate_b64_crypto_key(30, md->streams[i].crypto[1].master_key))
-                               md->streams[i].crypto[1].algo = 0;
-                       md->streams[i].crypto[2].algo = 0;
+                       if (keep_srtp_keys && old_md && old_md->streams[i].proto==SalProtoRtpSavp){
+                               int j;
+                               for(j=0;j<SAL_CRYPTO_ALGO_MAX;++j){
+                                       memcpy(&md->streams[i].crypto[j],&old_md->streams[i].crypto[j],sizeof(SalSrtpCryptoAlgo));
+                               }
+                       }else{
+                               md->streams[i].crypto[0].tag = 1;
+                               md->streams[i].crypto[0].algo = AES_128_SHA1_80;
+                               if (!generate_b64_crypto_key(30, md->streams[i].crypto[0].master_key))
+                                       md->streams[i].crypto[0].algo = 0;
+                               md->streams[i].crypto[1].tag = 2;
+                               md->streams[i].crypto[1].algo = AES_128_SHA1_32;
+                               if (!generate_b64_crypto_key(30, md->streams[i].crypto[1].master_key))
+                                       md->streams[i].crypto[1].algo = 0;
+                               md->streams[i].crypto[2].algo = 0;
+                       }
                }
        }
        update_media_description_from_stun(md,&call->ac,&call->vc);
@@ -280,22 +286,8 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
                linphone_core_update_ice_state_in_call_stats(call);
        }
        linphone_address_destroy(addr);
-       return md;
-}
-
-void update_local_media_description(LinphoneCore *lc, LinphoneCall *call){
-       SalMediaDescription *md=call->localdesc;
-       if (md== NULL) {
-               call->localdesc = create_local_media_description(lc,call);
-       } else {
-               call->localdesc = _create_local_media_description(lc,call,md->session_id,md->session_ver+1);
-               sal_media_description_unref(md);
-       }
-}
-
-SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
-       unsigned int id=rand() & 0xfff;
-       return _create_local_media_description(lc,call,id,id);
+       call->localdesc=md;
+       if (old_md) sal_media_description_unref(old_md);
 }
 
 static int find_port_offset(LinphoneCore *lc, SalStreamType type){
@@ -1026,11 +1018,11 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u
                        ms_warning("Case is MS_VIDEO_DECODER_DECODING_ERRORS");
                        linphone_call_send_vfu_request(call);
                        break;
-        case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED:
-            ms_message("First video frame decoded successfully");
-            if (call->nextVideoFrameDecoded._func != NULL)
-                call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data);
-            break;
+               case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED:
+                       ms_message("First video frame decoded successfully");
+                       if (call->nextVideoFrameDecoded._func != NULL)
+                       call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data);
+                       break;
                default:
                        ms_warning("Unhandled event %i", event_id);
                        break;
@@ -1039,10 +1031,10 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u
 #endif
 
 void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data) {
-    call->nextVideoFrameDecoded._func = cb;
-    call->nextVideoFrameDecoded._user_data = user_data;
+       call->nextVideoFrameDecoded._func = cb;
+       call->nextVideoFrameDecoded._user_data = user_data;
 #ifdef VIDEO_ENABLED
-    ms_filter_call_method_noarg(call->videostream->decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION);
+       ms_filter_call_method_noarg(call->videostream->decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION);
 #endif
 }
 
index f3d0a00302f7910c780b01970ecc82315aec8728..01667ebcb4f7608ae26d367fe7787d3cf487a4e8 100644 (file)
@@ -2290,7 +2290,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call){
        linphone_call_init_media_streams(call);
        if (lc->ringstream==NULL)
                audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
-       call->localdesc=create_local_media_description(lc,call);
+       linphone_call_make_local_media_description(lc,call);
        if (!lc->sip_conf.sdp_200_ack){
                call->media_pending=TRUE;
                sal_call_set_local_media_description(call->op,call->localdesc);
@@ -2552,7 +2552,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
        bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
        const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
 
-       call->localdesc=create_local_media_description(lc,call);
+       linphone_call_make_local_media_description(lc,call);
        sal_call_set_local_media_description(call->op,call->localdesc);
        md=sal_call_get_final_media_description(call->op);
        if (md && sal_media_description_empty(md)){
@@ -2658,7 +2658,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
                        call->videostream->ice_check_list = NULL;
                }
                call->params = *params;
-               update_local_media_description(lc, call);
+               linphone_call_make_local_media_description(lc, call);
                if ((call->ice_session != NULL) && !has_video && call->params.has_video) {
                        /* Defer call update until the ICE candidates gathering process has finished. */
                        ms_message("Defer call update to gather ICE candidates");
@@ -2769,7 +2769,7 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
        }
        call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op));
        call->camera_active=call->params.has_video;
-       update_local_media_description(lc,call);
+       linphone_call_make_local_media_description(lc,call);
        if (call->ice_session != NULL) {
                linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(call->op));
 #ifdef VIDEO_ENABLED
@@ -2885,7 +2885,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
                call->params=*params;
                call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op));
                call->camera_active=call->params.has_video;
-               update_local_media_description(lc,call);
+               linphone_call_make_local_media_description(lc,call);
                sal_call_set_local_media_description(call->op,call->localdesc);
        }
        
@@ -3075,7 +3075,7 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call)
                ms_warning("Cannot pause this call, it is not active.");
                return -1;
        }
-       update_local_media_description(lc,call);
+       linphone_call_make_local_media_description(lc,call);
        if (call->ice_session != NULL)
                linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
        if (sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv)){
@@ -3154,7 +3154,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
         prevents the participants to hear it while the 200OK comes back.*/
        if (call->audiostream) audio_stream_play(call->audiostream, NULL);
 
-       update_local_media_description(lc,the_call);
+       linphone_call_make_local_media_description(lc,the_call);
        if (call->ice_session != NULL)
                linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
        sal_call_set_local_media_description(call->op,call->localdesc);
index 60587dbcd8dc9524e598e9bf85f380401b345a99..5ebe8b5b7611c491970ab3579db576515b6c98ae 100644 (file)
@@ -582,10 +582,7 @@ int linphone_core_set_as_current_call(LinphoneCore *lc, LinphoneCall *call);
 int linphone_core_get_calls_nb(const LinphoneCore *lc);
 
 void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
-
-SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
-void update_local_media_description(LinphoneCore *lc, LinphoneCall *call);
-
+void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call);
 void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
 
 bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt,  int bandwidth_limit);
index 229ee577f3a531e3b8c9d3bf85c1312c6d5e03aa..f46d9a556c9b3f4b78be57fe10cf939ed173f868 100644 (file)
@@ -162,6 +162,10 @@ static bool_t payload_type_equals(const PayloadType *p1, const PayloadType *p2){
        return TRUE;
 }
 
+static bool_t is_recv_only(PayloadType *p){
+       return (p->flags & PAYLOAD_TYPE_FLAG_CAN_RECV) && ! (p->flags & PAYLOAD_TYPE_FLAG_CAN_SEND);
+}
+
 static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
        const MSList *e1,*e2;
        for(e1=l1,e2=l2;e1!=NULL && e2!=NULL; e1=e1->next,e2=e2->next){
@@ -170,6 +174,12 @@ static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
                if (!payload_type_equals(p1,p2))
                        return FALSE;
        }
+       if (e1!=NULL){
+               /*skip possible recv-only payloads*/
+               for(;e1!=NULL && is_recv_only((PayloadType*)e1->data);e1=e1->next){
+                       ms_message("Skipping recv-only payload type...");
+               }
+       }
        if (e1!=NULL || e2!=NULL){
                /*means one list is longer than the other*/
                return FALSE;