From 0c559f5860628b19e25b2215d60318212fec9688 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 19 Nov 2018 11:53:29 -0500 Subject: [PATCH] Add missing SDES accept routine When we receive an incoming SDES parameter, we must match them against the previously sent outgoing SDES parameters, choose the one that matches what we just received and eliminate all others. This is a no-op if none were sent previously (original offer). Issue only appears in a re-invite when the first offered crypto suite is accepted. fixes #631 Change-Id: I4991d0aaf0b29c1ba66045ed0e5281fc18c8af2e --- daemon/call.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/daemon/call.c b/daemon/call.c index ec8ddb45f..bfc89a130 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1447,7 +1447,7 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi } } } - else { + else { // OP_ANSWER // we pick the first supported crypto suite struct crypto_params_sdes *cps = cpq->head ? cpq->head->data : NULL; struct crypto_params_sdes *cps_in = cpq_in->head ? cpq_in->head->data : NULL; @@ -1491,6 +1491,32 @@ static void __generate_crypto(const struct sdp_ng_flags *flags, struct call_medi skip_sdes: ; } +// for an answer, uses the incoming received list of SDES crypto suites to prune +// the list of (generated) outgoing crypto suites to contain only the one that was +// accepted +static void __sdes_accept(struct call_media *media) { + if (!media->sdes_in.length) + return; + struct crypto_params_sdes *cps_in = media->sdes_in.head->data; + GList *l = media->sdes_out.head; + while (l) { + struct crypto_params_sdes *cps_out = l->data; + if (cps_out->params.crypto_suite != cps_in->params.crypto_suite) + goto del_next; + if (cps_out->tag != cps_in->tag) + goto del_next; + + // this one's good + l = l->next; + continue; +del_next: + // mismatch, prune this one out + crypto_params_sdes_free(cps_out); + GList *next = l->next; + g_queue_delete_link(&media->sdes_out, l); + l = next; + } +} static void __disable_streams(struct call_media *media, unsigned int num_ports) { @@ -1895,8 +1921,10 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, other_media->sdes_in = sp->sdes_params; g_queue_init(&sp->sdes_params); - if (other_media->sdes_in.length) + if (other_media->sdes_in.length) { MEDIA_SET(other_media, SDES); + __sdes_accept(other_media); + } } // codec and RTP payload types handling