summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c1
-rw-r--r--include/asterisk/utils.h13
-rw-r--r--main/manager.c55
-rw-r--r--main/rtp_engine.c8
-rw-r--r--main/utils.c34
-rw-r--r--res/res_pjsip/config_transport.c7
-rw-r--r--res/res_rtp_asterisk.c30
7 files changed, 122 insertions, 26 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5c808cc22..500aeb785 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -31464,6 +31464,7 @@ static int reload_config(enum channelreloadreason reason)
sip_cfg.peer_rtupdate = TRUE;
global_dynamic_exclude_static = 0; /* Exclude static peers */
sip_cfg.tcp_enabled = FALSE;
+ sip_cfg.websocket_enabled = TRUE;
/* Session-Timers */
global_st_mode = SESSION_TIMER_MODE_ACCEPT;
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 832500c31..c7a473732 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -1099,4 +1099,17 @@ int ast_crypt_validate(const char *key, const char *expected);
*/
int ast_file_is_readable(const char *filename);
+/*
+ * \brief Compare 2 major.minor.patch.extra version strings.
+ * \since 13.7.0
+ *
+ * \param version1.
+ * \param version2.
+ *
+ * \return <0 if version 1 < version 2.
+ * \return =0 if version 1 = version 2.
+ * \return >0 if version 1 > version 2.
+ */
+int ast_compare_versions(const char *version1, const char *version2);
+
#endif /* _ASTERISK_UTILS_H */
diff --git a/main/manager.c b/main/manager.c
index 99c550275..455a49c4e 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -651,6 +651,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="Channel"/>
<parameter name="Context"/>
<parameter name="Exten"/>
+ <parameter name="Application"/>
+ <parameter name="Data"/>
<parameter name="Reason"/>
<parameter name="Uniqueid"/>
<parameter name="CallerIDNum"/>
@@ -4969,22 +4971,43 @@ static void *fast_originate(void *data)
}
/* Tell the manager what happened with the channel */
chans[0] = chan;
- ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
- "%s"
- "Response: %s\r\n"
- "Channel: %s\r\n"
- "Context: %s\r\n"
- "Exten: %s\r\n"
- "Reason: %d\r\n"
- "Uniqueid: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n",
- in->idtext, res ? "Failure" : "Success",
- chan ? ast_channel_name(chan) : requested_channel, in->context, in->exten, reason,
- chan ? ast_channel_uniqueid(chan) : "<null>",
- S_OR(in->cid_num, "<unknown>"),
- S_OR(in->cid_name, "<unknown>")
- );
+ if (!ast_strlen_zero(in->app)) {
+ ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
+ "%s"
+ "Response: %s\r\n"
+ "Channel: %s\r\n"
+ "Application: %s\r\n"
+ "Data: %s\r\n"
+ "Reason: %d\r\n"
+ "Uniqueid: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n",
+ in->idtext, res ? "Failure" : "Success",
+ chan ? ast_channel_name(chan) : requested_channel,
+ in->app, in->appdata, reason,
+ chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
+ S_OR(in->cid_num, "<unknown>"),
+ S_OR(in->cid_name, "<unknown>")
+ );
+ } else {
+ ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
+ "%s"
+ "Response: %s\r\n"
+ "Channel: %s\r\n"
+ "Context: %s\r\n"
+ "Exten: %s\r\n"
+ "Reason: %d\r\n"
+ "Uniqueid: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n",
+ in->idtext, res ? "Failure" : "Success",
+ chan ? ast_channel_name(chan) : requested_channel,
+ in->context, in->exten, reason,
+ chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
+ S_OR(in->cid_num, "<unknown>"),
+ S_OR(in->cid_name, "<unknown>")
+ );
+ }
/* Locked and ref'd by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
if (chan) {
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index beda8cd74..7c5ef311a 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -1634,14 +1634,14 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name,
}
} else if (!strcasecmp(name, "dtlscertfile")) {
ast_free(dtls_cfg->certfile);
- if (!ast_file_is_readable(value)) {
+ if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
return -1;
}
dtls_cfg->certfile = ast_strdup(value);
} else if (!strcasecmp(name, "dtlsprivatekey")) {
ast_free(dtls_cfg->pvtfile);
- if (!ast_file_is_readable(value)) {
+ if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
return -1;
}
@@ -1651,14 +1651,14 @@ int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name,
dtls_cfg->cipher = ast_strdup(value);
} else if (!strcasecmp(name, "dtlscafile")) {
ast_free(dtls_cfg->cafile);
- if (!ast_file_is_readable(value)) {
+ if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
return -1;
}
dtls_cfg->cafile = ast_strdup(value);
} else if (!strcasecmp(name, "dtlscapath") || !strcasecmp(name, "dtlscadir")) {
ast_free(dtls_cfg->capath);
- if (!ast_file_is_readable(value)) {
+ if (!ast_strlen_zero(value) && !ast_file_is_readable(value)) {
ast_log(LOG_ERROR, "%s file %s does not exist or is not readable\n", name, value);
return -1;
}
diff --git a/main/utils.c b/main/utils.c
index 3eeafed4f..3a8d46ae4 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -1404,7 +1404,13 @@ int ast_carefulwrite(int fd, char *s, int len, int timeoutms)
if (res < 0 && errno != EAGAIN && errno != EINTR) {
/* fatal error from write() */
- ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
+ if (errno == EPIPE) {
+#ifndef STANDALONE
+ ast_debug(1, "write() failed due to reading end being closed: %s\n", strerror(errno));
+#endif
+ } else {
+ ast_log(LOG_ERROR, "write() returned error: %s\n", strerror(errno));
+ }
return -1;
}
@@ -2949,3 +2955,29 @@ int ast_file_is_readable(const char *filename)
return 1;
#endif
}
+
+int ast_compare_versions(const char *version1, const char *version2)
+{
+ unsigned int major[2] = { 0 };
+ unsigned int minor[2] = { 0 };
+ unsigned int patch[2] = { 0 };
+ unsigned int extra[2] = { 0 };
+ int res;
+
+ sscanf(version1, "%u.%u.%u.%u", &major[0], &minor[0], &patch[0], &extra[0]);
+ sscanf(version2, "%u.%u.%u.%u", &major[1], &minor[1], &patch[1], &extra[1]);
+
+ res = major[0] - major[1];
+ if (res) {
+ return res;
+ }
+ res = minor[0] - minor[1];
+ if (res) {
+ return res;
+ }
+ res = patch[0] - patch[1];
+ if (res) {
+ return res;
+ }
+ return extra[0] - extra[1];
+}
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index d8ece1509..840824bd9 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -217,11 +217,8 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg, &transport->state->factory);
} else if (transport->type == AST_TRANSPORT_TLS) {
- /* The following check is a work-around for ASTERISK-25615.
- * When that issue is resolved in upstream pjproject, this check can be removed.
- */
- if (transport->async_operations > 1) {
- ast_log(LOG_ERROR, "Transport: %s: When protocol=tls, async_operations can't be > 1 (ASTERISK-25615)\n",
+ if (transport->async_operations > 1 && ast_compare_versions(pj_get_version(), "2.5.0") < 0) {
+ ast_log(LOG_ERROR, "Transport: %s: When protocol=tls and pjproject version < 2.5.0, async_operations can't be > 1\n",
ast_sorcery_object_get_id(obj));
return -1;
}
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index f6bf34211..3dfaf87fa 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -2118,6 +2118,8 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
SSL_set_accept_state(dtls->ssl);
}
+ ast_mutex_lock(&dtls->lock);
+
dtls_srtp_check_pending(instance, rtp, rtcp);
BIO_write(dtls->read_bio, buf, len);
@@ -2128,6 +2130,7 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
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));
+ ast_mutex_unlock(&dtls->lock);
return -1;
}
@@ -2145,6 +2148,8 @@ static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t s
dtls_srtp_start_timeout_timer(instance, rtp, rtcp);
}
+ ast_mutex_unlock(&dtls->lock);
+
return res;
}
#endif
@@ -4817,6 +4822,9 @@ static int ast_rtp_fd(struct ast_rtp_instance *instance, int rtcp)
static void ast_rtp_remote_address_set(struct ast_rtp_instance *instance, struct ast_sockaddr *addr)
{
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+#ifdef HAVE_OPENSSL_SRTP
+ struct dtls_details *dtls;
+#endif
if (rtp->rtcp) {
ast_debug(1, "Setting RTCP address on RTP instance '%p'\n", instance);
@@ -4834,6 +4842,28 @@ static void ast_rtp_remote_address_set(struct ast_rtp_instance *instance, struct
rtp_learning_seq_init(&rtp->rtp_source_learn, rtp->seqno);
}
+#ifdef HAVE_OPENSSL_SRTP
+ /* Trigger pending outbound DTLS packets received before the address was set. Avoid unnecessary locking
+ * by checking if we're passive. Without this, we only send the pending packets once a new SSL packet is
+ * received in __rtp_recvfrom.
+ */
+ dtls = &rtp->dtls;
+ if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+ ast_mutex_lock(&dtls->lock);
+ dtls_srtp_check_pending(instance, rtp, 0);
+ ast_mutex_unlock(&dtls->lock);
+ }
+
+ if (rtp->rtcp) {
+ dtls = &rtp->rtcp->dtls;
+ if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_PASSIVE) {
+ ast_mutex_lock(&dtls->lock);
+ dtls_srtp_check_pending(instance, rtp, 1);
+ ast_mutex_unlock(&dtls->lock);
+ }
+ }
+#endif
+
return;
}