mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user