diff options
author | Joshua Colp <jcolp@digium.com> | 2014-06-30 19:51:28 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2014-06-30 19:51:28 +0000 |
commit | 6e60f5d317d2bccaa556c98fbcc01d2db5796c1e (patch) | |
tree | 9d2e1bd2d26e584aa31e3b6b019ffe145784a2b2 /channels/chan_sip.c | |
parent | 688bb204dc872aaec9f2b829fe85039c08091b55 (diff) |
Recorded merge of revisions 417677 from http://svn.asterisk.org/svn/asterisk/branches/11
........
res_rtp_asterisk: Add SHA-256 support for DTLS and perform DTLS negotiation on RTCP.
This change fixes up DTLS support in res_rtp_asterisk so it can accept and provide
a SHA-256 fingerprint, so it occurs on RTCP, and so it occurs after ICE negotiation
completes. Configuration options to chan_sip and chan_pjsip have also been added to
allow behavior to be tweaked (such as forcing the AVP type media transports in SDP).
ASTERISK-22961 #close
Reported by: Jay Jideliov
Review: https://reviewboard.asterisk.org/r/3679/
Review: https://reviewboard.asterisk.org/r/3686/
........
Merged revisions 417678 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417679 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r-- | channels/chan_sip.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2531061e7..35f5f5ef7 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1251,7 +1251,7 @@ static int process_sdp_a_text(const char *a, struct sip_pvt *p, struct ast_rtp_c static int process_sdp_a_image(const char *a, struct sip_pvt *p); static void add_ice_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf); static void add_dtls_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf); -static void start_ice(struct ast_rtp_instance *instance); +static void start_ice(struct ast_rtp_instance *instance, int offer); static void add_codec_to_sdp(const struct sip_pvt *p, struct ast_format *codec, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size, int *max_packet_size); @@ -10163,12 +10163,21 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action if (process_sdp_a_dtls(value, p, p->rtp)) { processed = TRUE; + if (p->srtp) { + ast_set_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK); + } } if (process_sdp_a_dtls(value, p, p->vrtp)) { processed = TRUE; + if (p->vsrtp) { + ast_set_flag(p->vsrtp, AST_SRTP_CRYPTO_OFFER_OK); + } } if (process_sdp_a_dtls(value, p, p->trtp)) { processed = TRUE; + if (p->tsrtp) { + ast_set_flag(p->tsrtp, AST_SRTP_CRYPTO_OFFER_OK); + } } break; @@ -10576,7 +10585,11 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action if (process_sdp_a_ice(value, p, p->rtp)) { processed = TRUE; } else if (process_sdp_a_dtls(value, p, p->rtp)) { + processed_crypto = TRUE; processed = TRUE; + if (p->srtp) { + ast_set_flag(p->srtp, AST_SRTP_CRYPTO_OFFER_OK); + } } else if (process_sdp_a_sendonly(value, &sendonly)) { processed = TRUE; } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) { @@ -10591,7 +10604,11 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action if (process_sdp_a_ice(value, p, p->vrtp)) { processed = TRUE; } else if (process_sdp_a_dtls(value, p, p->vrtp)) { + processed_crypto = TRUE; processed = TRUE; + if (p->vsrtp) { + ast_set_flag(p->vsrtp, AST_SRTP_CRYPTO_OFFER_OK); + } } else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) { processed_crypto = TRUE; processed = TRUE; @@ -10742,7 +10759,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action /* Setup audio address and port */ if (p->rtp) { if (sa && portno > 0) { - start_ice(p->rtp); + start_ice(p->rtp, (req->method != SIP_RESPONSE) ? 0 : 1); ast_sockaddr_set_port(sa, portno); ast_rtp_instance_set_remote_address(p->rtp, sa); if (debug) { @@ -10790,7 +10807,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action /* Setup video address and port */ if (p->vrtp) { if (vsa && vportno > 0) { - start_ice(p->vrtp); + start_ice(p->vrtp, (req->method != SIP_RESPONSE) ? 0 : 1); ast_sockaddr_set_port(vsa, vportno); ast_rtp_instance_set_remote_address(p->vrtp, vsa); if (debug) { @@ -10808,7 +10825,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action /* Setup text address and port */ if (p->trtp) { if (tsa && tportno > 0) { - start_ice(p->trtp); + start_ice(p->trtp, (req->method != SIP_RESPONSE) ? 0 : 1); ast_sockaddr_set_port(tsa, tportno); ast_rtp_instance_set_remote_address(p->trtp, tsa); if (debug) { @@ -11137,7 +11154,7 @@ static int process_sdp_a_dtls(const char *a, struct sip_pvt *p, struct ast_rtp_i { struct ast_rtp_engine_dtls *dtls; int found = FALSE; - char value[256], hash[6]; + char value[256], hash[32]; if (!instance || !p->dtls_cfg.enabled || !(dtls = ast_rtp_instance_get_dtls(instance))) { return found; @@ -11169,11 +11186,13 @@ static int process_sdp_a_dtls(const char *a, struct sip_pvt *p, struct ast_rtp_i ast_log(LOG_WARNING, "Unsupported connection attribute value '%s' received on dialog '%s'\n", value, p->callid); } - } else if (sscanf(a, "fingerprint: %5s %255s", hash, value) == 2) { + } else if (sscanf(a, "fingerprint: %31s %255s", hash, value) == 2) { found = TRUE; if (!strcasecmp(hash, "sha-1")) { dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA1, value); + } else if (!strcasecmp(hash, "sha-256")) { + dtls->set_fingerprint(instance, AST_RTP_DTLS_HASH_SHA256, value); } else { ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s' received on dialog '%s'\n", hash, p->callid); @@ -12820,7 +12839,7 @@ static void add_ice_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a } /*! \brief Start ICE negotiation on an RTP instance */ -static void start_ice(struct ast_rtp_instance *instance) +static void start_ice(struct ast_rtp_instance *instance, int offer) { struct ast_rtp_engine_ice *ice = ast_rtp_instance_get_ice(instance); @@ -12828,6 +12847,8 @@ static void start_ice(struct ast_rtp_instance *instance) return; } + /* If we are the offerer then we are the controlling agent, otherwise they are */ + ice->set_role(instance, offer ? AST_RTP_ICE_ROLE_CONTROLLING : AST_RTP_ICE_ROLE_CONTROLLED); ice->start(instance); } @@ -12835,6 +12856,7 @@ static void start_ice(struct ast_rtp_instance *instance) static void add_dtls_to_sdp(struct ast_rtp_instance *instance, struct ast_str **a_buf) { struct ast_rtp_engine_dtls *dtls; + enum ast_rtp_dtls_hash hash; const char *fingerprint; if (!instance || !(dtls = ast_rtp_instance_get_dtls(instance)) || !dtls->active(instance)) { @@ -12869,8 +12891,11 @@ static void add_dtls_to_sdp(struct ast_rtp_instance *instance, struct ast_str ** break; } - if ((fingerprint = dtls->get_fingerprint(instance, AST_RTP_DTLS_HASH_SHA1))) { - ast_str_append(a_buf, 0, "a=fingerprint:SHA-1 %s\r\n", fingerprint); + hash = dtls->get_fingerprint_hash(instance); + fingerprint = dtls->get_fingerprint(instance); + if (fingerprint && (hash == AST_RTP_DTLS_HASH_SHA1 || hash == AST_RTP_DTLS_HASH_SHA256)) { + ast_str_append(a_buf, 0, "a=fingerprint:%s %s\r\n", hash == AST_RTP_DTLS_HASH_SHA1 ? "SHA-1" : "SHA-256", + fingerprint); } } @@ -13343,7 +13368,8 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int ast_test_flag(&p->flags[2], SIP_PAGE3_SRTP_TAG_32)); ast_str_append(&m_video, 0, "m=video %d %s", ast_sockaddr_port(&vdest), ast_sdp_get_rtp_profile(v_a_crypto ? 1 : 0, p->vrtp, - ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF))); + ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF), + ast_test_flag(&p->flags[2], SIP_PAGE3_FORCE_AVP))); /* Build max bitrate string */ if (p->maxcallbitrate) @@ -13370,7 +13396,8 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int ast_test_flag(&p->flags[2], SIP_PAGE3_SRTP_TAG_32)); ast_str_append(&m_text, 0, "m=text %d %s", ast_sockaddr_port(&tdest), ast_sdp_get_rtp_profile(t_a_crypto ? 1 : 0, p->trtp, - ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF))); + ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF), + ast_test_flag(&p->flags[2], SIP_PAGE3_FORCE_AVP))); if (debug) { /* XXX should I use tdest below ? */ ast_verbose("Text is at %s\n", ast_sockaddr_stringify(&taddr)); } @@ -13393,7 +13420,8 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int ast_test_flag(&p->flags[2], SIP_PAGE3_SRTP_TAG_32)); ast_str_append(&m_audio, 0, "m=audio %d %s", ast_sockaddr_port(&dest), ast_sdp_get_rtp_profile(a_crypto ? 1 : 0, p->rtp, - ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF))); + ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF), + ast_test_flag(&p->flags[2], SIP_PAGE3_FORCE_AVP))); /* Now, start adding audio codecs. These are added in this order: - First what was requested by the calling channel @@ -30870,6 +30898,8 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_IGNORE_PREFCAPS); } else if (!strcasecmp(v->name, "discard_remote_hold_retrieval")) { ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL); + } else if (!strcasecmp(v->name, "force_avp")) { + ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_FORCE_AVP); } else { ast_rtp_dtls_cfg_parse(&peer->dtls_cfg, v->name, v->value); } |