summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-06-30 19:51:28 +0000
committerJoshua Colp <jcolp@digium.com>2014-06-30 19:51:28 +0000
commit6e60f5d317d2bccaa556c98fbcc01d2db5796c1e (patch)
tree9d2e1bd2d26e584aa31e3b6b019ffe145784a2b2 /channels
parent688bb204dc872aaec9f2b829fe85039c08091b55 (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')
-rw-r--r--channels/chan_sip.c54
-rw-r--r--channels/sip/include/sip.h3
2 files changed, 44 insertions, 13 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);
}
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index ab151de10..11078d5b7 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -384,11 +384,12 @@
#define SIP_PAGE3_ICE_SUPPORT (1 << 6) /*!< DGP: Enable ICE support */
#define SIP_PAGE3_IGNORE_PREFCAPS (1 << 7) /*!< DP: Ignore prefcaps when setting up an outgoing call leg */
#define SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL (1 << 8) /*!< DGP: Stop telling the peer to start music on hold */
+#define SIP_PAGE3_FORCE_AVP (1 << 9) /*!< DGP: Force 'RTP/AVP' for all streams, even DTLS */
#define SIP_PAGE3_FLAGS_TO_COPY \
(SIP_PAGE3_SNOM_AOC | SIP_PAGE3_SRTP_TAG_32 | SIP_PAGE3_NAT_AUTO_RPORT | SIP_PAGE3_NAT_AUTO_COMEDIA | \
SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_USE_AVPF | SIP_PAGE3_ICE_SUPPORT | SIP_PAGE3_IGNORE_PREFCAPS | \
- SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL)
+ SIP_PAGE3_DISCARD_REMOTE_HOLD_RETRIEVAL | SIP_PAGE3_FORCE_AVP)
#define CHECK_AUTH_BUF_INITLEN 256