Fix reINVITE issues when SRTP mode is mandatory
This commit is contained in:
parent
493815f88e
commit
9f4760fe25
|
@ -1107,6 +1107,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
tsk_bool_t is_ice_enabled[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_ice_restart[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_dtls_fingerprint_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tsk_bool_t is_sdes_crypto_changed[TMEDIA_SESSION_MAX_LINES] = { tsk_false };
|
||||
tmedia_type_t media_types[TMEDIA_SESSION_MAX_LINES] = { tmedia_none };
|
||||
tsk_bool_t is_media_type_changed = tsk_false;
|
||||
tsk_bool_t is_ro_media_lines_changed = tsk_false;
|
||||
|
@ -1189,12 +1190,13 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
while ((M0 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(self->sdp.ro, tsdp_htype_M, index))){
|
||||
++m_lines_count;
|
||||
if (m_lines_count >= TMEDIA_SESSION_MAX_LINES) {
|
||||
TSK_DEBUG_ERROR("Too many m-lines %d>%d", m_lines_count, TMEDIA_SESSION_MAX_LINES);
|
||||
TSK_DEBUG_ERROR("Too many m-lines %u>%u", (unsigned)m_lines_count, (unsigned)TMEDIA_SESSION_MAX_LINES);
|
||||
ret = -2;
|
||||
goto bail;
|
||||
}
|
||||
M1 = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp, tsdp_htype_M, index);
|
||||
// media-level diffs
|
||||
|
||||
if ((ret = tsdp_header_M_diff(M0, M1, &med_level_diff)) != 0) {
|
||||
goto bail;
|
||||
}
|
||||
|
@ -1205,8 +1207,8 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_enabled)) is_ice_enabled[index] = tsk_true;
|
||||
if (tmedia_defaults_get_ice_enabled() && (med_level_diff & tsdp_header_M_diff_ice_restart)) is_ice_restart[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_dtls_fingerprint) is_dtls_fingerprint_changed[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_sdes_crypto);
|
||||
if (med_level_diff & tsdp_header_M_diff_media_type);
|
||||
if (med_level_diff & tsdp_header_M_diff_sdes_crypto) is_sdes_crypto_changed[index] = tsk_true;
|
||||
if (med_level_diff & tsdp_header_M_diff_media_type); // cannot happen as media must keep same index
|
||||
|
||||
// dtls fingerprint (session-level)
|
||||
if (!is_dtls_fingerprint_changed[index]) {
|
||||
|
@ -1225,6 +1227,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: sdes crypo lines (session-level)
|
||||
|
||||
// media type
|
||||
media_types[index] = tmedia_type_from_sdp_headerM(M1);
|
||||
|
@ -1313,6 +1316,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
TSK_DEBUG_INFO(
|
||||
"m_lines_count=%u,\n"
|
||||
"is_dtls_fingerprint_changed=%u,\n"
|
||||
"is_sdes_crypto_changed=%u,\n"
|
||||
"is_ice_enabled=%u,\n"
|
||||
"is_ice_restart=%u,\n"
|
||||
"is_ro_hold_resume_changed=%u,\n"
|
||||
|
@ -1325,6 +1329,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
"is_local_encoder_still_ok=%u\n",
|
||||
(unsigned)m_lines_count,
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_dtls_fingerprint_changed, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_sdes_crypto_changed, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ice_enabled, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ice_restart, m_lines_count),
|
||||
(unsigned)__flags_sum((const tsk_bool_t*)&is_ro_hold_resume_changed, m_lines_count),
|
||||
|
@ -1348,7 +1353,7 @@ int tmedia_session_mgr_set_ro(tmedia_session_mgr_t* self, const tsdp_message_t*
|
|||
*/
|
||||
if (self->started) {
|
||||
for (index = 0; index < m_lines_count; ++index) {
|
||||
if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index])) {
|
||||
if (/* && (!is_ro_loopback_address[index]) && */ ((is_ro_codecs_changed[index] && !is_local_encoder_still_ok[index]) || is_ro_network_info_changed[index] || is_dtls_fingerprint_changed[index] || is_sdes_crypto_changed[index])) {
|
||||
TSK_DEBUG_INFO("Stop media index %d to reconf", (int)index);
|
||||
stopped_to_reconf[index] = tsk_true;
|
||||
tmedia_session_mgr_set(self,
|
||||
|
@ -1518,7 +1523,7 @@ end_of_sessions_update:
|
|||
for (index = 0; index < m_lines_count; ++index) {
|
||||
if (stopped_to_reconf[index] && !is_ice_enabled[index]) {
|
||||
if ((ret = _tmedia_session_mgr_start(self, (int)index))) {
|
||||
TSK_DEBUG_ERROR("Failed to re-start session at index = %d", index);
|
||||
TSK_DEBUG_ERROR("Failed to re-start session at index = %d", (int)index);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
@ -2365,7 +2370,7 @@ static int _tmedia_session_mgr_start(tmedia_session_mgr_t* self, int session_ind
|
|||
}
|
||||
}
|
||||
}
|
||||
if (session_index) {
|
||||
if (session_index == kSessionIndexAll) {
|
||||
self->started = tsk_true;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ typedef struct trtp_srtp_ctx_internal_xs
|
|||
trtp_srtp_crypto_type_t crypto_type;
|
||||
char key_str[SRTP_MAX_KEY_LEN];
|
||||
char key_bin[SRTP_MASTER_KEY_LEN];
|
||||
tsk_bool_t have_valid_key;
|
||||
|
||||
srtp_t session;
|
||||
srtp_policy_t policy;
|
||||
|
|
|
@ -45,12 +45,15 @@ int trtp_srtp_ctx_internal_init(struct trtp_srtp_ctx_internal_xs* ctx, int32_t t
|
|||
|
||||
ctx->tag = tag;
|
||||
ctx->crypto_type = type;
|
||||
if (!ctx->have_valid_key) { // use same key to avoid unseless SRTP re-negs (also fix interop-issues against buggy clients -reINVITEs-)
|
||||
if ((srtp_err = crypto_get_random((unsigned char*)ctx->key_bin, sizeof(ctx->key_bin))) != err_status_ok) {
|
||||
TSK_DEBUG_ERROR("crypto_get_random() failed");
|
||||
return -2;
|
||||
}
|
||||
size = tsk_base64_encode((const uint8_t*)ctx->key_bin, sizeof(ctx->key_bin), &key_str);
|
||||
key_str[size] = '\0';
|
||||
ctx->have_valid_key = tsk_true;
|
||||
}
|
||||
|
||||
switch(ctx->crypto_type){
|
||||
case HMAC_SHA1_80:
|
||||
|
@ -123,9 +126,11 @@ int trtp_srtp_ctx_deinit(trtp_srtp_ctx_xt* ctx)
|
|||
|
||||
int trtp_srtp_match_line(const char* crypto_line, int32_t* tag, int32_t* crypto_type, char* key, tsk_size_t key_size)
|
||||
{
|
||||
char* saveptr;
|
||||
char* v = tsk_strtok_r((char*)crypto_line, " :|;", &saveptr);
|
||||
char* copyptr = tsk_strdup(crypto_line); // "strtok_r" will insert "\0" and modify the string
|
||||
char* saveptr = tsk_null;
|
||||
char* v = tsk_strtok_r(copyptr, " :|;", &saveptr);
|
||||
int32_t k = 0;
|
||||
int ret = -0xF0;
|
||||
while(v){
|
||||
switch(k){
|
||||
case 0:
|
||||
|
@ -148,14 +153,14 @@ int trtp_srtp_match_line(const char* crypto_line, int32_t* tag, int32_t* crypto_
|
|||
}
|
||||
}
|
||||
else {
|
||||
return -0xFF;
|
||||
ret = -0xFF; goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if(!tsk_striequals(v, "inline")){
|
||||
return -0xFF;
|
||||
ret = -0xFF; goto bail;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -165,14 +170,15 @@ int trtp_srtp_match_line(const char* crypto_line, int32_t* tag, int32_t* crypto_
|
|||
memset(key, 0, key_size);
|
||||
memcpy(key, v, TSK_MIN(key_size, tsk_strlen(v)));
|
||||
}
|
||||
return 0;
|
||||
ret = 0; goto bail;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
v = tsk_strtok_r(tsk_null, " :|;", &saveptr);
|
||||
}
|
||||
|
||||
return -0xF0;
|
||||
bail:
|
||||
TSK_FREE(copyptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tsk_size_t trtp_srtp_get_local_contexts(trtp_manager_t* rtp_mgr, const struct trtp_srtp_ctx_xs ** contexts, tsk_size_t contexts_count)
|
||||
|
@ -242,7 +248,7 @@ int trtp_srtp_set_crypto(struct trtp_manager_s* rtp_mgr, const char* crypto_line
|
|||
}
|
||||
|
||||
key_bin = (unsigned char*)srtp_ctx->rtp.key_bin;
|
||||
tsk_base64_decode((const uint8_t*)srtp_ctx->rtp.key_str, tsk_strlen(srtp_ctx->rtp.key_str), (char**)&key_bin);
|
||||
tsk_base64_decode((const uint8_t*)srtp_ctx->rtp.key_str, (tsk_size_t)tsk_strlen(srtp_ctx->rtp.key_str), (char**)&key_bin);
|
||||
srtp_ctx->rtp.policy.key = key_bin;
|
||||
srtp_ctx->rtp.policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
|
||||
srtp_ctx->rtp.policy.window_size = 2048;
|
||||
|
|
|
@ -873,14 +873,16 @@ int tsdp_header_M_diff(const tsdp_header_M_t* M_old, const tsdp_header_M_t* M_ne
|
|||
do {
|
||||
A0 = tsdp_header_M_findA_at(M_old, "crypto", index);
|
||||
A1 = M_new ? tsdp_header_M_findA_at(M_new, "crypto", index) : tsk_null;
|
||||
if (A0 && A1 && !tsk_striequals(A0->value, A1->value)) {
|
||||
diff |= tsdp_header_M_diff_dtls_fingerprint;
|
||||
if (A0 && A1) {
|
||||
if (!tsk_striequals(A0->value, A1->value)) {
|
||||
diff |= tsdp_header_M_diff_sdes_crypto;
|
||||
}
|
||||
else if ((A0 && !A1) || (!A0 && A1)) {
|
||||
diff |= tsdp_header_M_diff_dtls_fingerprint;
|
||||
}
|
||||
else if (index == 0) { // (A1 && !AO) means "more" crypto lines, otherwise "less". In all cases if the first matched we're ok
|
||||
diff |= tsdp_header_M_diff_sdes_crypto;
|
||||
}
|
||||
++index;
|
||||
} while (A0 && A1);
|
||||
} while ((A0 && A1) && ((diff & tsdp_header_M_diff_sdes_crypto) != tsdp_header_M_diff_sdes_crypto));
|
||||
|
||||
// media lines
|
||||
if ((diff & tsdp_header_M_diff_index) != tsdp_header_M_diff_index) {
|
||||
|
|
Loading…
Reference in New Issue