[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