diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index a807c2385e43eac4271d2d80f21d97f1f1340522..a6f497568b3916631b31dc9002c77a67bf9df76b 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -773,6 +773,43 @@ static void check_ice_support(struct ast_sip_session *session, struct ast_sip_se } } +static void process_ice_auth_attrb(struct ast_sip_session *session, struct ast_sip_session_media *session_media, + const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream) +{ + struct ast_rtp_engine_ice *ice; + const pjmedia_sdp_attr *ufrag_attr, *passwd_attr; + char ufrag_attr_value[256]; + char passwd_attr_value[256]; + + /* If ICE support is not enabled or available exit early */ + if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) { + return; + } + + ufrag_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-ufrag", NULL); + if (!ufrag_attr) { + ufrag_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-ufrag", NULL); + } + if (ufrag_attr) { + ast_copy_pj_str(ufrag_attr_value, (pj_str_t*)&ufrag_attr->value, sizeof(ufrag_attr_value)); + } else { + return; + } + passwd_attr = pjmedia_sdp_media_find_attr2(remote_stream, "ice-pwd", NULL); + if (!passwd_attr) { + passwd_attr = pjmedia_sdp_attr_find2(remote->attr_count, remote->attr, "ice-pwd", NULL); + } + if (passwd_attr) { + ast_copy_pj_str(passwd_attr_value, (pj_str_t*)&passwd_attr->value, sizeof(passwd_attr_value)); + } else { + return; + } + + if (ufrag_attr && passwd_attr) { + ice->set_authentication(session_media->rtp, ufrag_attr_value, passwd_attr_value); + } +} + /*! \brief Function which processes ICE attributes in an audio stream */ static void process_ice_attributes(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream) @@ -1509,6 +1546,11 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, /* If ICE support is enabled find all the needed attributes */ check_ice_support(session, session_media, stream); + /* If ICE support is enabled then check remote ICE started? */ + if (session_media->remote_ice) { + process_ice_auth_attrb(session, session_media, sdp, stream); + } + if (ast_sip_session_is_pending_stream_default(session, asterisk_stream) && media_type == AST_MEDIA_TYPE_AUDIO) { /* Check if incomming SDP is changing the remotely held state */ if (ast_sockaddr_isnull(addrs) || diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index 403c397f6c48fc07f0a510c256a33f0d010bf374..a962d70267f08f22fe5c7a78bfb5d4e3f1c2d462 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -273,6 +273,8 @@ struct ast_ice_host_candidate { /*! \brief List of ICE host candidate mappings */ static AST_RWLIST_HEAD_STATIC(host_candidates, ast_ice_host_candidate); +static char *generate_random_string(char *buf, size_t size); + #endif #define FLAG_3389_WARNING (1 << 0) @@ -766,14 +768,27 @@ static void ast_rtp_ice_candidate_destroy(void *obj) static void ast_rtp_ice_set_authentication(struct ast_rtp_instance *instance, const char *ufrag, const char *password) { struct ast_rtp *rtp = ast_rtp_instance_get_data(instance); + int ice_attrb_reset = 0; if (!ast_strlen_zero(ufrag)) { + if (!ast_strlen_zero(rtp->remote_ufrag) && strcmp(ufrag, rtp->remote_ufrag)) { + ice_attrb_reset = 1; + } ast_copy_string(rtp->remote_ufrag, ufrag, sizeof(rtp->remote_ufrag)); } if (!ast_strlen_zero(password)) { + if (!ast_strlen_zero(rtp->remote_passwd) && strcmp(password, rtp->remote_passwd)) { + ice_attrb_reset = 1; + } ast_copy_string(rtp->remote_passwd, password, sizeof(rtp->remote_passwd)); } + + /* If the remote ufrag or passwd changed, local ufrag and passwd need to regenerate */ + if (ice_attrb_reset) { + generate_random_string(rtp->local_ufrag, sizeof(rtp->local_ufrag)); + generate_random_string(rtp->local_passwd, sizeof(rtp->local_passwd)); + } } static int ice_candidate_cmp(void *obj, void *arg, int flags)