[Pkg-voip-commits] [asterisk] 01/01: Merge branch 'master' into dtls-srtp-patch

Jeremy Lainé sharky at moszumanska.debian.org
Tue Jun 24 15:15:42 UTC 2014


This is an automated email from the git hooks/post-receive script.

sharky pushed a commit to branch dtls-srtp-patch
in repository asterisk.

commit b7bdf15252cab49e7491d485124943093de46471
Merge: de08810 b30399b
Author: Jeremy Lainé <jeremy.laine at m4x.org>
Date:   Tue Jun 24 17:14:33 2014 +0200

    Merge branch 'master' into dtls-srtp-patch
    
    Conflicts:
    	debian/changelog
    	debian/patches/series

 .version                                        |    2 +-
 CHANGES                                         |   23 +
 ChangeLog                                       | 2629 +++++++++++++++++++++++
 Makefile                                        |    6 +-
 Makefile.rules                                  |    2 +-
 UPGRADE.txt                                     |   90 +
 addons/chan_ooh323.c                            |  124 +-
 addons/ooh323c/src/ooCalls.h                    |    2 +-
 addons/ooh323c/src/ooCapability.c               |   16 +
 addons/ooh323c/src/ooCmdChannel.c               |   10 -
 addons/ooh323c/src/ooGkClient.c                 |   20 +-
 addons/ooh323c/src/ooGkClient.h                 |    3 +-
 addons/ooh323c/src/ooTimer.c                    |    6 +-
 addons/ooh323c/src/oochannels.c                 |    9 +-
 addons/ooh323c/src/ooh245.c                     |    8 +-
 addons/ooh323c/src/ooh323.c                     |   12 +-
 addons/ooh323c/src/ooq931.c                     |    2 +-
 apps/app_adsiprog.c                             |    4 +-
 apps/app_chanspy.c                              |   81 +-
 apps/app_confbridge.c                           |  188 +-
 apps/app_dial.c                                 |   16 +-
 apps/app_dumpchan.c                             |   30 +-
 apps/app_festival.c                             |    4 +-
 apps/app_forkcdr.c                              |   12 +-
 apps/app_getcpeid.c                             |   10 +-
 apps/app_jack.c                                 |    7 +-
 apps/app_meetme.c                               |   47 +-
 apps/app_minivm.c                               |    6 +-
 apps/app_mixmonitor.c                           |   10 +-
 apps/app_queue.c                                |  218 +-
 apps/app_sms.c                                  |   48 +-
 apps/app_speech_utils.c                         |    8 +-
 apps/app_stack.c                                |   26 +-
 apps/app_transfer.c                             |    4 +-
 apps/app_verbose.c                              |    8 +-
 apps/app_voicemail.c                            |   16 +-
 apps/confbridge/conf_config_parser.c            |   31 +-
 apps/confbridge/conf_state.c                    |    6 +-
 apps/confbridge/conf_state_empty.c              |    1 -
 apps/confbridge/conf_state_inactive.c           |    4 +-
 apps/confbridge/conf_state_multi.c              |    2 +
 apps/confbridge/conf_state_multi_marked.c       |   73 +-
 apps/confbridge/conf_state_single.c             |    5 +
 apps/confbridge/conf_state_single_marked.c      |    5 +
 apps/confbridge/include/confbridge.h            |   21 +-
 asterisk-11.10.2-summary.html                   |   68 +
 asterisk-11.10.2-summary.txt                    |  103 +
 asterisk-11.7.0-summary.html                    |  457 ----
 asterisk-11.7.0-summary.txt                     |  569 -----
 bridges/bridge_softmix.c                        |    8 +-
 build_tools/cflags.xml                          |    3 +
 cdr/cdr_adaptive_odbc.c                         |    6 +-
 cdr/cdr_radius.c                                |   10 +-
 cel/cel_manager.c                               |    9 +-
 cel/cel_odbc.c                                  |   10 +-
 cel/cel_pgsql.c                                 |   16 +-
 cel/cel_radius.c                                |   10 +-
 channels/chan_alsa.c                            |    8 +-
 channels/chan_dahdi.c                           |  164 +-
 channels/chan_gtalk.c                           |   14 +-
 channels/chan_iax2.c                            |  257 ++-
 channels/chan_jingle.c                          |   16 +-
 channels/chan_local.c                           |   15 +-
 channels/chan_mgcp.c                            |   76 +-
 channels/chan_motif.c                           |   16 +-
 channels/chan_oss.c                             |    4 +-
 channels/chan_phone.c                           |    6 +-
 channels/chan_sip.c                             |  937 ++++----
 channels/chan_skinny.c                          |  110 +-
 channels/chan_unistim.c                         |  151 +-
 channels/iax2-parser.c                          |    6 +-
 channels/sig_analog.c                           |   30 +-
 channels/sig_pri.c                              | 1068 +++++----
 channels/sip/config_parser.c                    |    4 +-
 channels/sip/include/sip.h                      |   14 +-
 channels/sip/security_events.c                  |    4 +-
 configs/agents.conf.sample                      |    5 -
 configs/asterisk.conf.sample                    |    1 -
 configs/confbridge.conf.sample                  |   14 +-
 configs/http.conf.sample                        |    6 +
 configs/iax.conf.sample                         |   20 +-
 configs/indications.conf.sample                 |   12 +-
 configs/logger.conf.sample                      |   19 +-
 configs/manager.conf.sample                     |   13 +-
 configs/queues.conf.sample                      |    2 +-
 configs/res_fax.conf.sample                     |   10 +-
 configs/res_odbc.conf.sample                    |   12 +-
 configs/sip.conf.sample                         |   24 +-
 configs/voicemail.conf.sample                   |    3 +-
 configure                                       |  889 +++++---
 configure.ac                                    |   30 +-
 contrib/scripts/astgenkey                       |    2 +-
 contrib/scripts/astgenkey.8                     |    2 +-
 contrib/scripts/install_prereq                  |    6 +-
 contrib/scripts/refcounter.py                   |  171 ++
 debian/asterisk.postrm                          |    4 +-
 debian/asterisk.prerm                           |    4 +-
 debian/changelog                                |   74 +-
 debian/control                                  |    4 +-
 debian/patches/dahdi_pri_event_removed          |  155 --
 debian/patches/dtls_srtp.patch                  | 1203 +++++++++++
 debian/patches/dtls_srtp_patch                  | 1213 -----------
 debian/patches/escape_manpage_hyphen.patch      |   19 +
 debian/patches/freeradius-client                |   74 -
 debian/patches/hyphen                           |  267 ---
 debian/patches/pjproject                        |   23 +-
 debian/patches/pri_destroy_span_prilist.patch   |  136 ++
 debian/patches/series                           |   13 +-
 debian/patches/sigpri_handle_enodev_1.patch     |   77 +
 debian/patches/smsq_enable.patch                |   13 +
 debian/patches/smsq_manpage.patch               |  154 ++
 debian/patches/suppress_warning_rasterisk.patch |   42 -
 debian/upstream/signing-key.asc                 |  224 ++
 debian/watch                                    |    4 +-
 doc/asterisk.8                                  |  100 +-
 formats/format_pcm.c                            |   10 +-
 formats/format_wav.c                            |    4 +-
 funcs/func_audiohookinherit.c                   |    5 +
 funcs/func_blacklist.c                          |    7 +-
 funcs/func_callcompletion.c                     |   12 +-
 funcs/func_callerid.c                           |   12 +-
 funcs/func_channel.c                            |   30 +-
 funcs/func_db.c                                 |    2 +-
 funcs/func_dialplan.c                           |   14 +-
 funcs/func_env.c                                |    8 +-
 funcs/func_frame_trace.c                        |    7 +-
 funcs/func_global.c                             |    8 +-
 funcs/func_groupcount.c                         |   21 +-
 funcs/func_hangupcause.c                        |    4 +-
 funcs/func_iconv.c                              |    4 +-
 funcs/func_jitterbuffer.c                       |    7 +-
 funcs/func_lock.c                               |    2 +-
 funcs/func_math.c                               |    7 +-
 funcs/func_odbc.c                               |    7 +-
 funcs/func_pitchshift.c                         |    7 +-
 funcs/func_presencestate.c                      |    4 +-
 funcs/func_realtime.c                           |    2 +-
 funcs/func_shell.c                              |    2 +-
 funcs/func_speex.c                              |    7 +-
 funcs/func_srv.c                                |    8 +-
 funcs/func_strings.c                            |   96 +-
 funcs/func_sysinfo.c                            |   12 +-
 funcs/func_timeout.c                            |   18 +-
 funcs/func_volume.c                             |   11 +-
 include/asterisk.h                              |   16 +
 include/asterisk/astobj.h                       |    2 +-
 include/asterisk/astobj2.h                      |  129 +-
 include/asterisk/autoconfig.h.in                |   21 +-
 include/asterisk/channel.h                      |    5 +
 include/asterisk/devicestate.h                  |    1 -
 include/asterisk/frame.h                        |   26 +
 include/asterisk/logger.h                       |  101 +-
 include/asterisk/message.h                      |   12 +-
 include/asterisk/options.h                      |    8 +-
 include/asterisk/res_odbc.h                     |    6 +
 include/asterisk/rtp_engine.h                   |   12 +-
 include/asterisk/tcptls.h                       |   63 +-
 include/asterisk/test.h                         |    2 +-
 include/asterisk/utils.h                        |    1 +
 main/Makefile                                   |    4 +-
 main/abstract_jb.c                              |    4 +-
 main/acl.c                                      |    4 +-
 main/adsi.c                                     |    2 +-
 main/aoc.c                                      |    6 +-
 main/app.c                                      |    8 +-
 main/asterisk.c                                 |  249 ++-
 main/astobj2.c                                  |   62 +-
 main/audiohook.c                                |    8 +-
 main/autoservice.c                              |   10 +-
 main/bridging.c                                 |   14 +-
 main/callerid.c                                 |   12 +-
 main/ccss.c                                     |   24 +-
 main/cel.c                                      |  277 ++-
 main/channel.c                                  |  203 +-
 main/cli.c                                      |  367 ++--
 main/config.c                                   |  123 +-
 main/config_options.c                           |    8 +-
 main/data.c                                     |   15 +-
 main/db.c                                       |   49 +-
 main/devicestate.c                              |    8 +-
 main/dsp.c                                      |    4 +-
 main/enum.c                                     |    6 +-
 main/event.c                                    |    6 +-
 main/features.c                                 |   48 +-
 main/file.c                                     |    6 +-
 main/format.c                                   |   16 +-
 main/frame.c                                    |   10 +-
 main/http.c                                     |  115 +-
 main/io.c                                       |    6 +-
 main/loader.c                                   |   34 +-
 main/logger.c                                   |  257 ++-
 main/manager.c                                  |  527 +++--
 main/message.c                                  |   70 +-
 main/netsock.c                                  |    8 +-
 main/pbx.c                                      |   65 +-
 main/rtp_engine.c                               |   44 +-
 main/say.c                                      |   16 +-
 main/sched.c                                    |    8 +-
 main/security_events.c                          |    8 +-
 main/slinfactory.c                              |    4 +-
 main/stdtime/localtime.c                        |    4 +-
 main/stun.c                                     |   12 +-
 main/taskprocessor.c                            |    4 +-
 main/tcptls.c                                   |  551 ++++-
 main/translate.c                                |   65 +-
 main/udptl.c                                    |   16 +-
 main/utils.c                                    |   36 +-
 main/xmldoc.c                                   |    5 +-
 pbx/dundi-parser.c                              |   10 +-
 pbx/pbx_config.c                                |    4 +-
 pbx/pbx_dundi.c                                 |   12 +-
 pbx/pbx_lua.c                                   |   13 +-
 res/Makefile                                    |    6 +-
 res/ael/pval.c                                  |    5 +-
 res/res_agi.c                                   |    6 +-
 res/res_calendar.c                              |   18 +-
 res/res_calendar_caldav.c                       |    9 +-
 res/res_calendar_ews.c                          |    4 +-
 res/res_calendar_exchange.c                     |    6 +-
 res/res_calendar_icalendar.c                    |    4 +-
 res/res_clialiases.c                            |   38 +-
 res/res_config_odbc.c                           |  115 +-
 res/res_config_pgsql.c                          |   56 +-
 res/res_corosync.c                              |   12 +-
 res/res_crypto.c                                |    4 +-
 res/res_fax.c                                   |   77 +-
 res/res_fax_spandsp.c                           |   56 +-
 res/res_format_attr_celt.c                      |    8 +-
 res/res_format_attr_h263.c                      |   10 +-
 res/res_format_attr_h264.c                      |   10 +-
 res/res_format_attr_silk.c                      |   12 +-
 res/res_http_websocket.c                        |  253 ++-
 res/res_jabber.c                                |   32 +-
 res/res_monitor.c                               |    6 +-
 res/res_musiconhold.c                           |   86 +-
 res/res_mutestream.c                            |    7 +-
 res/res_odbc.c                                  |   16 +-
 res/res_odbc.exports.in                         |    1 +
 res/res_pktccops.c                              |   23 +-
 res/res_rtp_asterisk.c                          |  398 +++-
 res/res_srtp.c                                  |   12 +-
 res/res_stun_monitor.c                          |    4 +-
 res/res_timing_dahdi.c                          |    6 +-
 res/res_xmpp.c                                  |   14 +-
 sounds/Makefile                                 |   11 +-
 sounds/sounds.xml                               |  117 +-
 utils/astman.c                                  |    3 +-
 utils/conf2ael.c                                |    4 +-
 utils/extconf.c                                 |   43 +-
 249 files changed, 12209 insertions(+), 6541 deletions(-)

diff --cc debian/changelog
index b12e389,d74f9f8..a688570
--- a/debian/changelog
+++ b/debian/changelog
@@@ -1,10 -1,74 +1,74 @@@
- asterisk (1:11.7.0~dfsg-1+e1) experimental; urgency=low
 -asterisk (1:11.10.2~dfsg-2) UNRELEASED; urgency=medium
++asterisk (1:11.10.2~dfsg-1+e1) experimental; urgency=low
  
-   * Add the DTLS-SRTP patch for Firefox WebRTC support
-   * suppress_warning_rasterisk.patch: rasterisk should not print a
-     warning.
 -  * Remove svn-upgrade from watch file.
++  * Add the DTLS-SRTP patch for WebRTC support.
  
-  -- Daniel Pocock <daniel at pocock.com.au>  Thu, 06 Feb 2014 12:28:37 +0100
 - -- Jeremy Lainé <jeremy.laine at m4x.org>  Tue, 17 Jun 2014 13:03:24 +0200
++ -- Jeremy Lainé <jeremy.laine at m4x.org>  Tue, 24 Jun 2014 17:10:32 +0200
+ 
+ asterisk (1:11.10.2~dfsg-1) unstable; urgency=high
+ 
+   * New upstream security release, fixes:
+     - AST-2014-006: Asterisk Manager User Unauthorized Shell Access
+     - AST-2014-007: Exhaustion of Allowed Concurrent HTTP Connections
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Fri, 13 Jun 2014 22:02:37 +0200
+ 
+ asterisk (1:11.10.0~dfsg-1) unstable; urgency=medium
+ 
+   * New upstream release.
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Mon, 02 Jun 2014 16:06:27 +0200
+ 
+ asterisk (1:11.9.0~dfsg-2) unstable; urgency=medium
+ 
+   * Rollback changes to init script (Closes: #749024).
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Tue, 27 May 2014 09:17:06 +0200
+ 
+ asterisk (1:11.9.0~dfsg-1) unstable; urgency=medium
+ 
+   [ Jeremy Lainé ]
+   * New upstream release.
+     - Drop ASTERISK-23310 patch, fixed upstream.
+     - Drop dahdi_pri_event_removed patch, fixed upstream.
+     - Drop freeradius-client patch, fixed upstream.
+     - Update pjproject patch.
+   * Provide a manpage for smsq.
+   * Use "set -e" in asterisk.(postrm|prerm) (fixes lintian warning).
+   * Add upstream GPG signature check to watch file.
+   * Add Daniel Pocock to uploaders.
+ 
+   [ Daniel Pocock ]
+   * Make init script more adaptable for multiple instances.
+ 
+   [ Tzafrir Cohen ]
+   * pri_destroy_span_prilist.patch, sigpri_handle_enodev_1.patch: fix
+     regressions due to dahdi_pri_event_removed.
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Wed, 21 May 2014 12:03:09 +0200
+ 
+ asterisk (1:11.8.1~dfsg-1) unstable; urgency=high
+ 
+   * New upstream security release (Closes: #741313).
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Tue, 11 Mar 2014 07:44:54 +0100
+ 
+ asterisk (1:11.8.0~dfsg-2) unstable; urgency=medium
+ 
+   * Really fix versioned Breaks/Replaces for asterisk-dahdi (Closes: #732419).
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Thu, 06 Mar 2014 07:38:11 +0100
+ 
+ asterisk (1:11.8.0~dfsg-1) unstable; urgency=low
+ 
+   [ Jeremy Lainé ]
+   * New upstream release.
+     - rasterisk no longer prints a warning when live_dangerously is set.
+   * Patch ASTERISK-23310: fixes crash when a leg of a remote RTP bridge fails.
+ 
+   [ Frederic Van Espen ]
+   * smsq_enable.patch: enable smsq compilation (Closes: #738588)
+ 
+  -- Jeremy Lainé <jeremy.laine at m4x.org>  Tue, 04 Mar 2014 16:27:58 +0100
  
  asterisk (1:11.7.0~dfsg-1) unstable; urgency=high
  
diff --cc debian/patches/dtls_srtp.patch
index 0000000,0000000..d7c0c9b
new file mode 100644
--- /dev/null
+++ b/debian/patches/dtls_srtp.patch
@@@ -1,0 -1,0 +1,1203 @@@
++diff --git a/channels/chan_sip.c b/channels/chan_sip.c
++index 72a7165..9fc7c74 100644
++--- a/channels/chan_sip.c
+++++ b/channels/chan_sip.c
++@@ -1387,7 +1387,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);
++@@ -7280,6 +7280,11 @@ static int sip_answer(struct ast_channel *ast)
++ 		ast_rtp_instance_update_source(p->rtp);
++ 		res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, oldsdp, TRUE);
++ 		ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
+++		/* RFC says the session timer starts counting on 200,
+++		 * not on INVITE. */
+++		if (p->stimer->st_active == TRUE) {
+++			start_session_timer(p);
+++		}
++ 	}
++ 	sip_pvt_unlock(p);
++ 	return res;
++@@ -10045,12 +10050,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, SRTP_CRYPTO_OFFER_OK);
+++				}
++ 			}
++ 			if (process_sdp_a_dtls(value, p, p->vrtp)) {
++ 				processed = TRUE;
+++				if (p->vsrtp) {
+++					ast_set_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK);
+++				}
++ 			}
++ 			if (process_sdp_a_dtls(value, p, p->trtp)) {
++ 				processed = TRUE;
+++				if (p->tsrtp) {
+++					ast_set_flag(p->tsrtp, SRTP_CRYPTO_OFFER_OK);
+++				}
++ 			}
++ 
++ 			break;
++@@ -10456,7 +10470,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, 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)) {
++@@ -10471,7 +10489,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, SRTP_CRYPTO_OFFER_OK);
+++						}
++ 					} else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
++ 						processed_crypto = TRUE;
++ 						processed = TRUE;
++@@ -10622,7 +10644,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) {
++@@ -10670,7 +10692,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) {
++@@ -10688,7 +10710,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) {
++@@ -11015,7 +11037,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;
++@@ -11047,11 +11069,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);
++@@ -12691,7 +12715,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);
++ 
++@@ -12699,6 +12723,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);
++ }
++ 
++@@ -12706,6 +12732,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)) {
++@@ -12740,8 +12767,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);
++ 	}
++ }
++ 
++@@ -13049,7 +13079,11 @@ static char *get_sdp_rtp_profile(const struct sip_pvt *p, unsigned int secure, s
++ 	struct ast_rtp_engine_dtls *dtls;
++ 
++ 	if ((dtls = ast_rtp_instance_get_dtls(instance)) && dtls->active(instance)) {
++-		return ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF) ? "UDP/TLS/RTP/SAVPF" : "UDP/TLS/RTP/SAVP";
+++		if (ast_test_flag(&p->flags[2], SIP_PAGE3_FORCE_AVP)) {
+++			return ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF) ? "RTP/SAVPF" : "RTP/SAVP";
+++		} else {
+++			return ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF) ? "UDP/TLS/RTP/SAVPF" : "UDP/TLS/RTP/SAVP";
+++		}
++ 	} else {
++ 		if (ast_test_flag(&p->flags[2], SIP_PAGE3_USE_AVPF)) {
++ 			return secure ? "RTP/SAVPF" : "RTP/AVPF";
++@@ -25815,12 +25849,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
++ 	/* Check if OLI/ANI-II is present in From: */
++ 	parse_oli(req, p->owner);
++ 
++-	if (p->stimer->st_active == TRUE) {
++-		if (reinvite == 0) {
++-			start_session_timer(p);
++-		} else {
++-			restart_session_timer(p);
++-		}
+++	if (reinvite && p->stimer->st_active == TRUE) {
+++		restart_session_timer(p);
++ 	}
++ 
++ 	if (!req->ignore && p)
++@@ -26903,7 +26933,9 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req)
++ 	}
++ 
++ 	stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
++-	stop_session_timer(p); /* Stop Session-Timer */
+++	if (p->stimer) {
+++		stop_session_timer(p); /* Stop Session-Timer */
+++	}
++ 
++ 	if (!ast_strlen_zero(sip_get_header(req, "Also"))) {
++ 		ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
++@@ -29206,11 +29238,6 @@ static void acl_change_event_cb(const struct ast_event *event, void *userdata)
++ /*! \brief Session-Timers: Restart session timer */
++ static void restart_session_timer(struct sip_pvt *p)
++ {
++-	if (!p->stimer) {
++-		ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid);
++-		return;
++-	}
++-
++ 	if (p->stimer->st_active == TRUE) {
++ 		ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
++ 		AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
++@@ -29223,11 +29250,6 @@ static void restart_session_timer(struct sip_pvt *p)
++ /*! \brief Session-Timers: Stop session timer */
++ static void stop_session_timer(struct sip_pvt *p)
++ {
++-	if (!p->stimer) {
++-		ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid);
++-		return;
++-	}
++-
++ 	if (p->stimer->st_active == TRUE) {
++ 		p->stimer->st_active = FALSE;
++ 		ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
++@@ -29242,11 +29264,6 @@ static void start_session_timer(struct sip_pvt *p)
++ {
++ 	unsigned int timeout_ms;
++ 
++-	if (!p->stimer) {
++-		ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid);
++-		return;
++-	}
++-
++ 	if (p->stimer->st_schedid > -1) {
++ 		/* in the event a timer is already going, stop it */
++ 		ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
++@@ -29338,7 +29355,11 @@ return_unref:
++ 		/* An error occurred.  Stop session timer processing */
++ 		if (p->stimer) {
++ 			ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
+++			/* Don't pass go, don't collect $200.. we are the scheduled
+++			 * callback. We can rip ourself out here. */
++ 			p->stimer->st_schedid = -1;
+++			/* Calling stop_session_timer is nice for consistent debug
+++			 * logs. */
++ 			stop_session_timer(p);
++ 		}
++ 
++@@ -31105,6 +31126,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_USE_AVPF);
++ 			} else if (!strcasecmp(v->name, "icesupport")) {
++ 				ast_set2_flag(&peer->flags[2], ast_true(v->value), SIP_PAGE3_ICE_SUPPORT);
+++			} 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 99a0dae..36a3faa 100644
++--- a/channels/sip/include/sip.h
+++++ b/channels/sip/include/sip.h
++@@ -379,10 +379,11 @@
++ #define SIP_PAGE3_DIRECT_MEDIA_OUTGOING  (1 << 4)  /*!< DP: Only send direct media reinvites on outgoing calls */
++ #define SIP_PAGE3_USE_AVPF               (1 << 5)  /*!< DGP: Support a minimal AVPF-compatible profile */
++ #define SIP_PAGE3_ICE_SUPPORT            (1 << 6)  /*!< DGP: Enable ICE support */
+++#define SIP_PAGE3_FORCE_AVP              (1 << 7)  /*!< 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_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_USE_AVPF | SIP_PAGE3_ICE_SUPPORT | SIP_PAGE3_FORCE_AVP)
++ 
++ #define CHECK_AUTH_BUF_INITLEN   256
++ 
++diff --git a/channels/sip/sdp_crypto.c b/channels/sip/sdp_crypto.c
++index cacdcbe..f6d9dd2 100644
++--- a/channels/sip/sdp_crypto.c
+++++ b/channels/sip/sdp_crypto.c
++@@ -282,7 +282,7 @@ int sdp_crypto_process(struct sdp_crypto *p, const char *attr, struct ast_rtp_in
++ 	}
++ 
++ 	if (!p->tag) {
++-		ast_log(LOG_DEBUG, "Accepting crypto tag %s\n", tag);
+++		ast_debug(1, "Accepting crypto tag %s\n", tag);
++ 		p->tag = ast_strdup(tag);
++ 		if (!p->tag) {
++ 			ast_log(LOG_ERROR, "Could not allocate memory for tag\n");
++@@ -307,7 +307,7 @@ int sdp_crypto_offer(struct sdp_crypto *p, int taglen)
++ 		return -1;
++ 	}
++ 
++-	ast_log(LOG_DEBUG, "Crypto line: %s", p->a_crypto);
+++	ast_debug(1, "Crypto line: %s", p->a_crypto);
++ 
++ 	return 0;
++ }
++diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
++index 962806e..00a5d33 100644
++--- a/configs/sip.conf.sample
+++++ b/configs/sip.conf.sample
++@@ -1026,6 +1026,8 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
++ ;avpf=yes                       ; Enable inter-operability with media streams using the AVPF RTP profile.
++ 				; This will cause all offers and answers to use AVPF (or SAVPF). This
++ 				; option may be specified at the global or peer scope.
+++;force_avp=yes			; Force 'RTP/AVP', 'RTP/AVPF', 'RTP/SAVP', and 'RTP/SAVPF' to be used for
+++				; media streams when appropriate, even if a DTLS stream is present.
++ ;----------------------------------------- REALTIME SUPPORT ------------------------
++ ; For additional information on ARA, the Asterisk Realtime Architecture,
++ ; please read https://wiki.asterisk.org/wiki/display/AST/Realtime+Database+Configuration
++@@ -1281,6 +1283,7 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
++ ; dtlscafile
++ ; dtlscapath
++ ; dtlssetup
+++; dtlsfingerprint
++ ;
++ 
++ ;------------------------------------------------------------------------------
++@@ -1289,7 +1292,11 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
++ ; DTLS-SRTP support is available if the underlying RTP engine in use supports it.
++ ;
++ ; dtlsenable = yes                   ; Enable or disable DTLS-SRTP support
++-; dtlsverify = yes                   ; Verify that the provided peer certificate is valid
+++; dtlsverify = yes                   ; Verify that provided peer certificate and fingerprint are valid
+++;				     ; A value of 'yes' will perform both certificate and fingerprint verification
+++;				     ; A value of 'no' will perform no certificate or fingerprint verification
+++;				     ; A value of 'fingerprint' will perform ONLY fingerprint verification
+++;				     ; A value of 'certificate' will perform ONLY certficiate verification
++ ; dtlsrekey = 60                     ; Interval at which to renegotiate the TLS session and rekey the SRTP session
++ ;                                    ; If this is not set or the value provided is 0 rekeying will be disabled
++ ; dtlscertfile = file                ; Path to certificate file to present
++@@ -1304,6 +1311,7 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
++ ;                                    ; accept connections only), and actpass (we will do both). This value will be used in
++ ;                                    ; the outgoing SDP when offering and for incoming SDP offers when the remote party sends
++ ;                                    ; actpass
+++; dtlsfingerprint = sha-1            ; The hash to use for the fingerprint in SDP (valid options are sha-1 and sha-256)
++ 
++ ;[sip_proxy]
++ ; For incoming calls only. Example: FWD (Free World Dialup)
++diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
++index 91e6335..9d8d293 100644
++--- a/include/asterisk/rtp_engine.h
+++++ b/include/asterisk/rtp_engine.h
++@@ -328,6 +328,12 @@ enum ast_rtp_ice_component_type {
++ 	AST_RTP_ICE_COMPONENT_RTCP = 2,
++ };
++ 
+++/*! \brief ICE role during negotiation */
+++enum ast_rtp_ice_role {
+++	AST_RTP_ICE_ROLE_CONTROLLED,
+++	AST_RTP_ICE_ROLE_CONTROLLING,
+++};
+++
++ /*! \brief Structure for an ICE candidate */
++ struct ast_rtp_engine_ice_candidate {
++ 	char *foundation;                     /*!< Foundation identifier */
++@@ -357,6 +363,8 @@ struct ast_rtp_engine_ice {
++ 	struct ao2_container *(*get_local_candidates)(struct ast_rtp_instance *instance);
++ 	/*! Callback for telling the ICE support that it is talking to an ice-lite implementation */
++ 	void (*ice_lite)(struct ast_rtp_instance *instance);
+++	/*! Callback for changing our role in negotiation */
+++	void (*set_role)(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role);
++ };
++ 
++ /*! \brief DTLS setup types */
++@@ -369,22 +377,31 @@ enum ast_rtp_dtls_setup {
++ 
++ /*! \brief DTLS connection states */
++ enum ast_rtp_dtls_connection {
++-        AST_RTP_DTLS_CONNECTION_NEW,      /*!< Endpoint wants to use a new connection */
+++	AST_RTP_DTLS_CONNECTION_NEW,      /*!< Endpoint wants to use a new connection */
++ 	AST_RTP_DTLS_CONNECTION_EXISTING, /*!< Endpoint wishes to use existing connection */
++ };
++ 
++ /*! \brief DTLS fingerprint hashes */
++ enum ast_rtp_dtls_hash {
++-	AST_RTP_DTLS_HASH_SHA1, /*!< SHA-1 fingerprint hash */
+++	AST_RTP_DTLS_HASH_SHA256, /*!< SHA-256 fingerprint hash */
+++	AST_RTP_DTLS_HASH_SHA1,   /*!< SHA-1 fingerprint hash */
+++};
+++
+++/*! \brief DTLS verification settings */
+++enum ast_rtp_dtls_verify {
+++	AST_RTP_DTLS_VERIFY_NONE = 0,		 		/*!< Don't verify anything */
+++	AST_RTP_DTLS_VERIFY_FINGERPRINT = (1 << 0), /*!< Verify the fingerprint */
+++	AST_RTP_DTLS_VERIFY_CERTIFICATE = (1 << 1), /*!< Verify the certificate */
++ };
++ 
++ /*! \brief DTLS configuration structure */
++ struct ast_rtp_dtls_cfg {
++ 	unsigned int enabled:1;                /*!< Whether DTLS support is enabled or not */
++-	unsigned int verify:1;                 /*!< Whether to request and verify a client certificate when acting as server */
++ 	unsigned int rekey;                    /*!< Interval at which to renegotiate and rekey - defaults to 0 (off) */
++ 	enum ast_rtp_dtls_setup default_setup; /*!< Default setup type to use for outgoing */
++ 	enum ast_srtp_suite suite;             /*!< Crypto suite in use */
+++	enum ast_rtp_dtls_hash hash;		   /*!< Hash to use for fingerprint */
+++	enum ast_rtp_dtls_verify verify;	   /*!< What should be verified */
++ 	char *certfile;                        /*!< Certificate file */
++ 	char *pvtfile;                         /*!< Private key file */
++ 	char *cipher;                          /*!< Cipher to use */
++@@ -410,8 +427,10 @@ struct ast_rtp_engine_dtls {
++ 	void (*set_setup)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup);
++ 	/*! Set the remote fingerprint */
++ 	void (*set_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint);
+++	/*! Get the local fingerprint hash type */
+++	enum ast_rtp_dtls_hash (*get_fingerprint_hash)(struct ast_rtp_instance *instance);
++ 	/*! Get the local fingerprint */
++-	const char *(*get_fingerprint)(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash);
+++	const char *(*get_fingerprint)(struct ast_rtp_instance *instance);
++ };
++ 
++ /*! Structure that represents an RTP stack (engine) */
++diff --git a/main/rtp_engine.c b/main/rtp_engine.c
++index b84951a..9a790f1 100644
++--- a/main/rtp_engine.c
+++++ b/main/rtp_engine.c
++@@ -2109,7 +2109,17 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name,
++ 	if (!strcasecmp(name, "dtlsenable")) {
++ 		dtls_cfg->enabled = ast_true(value) ? 1 : 0;
++ 	} else if (!strcasecmp(name, "dtlsverify")) {
++-		dtls_cfg->verify = ast_true(value) ? 1 : 0;
+++		if (!strcasecmp(value, "yes")) {
+++			dtls_cfg->verify = AST_RTP_DTLS_VERIFY_FINGERPRINT | AST_RTP_DTLS_VERIFY_CERTIFICATE;
+++		} else if (!strcasecmp(value, "fingerprint")) {
+++			dtls_cfg->verify = AST_RTP_DTLS_VERIFY_FINGERPRINT;
+++		} else if (!strcasecmp(value, "certificate")) {
+++			dtls_cfg->verify = AST_RTP_DTLS_VERIFY_CERTIFICATE;
+++		} else if (!strcasecmp(value, "no")) {
+++			dtls_cfg->verify = AST_RTP_DTLS_VERIFY_NONE;
+++		} else {
+++			return -1;
+++		}
++ 	} else if (!strcasecmp(name, "dtlsrekey")) {
++ 		if (sscanf(value, "%30u", &dtls_cfg->rekey) != 1) {
++ 			return -1;
++@@ -2137,6 +2147,12 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name,
++ 		} else if (!strcasecmp(value, "actpass")) {
++ 			dtls_cfg->default_setup = AST_RTP_DTLS_SETUP_ACTPASS;
++ 		}
+++	} else if (!strcasecmp(name, "dtlsfingerprint")) {
+++		if (!strcasecmp(value, "sha-256")) {
+++			dtls_cfg->hash = AST_RTP_DTLS_HASH_SHA256;
+++		} else if (!strcasecmp(value, "sha-1")) {
+++			dtls_cfg->hash = AST_RTP_DTLS_HASH_SHA1;
+++		}
++ 	} else {
++ 		return -1;
++ 	}
++@@ -2150,6 +2166,7 @@ void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rt
++ 	dst_cfg->verify = src_cfg->verify;
++ 	dst_cfg->rekey = src_cfg->rekey;
++ 	dst_cfg->suite = src_cfg->suite;
+++	dst_cfg->hash = src_cfg->hash;
++ 	dst_cfg->certfile = ast_strdup(src_cfg->certfile);
++ 	dst_cfg->pvtfile = ast_strdup(src_cfg->pvtfile);
++ 	dst_cfg->cipher = ast_strdup(src_cfg->cipher);
++diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
++index 4853a0f..3bd24a8 100644
++--- a/res/res_rtp_asterisk.c
+++++ b/res/res_rtp_asterisk.c
++@@ -288,11 +288,13 @@ struct ast_rtp {
++ 	BIO *write_bio;   /*!< Memory buffer for writing */
++ 	ast_mutex_t dtls_timer_lock;           /*!< Lock for synchronization purposes */
++ 	enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
+++	enum ast_rtp_dtls_verify dtls_verify; /*!< What to verify */
++ 	enum ast_srtp_suite suite;   /*!< SRTP crypto suite */
+++	enum ast_rtp_dtls_hash local_hash; /*!< Local hash used for the fingerprint */
++ 	char local_fingerprint[160]; /*!< Fingerprint of our certificate */
+++	enum ast_rtp_dtls_hash remote_hash; /*!< Remote hash used for the fingerprint */
++ 	unsigned char remote_fingerprint[EVP_MAX_MD_SIZE]; /*!< Fingerprint of the peer certificate */
++ 	enum ast_rtp_dtls_connection connection; /*!< Whether this is a new or existing connection */
++-	unsigned int dtls_failure:1; /*!< Failure occurred during DTLS negotiation */
++ 	unsigned int rekey; /*!< Interval at which to renegotiate and rekey */
++ 	int rekeyid; /*!< Scheduled item id for rekeying */
++ 	int dtlstimerid; /*!< Scheduled item id for DTLS retransmission for RTP */
++@@ -358,6 +360,14 @@ struct ast_rtcp {
++ 	double normdevrtt;
++ 	double stdevrtt;
++ 	unsigned int rtt_count;
+++
+++#ifdef HAVE_OPENSSL_SRTP
+++	SSL *ssl;         /*!< SSL session */
+++	BIO *read_bio;    /*!< Memory buffer for reading */
+++	BIO *write_bio;   /*!< Memory buffer for writing */
+++	enum ast_rtp_dtls_setup dtls_setup; /*!< Current setup state */
+++	enum ast_rtp_dtls_connection connection; /*!< Whether this is a new or existing connection */
+++#endif
++ };
++ 
++ struct rtp_red {
++@@ -405,7 +415,7 @@ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level);
++ 
++ #ifdef HAVE_OPENSSL_SRTP
++ static int ast_rtp_activate(struct ast_rtp_instance *instance);
++-static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp);
+++static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp, int rtcp);
++ #endif
++ 
++ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *ice, int use_srtp);
++@@ -541,9 +551,18 @@ static void ast_rtp_ice_stop(struct ast_rtp_instance *instance)
++ static int ice_reset_session(struct ast_rtp_instance *instance)
++ {
++ 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+++	pj_ice_sess_role role = rtp->ice->role;
+++	int res;
++ 
++ 	ast_rtp_ice_stop(instance);
++-	return ice_create(instance, &rtp->ice_original_rtp_addr, rtp->ice_port, 1);
+++	
+++	res = ice_create(instance, &rtp->ice_original_rtp_addr, rtp->ice_port, 1);
+++	if (!res) {
+++		/* Preserve the role that the old ICE session used */
+++		pj_ice_sess_change_role(rtp->ice, role);
+++	}
+++
+++	return res;
++ }
++ 
++ static int ice_candidates_compare(struct ao2_container *left, struct ao2_container *right)
++@@ -700,6 +719,20 @@ static void ast_rtp_ice_lite(struct ast_rtp_instance *instance)
++ 	pj_ice_sess_change_role(rtp->ice, PJ_ICE_SESS_ROLE_CONTROLLING);
++ }
++ 
+++static void ast_rtp_ice_set_role(struct ast_rtp_instance *instance, enum ast_rtp_ice_role role)
+++{
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+++
+++	if (!rtp->ice) {
+++		return;
+++	}
+++
+++	pj_thread_register_check();
+++
+++	pj_ice_sess_change_role(rtp->ice, role == AST_RTP_ICE_ROLE_CONTROLLED ?
+++		PJ_ICE_SESS_ROLE_CONTROLLED : PJ_ICE_SESS_ROLE_CONTROLLING);
+++}
+++
++ static void ast_rtp_ice_add_cand(struct ast_rtp *rtp, unsigned comp_id, unsigned transport_id, pj_ice_cand_type type, pj_uint16_t local_pref,
++ 					const pj_sockaddr_t *addr, const pj_sockaddr_t *base_addr, const pj_sockaddr_t *rel_addr, int addr_len)
++ {
++@@ -779,20 +812,67 @@ static struct ast_rtp_engine_ice ast_rtp_ice = {
++ 	.get_password = ast_rtp_ice_get_password,
++ 	.get_local_candidates = ast_rtp_ice_get_local_candidates,
++ 	.ice_lite = ast_rtp_ice_lite,
+++	.set_role = ast_rtp_ice_set_role,
++ };
++ #endif
++ 
++ #ifdef HAVE_OPENSSL_SRTP
++-static void dtls_info_callback(const SSL *ssl, int where, int ret)
+++static int dtls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
+++{
+++	/* We don't want to actually verify the certificate so just accept what they have provided */
+++	return 1;
+++}
+++
+++static int dtls_setup_rtcp(struct ast_rtp_instance *instance)
++ {
++-	struct ast_rtp *rtp = SSL_get_ex_data(ssl, 0);
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++-	/* We only care about alerts */
++-	if (!(where & SSL_CB_ALERT)) {
++-		return;
+++	if (!rtp->ssl_ctx) {
+++		return 0;
+++	}
+++
+++	rtp->rtcp->dtls_setup = rtp->dtls_setup;
+++
+++	if (!(rtp->rtcp->ssl = SSL_new(rtp->ssl_ctx))) {
+++		ast_log(LOG_ERROR, "Failed to allocate memory for SSL context on RTCP of RTP instance '%p'\n",
+++			instance);
+++		goto error;
+++	}
+++
+++	if (!(rtp->rtcp->read_bio = BIO_new(BIO_s_mem()))) {
+++		ast_log(LOG_ERROR, "Failed to allocate memory for inbound SSL traffic on RTCP of RTP instance '%p'\n",
+++			instance);
+++		goto error;
++ 	}
+++	BIO_set_mem_eof_return(rtp->rtcp->read_bio, -1);
++ 
++-	rtp->dtls_failure = 1;
+++	if (!(rtp->rtcp->write_bio = BIO_new(BIO_s_mem()))) {
+++		ast_log(LOG_ERROR, "Failed to allocate memory for outbound SSL traffic on RTCP of RTP instance '%p'\n",
+++			instance);
+++		goto error;
+++	}
+++	BIO_set_mem_eof_return(rtp->rtcp->write_bio, -1);
+++
+++	SSL_set_bio(rtp->rtcp->ssl, rtp->rtcp->read_bio, rtp->rtcp->write_bio);
+++
+++	return 0;
+++
+++error:
+++	if (rtp->rtcp->read_bio) {
+++		BIO_free(rtp->rtcp->read_bio);
+++		rtp->rtcp->read_bio = NULL;
+++	}
+++
+++	if (rtp->rtcp->write_bio) {
+++		BIO_free(rtp->rtcp->write_bio);
+++		rtp->rtcp->write_bio = NULL;
+++	}
+++
+++	if (rtp->rtcp->ssl) {
+++		SSL_free(rtp->rtcp->ssl);
+++		rtp->rtcp->ssl = NULL;
+++	}
+++	return -1;
++ }
++ 
++ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, const struct ast_rtp_dtls_cfg *dtls_cfg)
++@@ -811,7 +891,11 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
++ 		return -1;
++ 	}
++ 
++-	SSL_CTX_set_verify(rtp->ssl_ctx, dtls_cfg->verify ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE, NULL);
+++	rtp->dtls_verify = dtls_cfg->verify;
+++
+++	SSL_CTX_set_verify(rtp->ssl_ctx, (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) || (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) ?
+++		SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE, !(rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) ?
+++		dtls_verify_callback : NULL);
++ 
++ 	if (dtls_cfg->suite == AST_AES_CM_128_HMAC_SHA1_80) {
++ 		SSL_CTX_set_tlsext_use_srtp(rtp->ssl_ctx, "SRTP_AES128_CM_SHA1_80");
++@@ -822,10 +906,13 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
++ 		goto error;
++ 	}
++ 
+++	rtp->local_hash = dtls_cfg->hash;
+++
++ 	if (!ast_strlen_zero(dtls_cfg->certfile)) {
++ 		char *private = ast_strlen_zero(dtls_cfg->pvtfile) ? dtls_cfg->certfile : dtls_cfg->pvtfile;
++ 		BIO *certbio;
++ 		X509 *cert;
+++		const EVP_MD *type;
++ 		unsigned int size, i;
++ 		unsigned char fingerprint[EVP_MAX_MD_SIZE];
++ 		char *local_fingerprint = rtp->local_fingerprint;
++@@ -849,9 +936,19 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
++ 			goto error;
++ 		}
++ 
+++		if (rtp->local_hash == AST_RTP_DTLS_HASH_SHA1) {
+++			type = EVP_sha1();
+++		} else if (rtp->local_hash == AST_RTP_DTLS_HASH_SHA256) {
+++			type = EVP_sha256();
+++		} else {
+++			ast_log(LOG_ERROR, "Unsupported fingerprint hash type on RTP instance '%p'\n",
+++				instance);
+++			goto error;
+++		}
+++
++ 		if (!BIO_read_filename(certbio, dtls_cfg->certfile) ||
++ 		    !(cert = PEM_read_bio_X509(certbio, NULL, 0, NULL)) ||
++-		    !X509_digest(cert, EVP_sha1(), fingerprint, &size) ||
+++		    !X509_digest(cert, type, fingerprint, &size) ||
++ 		    !size) {
++ 			ast_log(LOG_ERROR, "Could not produce fingerprint from certificate '%s' for RTP instance '%p'\n",
++ 				dtls_cfg->certfile, instance);
++@@ -895,9 +992,6 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
++ 		goto error;
++ 	}
++ 
++-	SSL_set_ex_data(rtp->ssl, 0, rtp);
++-	SSL_set_info_callback(rtp->ssl, dtls_info_callback);
++-
++ 	if (!(rtp->read_bio = BIO_new(BIO_s_mem()))) {
++ 		ast_log(LOG_ERROR, "Failed to allocate memory for inbound SSL traffic on RTP instance '%p'\n",
++ 			instance);
++@@ -914,14 +1008,6 @@ static int ast_rtp_dtls_set_configuration(struct ast_rtp_instance *instance, con
++ 
++ 	SSL_set_bio(rtp->ssl, rtp->read_bio, rtp->write_bio);
++ 
++-	if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
++-		SSL_set_accept_state(rtp->ssl);
++-	} else {
++-		SSL_set_connect_state(rtp->ssl);
++-	}
++-
++-	rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
++-
++ 	return 0;
++ 
++ error:
++@@ -966,19 +1052,26 @@ static void ast_rtp_dtls_stop(struct ast_rtp_instance *instance)
++ 		SSL_free(rtp->ssl);
++ 		rtp->ssl = NULL;
++ 	}
+++
+++	if (rtp->rtcp && rtp->rtcp->ssl) {
+++		SSL_free(rtp->rtcp->ssl);
+++		rtp->rtcp->ssl = NULL;
+++	}
++ }
++ 
++ static void ast_rtp_dtls_reset(struct ast_rtp_instance *instance)
++ {
++ 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++-	/* If the SSL session is not yet finalized don't bother resetting */
++-	if (!SSL_is_init_finished(rtp->ssl)) {
++-		return;
+++	if (SSL_is_init_finished(rtp->ssl)) {
+++		SSL_shutdown(rtp->ssl);
+++		rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
++ 	}
++ 
++-	SSL_shutdown(rtp->ssl);
++-	rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++	if (rtp->rtcp && SSL_is_init_finished(rtp->rtcp->ssl)) {
+++		SSL_shutdown(rtp->rtcp->ssl);
+++		rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++	}
++ }
++ 
++ static enum ast_rtp_dtls_connection ast_rtp_dtls_get_connection(struct ast_rtp_instance *instance)
++@@ -995,26 +1088,25 @@ static enum ast_rtp_dtls_setup ast_rtp_dtls_get_setup(struct ast_rtp_instance *i
++ 	return rtp->dtls_setup;
++ }
++ 
++-static void ast_rtp_dtls_set_setup(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
+++static void dtls_set_setup(enum ast_rtp_dtls_setup *dtls_setup, enum ast_rtp_dtls_setup setup, SSL *ssl)
++ {
++-	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++-	enum ast_rtp_dtls_setup old = rtp->dtls_setup;
+++	enum ast_rtp_dtls_setup old = *dtls_setup;
++ 
++ 	switch (setup) {
++ 	case AST_RTP_DTLS_SETUP_ACTIVE:
++-		rtp->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
+++		*dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
++ 		break;
++ 	case AST_RTP_DTLS_SETUP_PASSIVE:
++-		rtp->dtls_setup = AST_RTP_DTLS_SETUP_ACTIVE;
+++		*dtls_setup = AST_RTP_DTLS_SETUP_ACTIVE;
++ 		break;
++ 	case AST_RTP_DTLS_SETUP_ACTPASS:
++ 		/* We can't respond to an actpass setup with actpass ourselves... so respond with active, as we can initiate connections */
++-		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
++-			rtp->dtls_setup = AST_RTP_DTLS_SETUP_ACTIVE;
+++		if (*dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
+++			*dtls_setup = AST_RTP_DTLS_SETUP_ACTIVE;
++ 		}
++ 		break;
++ 	case AST_RTP_DTLS_SETUP_HOLDCONN:
++-		rtp->dtls_setup = AST_RTP_DTLS_SETUP_HOLDCONN;
+++		*dtls_setup = AST_RTP_DTLS_SETUP_HOLDCONN;
++ 		break;
++ 	default:
++ 		/* This should never occur... if it does exit early as we don't know what state things are in */
++@@ -1022,46 +1114,64 @@ static void ast_rtp_dtls_set_setup(struct ast_rtp_instance *instance, enum ast_r
++ 	}
++ 
++ 	/* If the setup state did not change we go on as if nothing happened */
++-	if (old == rtp->dtls_setup) {
+++	if (old == *dtls_setup) {
++ 		return;
++ 	}
++ 
++ 	/* If they don't want us to establish a connection wait until later */
++-	if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_HOLDCONN) {
+++	if (*dtls_setup == AST_RTP_DTLS_SETUP_HOLDCONN) {
++ 		return;
++ 	}
++ 
++-	if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTIVE) {
++-		SSL_set_connect_state(rtp->ssl);
++-	} else if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
++-		SSL_set_accept_state(rtp->ssl);
+++	if (*dtls_setup == AST_RTP_DTLS_SETUP_ACTIVE) {
+++		SSL_set_connect_state(ssl);
+++	} else if (*dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+++		SSL_set_accept_state(ssl);
++ 	} else {
++ 		return;
++ 	}
++ }
++ 
+++static void ast_rtp_dtls_set_setup(struct ast_rtp_instance *instance, enum ast_rtp_dtls_setup setup)
+++{
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+++
+++	if (rtp->ssl) {
+++		dtls_set_setup(&rtp->dtls_setup, setup, rtp->ssl);
+++	}
+++
+++	if (rtp->rtcp && rtp->rtcp->ssl) {
+++		dtls_set_setup(&rtp->rtcp->dtls_setup, setup, rtp->rtcp->ssl);
+++	}
+++}
+++
++ static void ast_rtp_dtls_set_fingerprint(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash, const char *fingerprint)
++ {
++ 	char *tmp = ast_strdupa(fingerprint), *value;
++ 	int pos = 0;
++ 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++-	if (hash != AST_RTP_DTLS_HASH_SHA1) {
+++	if (hash != AST_RTP_DTLS_HASH_SHA1 && hash != AST_RTP_DTLS_HASH_SHA256) {
++ 		return;
++ 	}
++ 
+++	rtp->remote_hash = hash;
+++
++ 	while ((value = strsep(&tmp, ":")) && (pos != (EVP_MAX_MD_SIZE - 1))) {
++ 		sscanf(value, "%02x", (unsigned int*)&rtp->remote_fingerprint[pos++]);
++ 	}
++ }
++ 
++-static const char *ast_rtp_dtls_get_fingerprint(struct ast_rtp_instance *instance, enum ast_rtp_dtls_hash hash)
+++static enum ast_rtp_dtls_hash ast_rtp_dtls_get_fingerprint_hash(struct ast_rtp_instance *instance)
++ {
++ 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++-	if (hash != AST_RTP_DTLS_HASH_SHA1) {
++-		return NULL;
++-	}
+++	return rtp->local_hash;
+++}
+++
+++static const char *ast_rtp_dtls_get_fingerprint(struct ast_rtp_instance *instance)
+++{
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++ 	return rtp->local_fingerprint;
++ }
++@@ -1076,6 +1186,7 @@ static struct ast_rtp_engine_dtls ast_rtp_dtls = {
++ 	.get_setup = ast_rtp_dtls_get_setup,
++ 	.set_setup = ast_rtp_dtls_set_setup,
++ 	.set_fingerprint = ast_rtp_dtls_set_fingerprint,
+++	.get_fingerprint_hash = ast_rtp_dtls_get_fingerprint_hash,
++ 	.get_fingerprint = ast_rtp_dtls_get_fingerprint,
++ };
++ 
++@@ -1122,7 +1233,34 @@ static void rtp_learning_seq_init(struct rtp_learning_info *info, uint16_t seq);
++ #ifdef USE_PJPROJECT
++ static void ast_rtp_on_ice_complete(pj_ice_sess *ice, pj_status_t status)
++ {
++-	struct ast_rtp *rtp = ice->user_data;
+++	struct ast_rtp_instance *instance = ice->user_data;
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+++
+++#ifdef HAVE_OPENSSL_SRTP
+++	if (rtp->ssl) {
+++		SSL_clear(rtp->ssl);
+++		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+++			SSL_set_accept_state(rtp->ssl);
+++		} else {
+++			SSL_set_connect_state(rtp->ssl);
+++		}
+++		rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++		SSL_do_handshake(rtp->ssl);
+++		dtls_srtp_check_pending(instance, rtp, 0);
+++	}
+++
+++	if (rtp->rtcp && rtp->rtcp->ssl) {
+++		SSL_clear(rtp->rtcp->ssl);
+++		if (rtp->rtcp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+++			SSL_set_accept_state(rtp->rtcp->ssl);
+++		} else {
+++			SSL_set_connect_state(rtp->rtcp->ssl);
+++		}
+++		rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++		SSL_do_handshake(rtp->rtcp->ssl);
+++		dtls_srtp_check_pending(instance, rtp, 1);
+++	}
+++#endif
++ 
++ 	if (!strictrtp) {
++ 		return;
++@@ -1134,7 +1272,8 @@ static void ast_rtp_on_ice_complete(pj_ice_sess *ice, pj_status_t status)
++ 
++ static void ast_rtp_on_ice_rx_data(pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, void *pkt, pj_size_t size, const pj_sockaddr_t *src_addr, unsigned src_addr_len)
++ {
++-	struct ast_rtp *rtp = ice->user_data;
+++	struct ast_rtp_instance *instance = ice->user_data;
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++ 	/* Instead of handling the packet here (which really doesn't work with our architecture) we set a bit to indicate that it should be handled after pj_ice_sess_on_rx_pkt
++ 	 * returns */
++@@ -1143,7 +1282,8 @@ static void ast_rtp_on_ice_rx_data(pj_ice_sess *ice, unsigned comp_id, unsigned
++ 
++ static pj_status_t ast_rtp_on_ice_tx_pkt(pj_ice_sess *ice, unsigned comp_id, unsigned transport_id, const void *pkt, pj_size_t size, const pj_sockaddr_t *dst_addr, unsigned dst_addr_len)
++ {
++-	struct ast_rtp *rtp = ice->user_data;
+++	struct ast_rtp_instance *instance = ice->user_data;
+++	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 	pj_status_t status = PJ_EINVALIDOP;
++ 	pj_ssize_t _size = (pj_ssize_t)size;
++ 
++@@ -1344,36 +1484,52 @@ static int dtls_srtp_handle_timeout(const void *data)
++ 	rtp->dtlstimerid = -1;
++ 	ast_mutex_unlock(&rtp->dtls_timer_lock);
++ 
++-	if (rtp->ssl) {
+++	if (rtp->ssl && !SSL_is_init_finished(rtp->ssl)) {
++ 		DTLSv1_handle_timeout(rtp->ssl);
++ 	}
+++	dtls_srtp_check_pending(instance, rtp, 0);
++ 
++-	dtls_srtp_check_pending(instance, rtp);
+++	if (rtp->rtcp && rtp->rtcp->ssl && !SSL_is_init_finished(rtp->rtcp->ssl)) {
+++		DTLSv1_handle_timeout(rtp->rtcp->ssl);
+++	}
+++	dtls_srtp_check_pending(instance, rtp, 1);
++ 
++ 	ao2_ref(instance, -1);
++ 
++ 	return 0;
++ }
++ 
++-static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp)
+++static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct ast_rtp *rtp, int rtcp)
++ {
++-	size_t pending = BIO_ctrl_pending(rtp->write_bio);
+++	SSL *ssl = !rtcp ? rtp->ssl : rtp->rtcp->ssl;
+++	BIO *write_bio = !rtcp ? rtp->write_bio : rtp->rtcp->write_bio;
+++	size_t pending;
++ 	struct timeval dtls_timeout; /* timeout on DTLS  */
++ 
+++	if (!ssl || !write_bio) {
+++		return;
+++	}
+++
+++	pending = BIO_ctrl_pending(write_bio);
+++
++ 	if (pending > 0) {
++ 		char outgoing[pending];
++ 		size_t out;
++ 		struct ast_sockaddr remote_address = { {0, } };
++ 		int ice;
++ 
++-		ast_rtp_instance_get_remote_address(instance, &remote_address);
+++		if (!rtcp) {
+++			ast_rtp_instance_get_remote_address(instance, &remote_address);
+++		} else {
+++			ast_sockaddr_copy(&remote_address, &rtp->rtcp->them);
+++		}
++ 
++ 		/* If we do not yet know an address to send this to defer it until we do */
++ 		if (ast_sockaddr_isnull(&remote_address)) {
++ 			return;
++ 		}
++ 
++-		out = BIO_read(rtp->write_bio, outgoing, sizeof(outgoing));
+++		out = BIO_read(write_bio, outgoing, sizeof(outgoing));
++ 
++ 		/* Stop existing DTLS timer if running */
++ 		ast_mutex_lock(&rtp->dtls_timer_lock);
++@@ -1382,7 +1538,7 @@ static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct as
++ 			rtp->dtlstimerid = -1;
++ 		}
++ 
++-		if (DTLSv1_get_timeout(rtp->ssl, &dtls_timeout)) {
+++		if (DTLSv1_get_timeout(ssl, &dtls_timeout)) {
++ 			int timeout = dtls_timeout.tv_sec * 1000 + dtls_timeout.tv_usec / 1000;
++ 			ao2_ref(instance, +1);
++ 			if ((rtp->dtlstimerid = ast_sched_add(rtp->sched, timeout, dtls_srtp_handle_timeout, instance)) < 0) {
++@@ -1392,7 +1548,7 @@ static void dtls_srtp_check_pending(struct ast_rtp_instance *instance, struct as
++ 		}
++ 		ast_mutex_unlock(&rtp->dtls_timer_lock);
++ 
++-		__rtp_sendto(instance, outgoing, out, 0, &remote_address, 0, &ice, 0);
+++		__rtp_sendto(instance, outgoing, out, 0, &remote_address, rtcp, &ice, 0);
++ 	}
++ }
++ 
++@@ -1403,7 +1559,13 @@ static int dtls_srtp_renegotiate(const void *data)
++ 
++ 	SSL_renegotiate(rtp->ssl);
++ 	SSL_do_handshake(rtp->ssl);
++-	dtls_srtp_check_pending(instance, rtp);
+++	dtls_srtp_check_pending(instance, rtp, 0);
+++
+++	if (rtp->rtcp && rtp->rtcp->ssl) {
+++		SSL_renegotiate(rtp->rtcp->ssl);
+++		SSL_do_handshake(rtp->rtcp->ssl);
+++		dtls_srtp_check_pending(instance, rtp, 1);
+++	}
++ 
++ 	rtp->rekeyid = -1;
++ 	ao2_ref(instance, -1);
++@@ -1419,7 +1581,7 @@ static int dtls_srtp_setup(struct ast_rtp *rtp, struct ast_srtp *srtp, struct as
++ 	struct ast_rtp_instance_stats stats = { 0, };
++ 
++ 	/* If a fingerprint is present in the SDP make sure that the peer certificate matches it */
++-	if (SSL_CTX_get_verify_mode(rtp->ssl_ctx) != SSL_VERIFY_NONE) {
+++	if (rtp->dtls_verify & AST_RTP_DTLS_VERIFY_FINGERPRINT) {
++ 		X509 *certificate;
++ 
++ 		if (!(certificate = SSL_get_peer_certificate(rtp->ssl))) {
++@@ -1429,10 +1591,20 @@ static int dtls_srtp_setup(struct ast_rtp *rtp, struct ast_srtp *srtp, struct as
++ 
++ 		/* If a fingerprint is present in the SDP make sure that the peer certificate matches it */
++ 		if (rtp->remote_fingerprint[0]) {
+++			const EVP_MD *type;
++ 			unsigned char fingerprint[EVP_MAX_MD_SIZE];
++ 			unsigned int size;
++ 
++-			if (!X509_digest(certificate, EVP_sha1(), fingerprint, &size) ||
+++			if (rtp->remote_hash == AST_RTP_DTLS_HASH_SHA1) {
+++				type = EVP_sha1();
+++			} else if (rtp->remote_hash == AST_RTP_DTLS_HASH_SHA256) {
+++				type = EVP_sha256();
+++			} else {
+++				ast_log(LOG_WARNING, "Unsupported fingerprint hash type on RTP instance '%p'\n", instance);
+++				return -1;
+++			}
+++
+++			if (!X509_digest(certificate, type, fingerprint, &size) ||
++ 			    !size ||
++ 			    memcmp(fingerprint, rtp->remote_fingerprint, size)) {
++ 				X509_free(certificate);
++@@ -1446,7 +1618,7 @@ static int dtls_srtp_setup(struct ast_rtp *rtp, struct ast_srtp *srtp, struct as
++ 	}
++ 
++ 	/* Ensure that certificate verification was successful */
++-	if (SSL_get_verify_result(rtp->ssl) != X509_V_OK) {
+++	if ((rtp->dtls_verify & AST_RTP_DTLS_VERIFY_CERTIFICATE) && SSL_get_verify_result(rtp->ssl) != X509_V_OK) {
++ 		ast_log(LOG_WARNING, "Peer certificate on RTP instance '%p' failed verification test\n",
++ 			instance);
++ 		return -1;
++@@ -1546,50 +1718,54 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
++ 	}
++ 
++ #ifdef HAVE_OPENSSL_SRTP
++-	if (!rtcp) {
++-		dtls_srtp_check_pending(instance, rtp);
+++	dtls_srtp_check_pending(instance, rtp, rtcp);
++ 
++-		/* If this is an SSL packet pass it to OpenSSL for processing */
++-		if ((*in >= 20) && (*in <= 64)) {
++-			int res = 0;
+++	/* If this is an SSL packet pass it to OpenSSL for processing */
+++	if ((*in >= 20) && (*in <= 64)) {
+++		SSL *ssl = !rtcp ? rtp->ssl : rtp->rtcp->ssl;
+++		BIO *read_bio = !rtcp ? rtp->read_bio : rtp->rtcp->read_bio;
+++		int res = 0;
++ 
++-			/* If no SSL session actually exists terminate things */
++-			if (!rtp->ssl) {
++-				ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
++-					instance);
++-				return -1;
++-			}
+++		/* If no SSL session actually exists terminate things */
+++		if (!ssl) {
+++			ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
+++				instance);
+++			return -1;
+++		}
++ 
++-			/* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
++-			if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
++-				rtp->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
++-				SSL_set_accept_state(rtp->ssl);
++-			}
+++		/* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
+++		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
+++			rtp->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
+++			SSL_set_accept_state(ssl);
+++		}
++ 
++-			dtls_srtp_check_pending(instance, rtp);
+++		dtls_srtp_check_pending(instance, rtp, rtcp);
++ 
++-			BIO_write(rtp->read_bio, buf, len);
+++		BIO_write(read_bio, buf, len);
++ 
++-			len = SSL_read(rtp->ssl, buf, len);
+++		len = SSL_read(ssl, buf, len);
++ 
++-			dtls_srtp_check_pending(instance, rtp);
+++		if ((len < 0) && (SSL_get_error(ssl, len) == SSL_ERROR_SSL)) {
+++			unsigned long error = ERR_get_error();
+++			ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p' due to reason '%s', terminating\n",
+++				instance, ERR_reason_error_string(error));
+++			return -1;
+++		}
++ 
++-			if (rtp->dtls_failure) {
++-				ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p', terminating\n",
++-					instance);
++-				return -1;
++-			}
+++		dtls_srtp_check_pending(instance, rtp, rtcp);
++ 
++-			if (SSL_is_init_finished(rtp->ssl)) {
++-				/* Any further connections will be existing since this is now established */
+++		if (SSL_is_init_finished(ssl)) {
+++			/* Any further connections will be existing since this is now established */
+++			if (!rtcp) {
++ 				rtp->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
++-
++ 				/* Use the keying material to set up key/salt information */
++ 				res = dtls_srtp_setup(rtp, srtp, instance);
+++			} else {
+++				rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
++ 			}
++-
++-			return res;
++ 		}
+++
+++		return res;
++ 	}
++ #endif
++ 
++@@ -1657,7 +1833,7 @@ static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t siz
++ 
++ 		if (pj_ice_sess_send_data(rtp->ice, rtcp ? AST_RTP_ICE_COMPONENT_RTCP : AST_RTP_ICE_COMPONENT_RTP, temp, len) == PJ_SUCCESS) {
++ 			*ice = 1;
++-			return 0;
+++			return len;
++ 		}
++ 	}
++ #endif
++@@ -1918,7 +2094,7 @@ static int ice_create(struct ast_rtp_instance *instance, struct ast_sockaddr *ad
++ 	if (pj_ice_sess_create(&stun_config, NULL, PJ_ICE_SESS_ROLE_UNKNOWN, 2,
++ 			&ast_rtp_ice_sess_cb, &ufrag, &passwd, NULL, &rtp->ice) == PJ_SUCCESS) {
++ 		/* Make this available for the callbacks */
++-		rtp->ice->user_data = rtp;
+++		rtp->ice->user_data = instance;
++ 
++ 		/* Add all of the available candidates to the ICE session */
++ 		rtp_add_candidates_to_ice(instance, rtp, addr, port, AST_RTP_ICE_COMPONENT_RTP,
++@@ -2055,6 +2231,11 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance)
++ 		 * RTP instance while it's active.
++ 		 */
++ 		close(rtp->rtcp->s);
+++#ifdef HAVE_OPENSSL_SRTP
+++		if (rtp->rtcp->ssl) {
+++			SSL_free(rtp->rtcp->ssl);
+++		}
+++#endif
++ 		ast_free(rtp->rtcp);
++ 	}
++ 
++@@ -4131,6 +4312,10 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
++ 			}
++ #endif
++ 
+++#ifdef HAVE_OPENSSL_SRTP
+++			dtls_setup_rtcp(instance);
+++#endif
+++
++ 			return;
++ 		} else {
++ 			if (rtp->rtcp) {
++@@ -4146,6 +4331,11 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
++ 					rtp->rtcp->schedid = -1;
++ 				}
++ 				close(rtp->rtcp->s);
+++#ifdef HAVE_OPENSSL_SRTP
+++				if (rtp->rtcp->ssl) {
+++					SSL_free(rtp->rtcp->ssl);
+++				}
+++#endif
++ 				ast_free(rtp->rtcp);
++ 				rtp->rtcp = NULL;
++ 			}
++@@ -4442,13 +4632,35 @@ static int ast_rtp_activate(struct ast_rtp_instance *instance)
++ {
++ 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ 
++-	if (!rtp->ssl) {
+++	/* If ICE negotiation is enabled the DTLS Handshake will be performed upon completion of it */
+++#ifdef USE_PJPROJECT
+++	if (rtp->ice) {
++ 		return 0;
++ 	}
+++#endif
++ 
++-	SSL_do_handshake(rtp->ssl);
++-
++-	dtls_srtp_check_pending(instance, rtp);
+++	if (rtp->ssl) {
+++		SSL_clear(rtp->ssl);
+++		if (rtp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+++			SSL_set_accept_state(rtp->ssl);
+++		} else {
+++			SSL_set_connect_state(rtp->ssl);
+++		}
+++		rtp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++		SSL_do_handshake(rtp->ssl);
+++		dtls_srtp_check_pending(instance, rtp, 0);
+++	}
+++	if (rtp->rtcp && rtp->rtcp->ssl) {
+++		SSL_clear(rtp->rtcp->ssl);
+++		if (rtp->rtcp->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+++			SSL_set_accept_state(rtp->rtcp->ssl);
+++		} else {
+++			SSL_set_connect_state(rtp->rtcp->ssl);
+++		}
+++		rtp->rtcp->connection = AST_RTP_DTLS_CONNECTION_NEW;
+++		SSL_do_handshake(rtp->rtcp->ssl);
+++		dtls_srtp_check_pending(instance, rtp, 1);
+++	}
++ 
++ 	return 0;
++ }
diff --cc debian/patches/series
index 974966f,3307ab7..915b0bd
--- a/debian/patches/series
+++ b/debian/patches/series
@@@ -24,14 -24,12 +24,13 @@@ astdatadi
  pjproject
  
  # Backport of dynamic generation of DAHDI channels:
- dahdi_pri_event_removed
  dahdi_create_channels
+ pri_destroy_span_prilist.patch
+ sigpri_handle_enodev_1.patch
  
- hyphen
  reenable
- freeradius-client
  ignore_failed_channels.patch
- suppress_warning_rasterisk.patch
- 
- dtls_srtp_patch
- 
+ smsq_enable.patch
+ smsq_manpage.patch
+ escape_manpage_hyphen.patch
++dtls_srtp.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/asterisk.git



More information about the Pkg-voip-commits mailing list