diff options
-rw-r--r-- | channels/chan_sip.c | 1 | ||||
-rw-r--r-- | include/asterisk/utils.h | 13 | ||||
-rw-r--r-- | main/manager.c | 55 | ||||
-rw-r--r-- | main/rtp_engine.c | 8 | ||||
-rw-r--r-- | main/utils.c | 34 | ||||
-rw-r--r-- | res/res_pjsip/config_transport.c | 7 | ||||
-rw-r--r-- | res/res_rtp_asterisk.c | 30 |
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; } |