summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_pjsip.c14
-rw-r--r--channels/chan_sip.c3
-rw-r--r--contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py22
-rw-r--r--include/asterisk/res_pjsip.h38
-rw-r--r--include/asterisk/res_pjsip_session.h6
-rw-r--r--main/pbx.c2
-rw-r--r--main/sched.c4
-rw-r--r--main/taskprocessor.c12
-rw-r--r--res/res_pjsip.c62
-rw-r--r--res/res_pjsip/config_global.c21
-rw-r--r--res/res_pjsip_multihomed.c23
-rw-r--r--res/res_pjsip_pubsub.c15
-rw-r--r--res/res_pjsip_sdp_rtp.c40
-rw-r--r--res/res_pjsip_session.c26
-rw-r--r--res/res_pjsip_t38.c15
-rw-r--r--res/res_pjsip_transport_websocket.c2
-rw-r--r--res/res_rtp_asterisk.c3
17 files changed, 246 insertions, 62 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index d3ba0a283..9603f0514 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -1811,9 +1811,17 @@ static int hangup(void *data)
static int chan_pjsip_hangup(struct ast_channel *ast)
{
struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
- struct chan_pjsip_pvt *pvt = channel->pvt;
- int cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
- struct hangup_data *h_data = hangup_data_alloc(cause, ast);
+ struct chan_pjsip_pvt *pvt;
+ int cause;
+ struct hangup_data *h_data;
+
+ if (!channel || !channel->session) {
+ return -1;
+ }
+
+ pvt = channel->pvt;
+ cause = hangup_cause2sip(ast_channel_hangupcause(channel->session->channel));
+ h_data = hangup_data_alloc(cause, ast);
if (!h_data) {
goto failure;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 1888091b8..e385ddb53 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -24527,10 +24527,9 @@ static void *sip_pickup_thread(void *stuff)
struct ast_channel *chan;
chan = stuff;
+ ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
if (ast_pickup_call(chan)) {
ast_channel_hangupcause_set(chan, AST_CAUSE_CALL_REJECTED);
- } else {
- ast_channel_hangupcause_set(chan, AST_CAUSE_NORMAL_CLEARING);
}
ast_hangup(chan);
ast_channel_unref(chan);
diff --git a/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py
new file mode 100644
index 000000000..7e6cf994f
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py
@@ -0,0 +1,22 @@
+"""add default_from_user
+
+Revision ID: 154177371065
+Revises: 26f10cadc157
+Create Date: 2015-09-04 14:13:59.195013
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '154177371065'
+down_revision = '26f10cadc157'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ op.add_column('ps_globals', sa.Column('default_from_user', sa.String(80)))
+
+
+def downgrade():
+ op.drop_column('ps_globals', 'default_from_user')
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index decb4177a..b7b875d0f 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -2018,6 +2018,17 @@ char *ast_sip_get_debug(void);
*/
char *ast_sip_get_endpoint_identifier_order(void);
+/*!
+ * \brief Retrieve the global default from user.
+ *
+ * This is the value placed in outbound requests' From header if there
+ * is no better option (such as an endpoint-configured from_user or
+ * caller ID number).
+ *
+ * \retval The global default_from_user value.
+ */
+const char *ast_sip_get_default_from_user(void);
+
/*! \brief Determines whether the res_pjsip module is loaded */
#define CHECK_PJSIP_MODULE_LOADED() \
do { \
@@ -2059,4 +2070,31 @@ const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_st
*/
int ast_sip_failover_request(pjsip_tx_data *tdata);
+/*
+ * \brief Retrieve the local host address in IP form
+ *
+ * \param af The address family to retrieve
+ * \param addr A place to store the local host address
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \since 13.6.0
+ */
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr);
+
+/*!
+ * \brief Retrieve the local host address in string form
+ *
+ * \param af The address family to retrieve
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \since 13.6.0
+ *
+ * \note An empty string may be returned if the address family is valid but no local address exists
+ */
+const char *ast_sip_get_host_ip_string(int af);
+
#endif /* _RES_PJSIP_H */
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 734a887b3..613984713 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -357,6 +357,12 @@ struct ast_sip_session_sdp_handler {
int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
/*!
+ * \brief Stop a session_media created by this handler but do not destroy resources
+ * \param session The session for which media is being stopped
+ * \param session_media The media to destroy
+ */
+ void (*stream_stop)(struct ast_sip_session_media *session_media);
+ /*!
* \brief Destroy a session_media created by this handler
* \param session The session for which media is being destroyed
* \param session_media The media to destroy
diff --git a/main/pbx.c b/main/pbx.c
index fcf0aa64e..5e4f0a4db 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -7521,7 +7521,7 @@ static char *handle_show_hints(struct ast_cli_entry *e, int cmd, struct ast_cli_
continue;
}
watchers = ao2_container_count(hint->callbacks);
- sprintf(buf, "%s@%s",
+ snprintf(buf, sizeof(buf), "%s@%s",
ast_get_extension_name(hint->exten),
ast_get_context_name(ast_get_extension_context(hint->exten)));
diff --git a/main/sched.c b/main/sched.c
index d50a31e56..062b2fd96 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -497,7 +497,9 @@ int _ast_sched_del(struct ast_sched_context *con, int id, const char *file, int
/* Wait for executing task to complete so that caller of ast_sched_del() does not
* free memory out from under the task.
*/
- ast_cond_wait(&s->cond, &con->lock);
+ while (con->currently_executing && (id == con->currently_executing->id)) {
+ ast_cond_wait(&s->cond, &con->lock);
+ }
/* Do not sched_release() here because ast_sched_runq() will do it */
}
diff --git a/main/taskprocessor.c b/main/taskprocessor.c
index 1edbaa3ed..5c513ee66 100644
--- a/main/taskprocessor.c
+++ b/main/taskprocessor.c
@@ -691,15 +691,25 @@ void *ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
return NULL;
}
+ /* To prevent another thread from finding and getting a reference to this
+ * taskprocessor we hold the singletons lock. If we didn't do this then
+ * they may acquire it and find that the listener has been shut down.
+ */
+ ao2_lock(tps_singletons);
+
if (ao2_ref(tps, -1) > 3) {
+ ao2_unlock(tps_singletons);
return NULL;
}
+
/* If we're down to 3 references, then those must be:
* 1. The reference we just got rid of
* 2. The container
* 3. The listener
*/
- ao2_unlink(tps_singletons, tps);
+ ao2_unlink_flags(tps_singletons, tps, OBJ_NOLOCK);
+ ao2_unlock(tps_singletons);
+
listener_shutdown(tps->listener);
return NULL;
}
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 04e16c415..4af886b4b 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1286,6 +1286,11 @@
Identifier names are usually derived from and can be found in the endpoint
identifier module itself (res_pjsip_endpoint_identifier_*)</synopsis>
</configOption>
+ <configOption name="default_from_user" default="asterisk">
+ <synopsis>When Asterisk generates an outgoing SIP request, the From header username will be
+ set to this value if there is no better option (such as CallerID) to be
+ used.</synopsis>
+ </configOption>
</configObject>
</configFile>
</configInfo>
@@ -1912,6 +1917,18 @@ static pjsip_endpoint *ast_pjsip_endpoint;
static struct ast_threadpool *sip_threadpool;
+/*! Local host address for IPv4 */
+static pj_sockaddr host_ip_ipv4;
+
+/*! Local host address for IPv4 (string form) */
+static char host_ip_ipv4_string[PJ_INET6_ADDRSTRLEN + 2];
+
+/*! Local host address for IPv6 */
+static pj_sockaddr host_ip_ipv6;
+
+/*! Local host address for IPv6 (string form) */
+static char host_ip_ipv6_string[PJ_INET6_ADDRSTRLEN + 2];
+
static int register_service_noref(void *data)
{
pjsip_module **module = data;
@@ -2321,10 +2338,9 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u
pjsip_sip_uri *sip_uri;
pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
int local_port;
- char uuid_str[AST_UUID_STR_LEN];
if (ast_strlen_zero(user)) {
- user = ast_uuid_generate_str(uuid_str, sizeof(uuid_str));
+ user = ast_sip_get_default_from_user();
}
/* Parse the provided target URI so we can determine what transport it will end up using */
@@ -3724,6 +3740,14 @@ int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, s
pjsip_transaction *tsx;
if (pjsip_tsx_create_uas(NULL, rdata, &tsx) != PJ_SUCCESS) {
+ struct ast_sip_contact *contact;
+
+ /* ast_sip_create_response bumps the refcount of the contact and adds it to the tdata.
+ * We'll leak that reference if we don't get rid of it here.
+ */
+ contact = ast_sip_mod_data_get(tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT);
+ ao2_cleanup(contact);
+ ast_sip_mod_data_set(tdata->pool, tdata->mod_data, supplement_module.id, MOD_DATA_CONTACT, NULL);
pjsip_tx_data_dec_ref(tdata);
return -1;
}
@@ -3751,6 +3775,30 @@ int ast_sip_create_response(const pjsip_rx_data *rdata, int st_code,
return res;
}
+int ast_sip_get_host_ip(int af, pj_sockaddr *addr)
+{
+ if (af == pj_AF_INET() && !ast_strlen_zero(host_ip_ipv4_string)) {
+ pj_sockaddr_copy_addr(addr, &host_ip_ipv4);
+ return 0;
+ } else if (af == pj_AF_INET6() && !ast_strlen_zero(host_ip_ipv6_string)) {
+ pj_sockaddr_copy_addr(addr, &host_ip_ipv6);
+ return 0;
+ }
+
+ return -1;
+}
+
+const char *ast_sip_get_host_ip_string(int af)
+{
+ if (af == pj_AF_INET()) {
+ return host_ip_ipv4_string;
+ } else if (af == pj_AF_INET6()) {
+ return host_ip_ipv6_string;
+ }
+
+ return NULL;
+}
+
static void remove_request_headers(pjsip_endpoint *endpt)
{
const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
@@ -3865,6 +3913,16 @@ static int load_module(void)
return AST_MODULE_LOAD_DECLINE;
}
+ if (!pj_gethostip(pj_AF_INET(), &host_ip_ipv4)) {
+ pj_sockaddr_print(&host_ip_ipv4, host_ip_ipv4_string, sizeof(host_ip_ipv4_string), 2);
+ ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ip_ipv4_string);
+ }
+
+ if (!pj_gethostip(pj_AF_INET6(), &host_ip_ipv6)) {
+ pj_sockaddr_print(&host_ip_ipv6, host_ip_ipv6_string, sizeof(host_ip_ipv6_string), 2);
+ ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ip_ipv6_string);
+ }
+
if (ast_sip_initialize_system()) {
ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n");
pj_pool_release(memory_pool);
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 42ba23487..b348896c8 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -34,6 +34,7 @@
#define DEFAULT_DEBUG "no"
#define DEFAULT_ENDPOINT_IDENTIFIER_ORDER "ip,username,anonymous"
#define DEFAULT_MAX_INITIAL_QUALIFY_TIME 0
+#define DEFAULT_FROM_USER "asterisk"
static char default_useragent[256];
@@ -46,6 +47,8 @@ struct global_config {
AST_STRING_FIELD(debug);
/*! Order by which endpoint identifiers are checked (comma separated list) */
AST_STRING_FIELD(endpoint_identifier_order);
+ /*! User name to place in From header if there is no better option */
+ AST_STRING_FIELD(default_from_user);
);
/* Value to put in Max-Forwards header */
unsigned int max_forwards;
@@ -179,6 +182,22 @@ unsigned int ast_sip_get_max_initial_qualify_time(void)
return time;
}
+const char *ast_sip_get_default_from_user(void)
+{
+ const char *from_user;
+ struct global_config *cfg;
+
+ cfg = get_global_cfg();
+ if (!cfg) {
+ return DEFAULT_FROM_USER;
+ }
+
+ from_user = cfg->default_from_user;
+ ao2_ref(cfg, -1);
+
+ return from_user;
+}
+
/*!
* \internal
* \brief Observer to set default global object if none exist.
@@ -292,6 +311,8 @@ int ast_sip_initialize_sorcery_global(void)
ast_sorcery_object_field_register(sorcery, "global", "max_initial_qualify_time",
__stringify(DEFAULT_MAX_INITIAL_QUALIFY_TIME),
OPT_UINT_T, 0, FLDSET(struct global_config, max_initial_qualify_time));
+ ast_sorcery_object_field_register(sorcery, "global", "default_from_user", DEFAULT_FROM_USER,
+ OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, default_from_user));
if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) {
return -1;
diff --git a/res/res_pjsip_multihomed.c b/res/res_pjsip_multihomed.c
index 68a431153..7062fc60b 100644
--- a/res/res_pjsip_multihomed.c
+++ b/res/res_pjsip_multihomed.c
@@ -30,12 +30,6 @@
#include "asterisk/res_pjsip.h"
#include "asterisk/module.h"
-/*! \brief Local host address for IPv4 */
-static char host_ipv4[PJ_INET_ADDRSTRLEN + 2];
-
-/*! \brief Local host address for IPv6 */
-static char host_ipv6[PJ_INET6_ADDRSTRLEN + 2];
-
/*! \brief Helper function which returns a UDP transport bound to the given address and port */
static pjsip_transport *multihomed_get_udp_transport(pj_str_t *address, int port)
{
@@ -75,8 +69,10 @@ static int multihomed_rewrite_sdp(struct pjmedia_sdp_session *sdp)
}
/* If the host address is used in the SDP replace it with the address of what this is going out on */
- if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr, host_ipv4)) ||
- (!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr, host_ipv6))) {
+ if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr,
+ ast_sip_get_host_ip_string(pj_AF_INET()))) ||
+ (!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr,
+ ast_sip_get_host_ip_string(pj_AF_INET6())))) {
return 1;
}
@@ -204,7 +200,6 @@ static int unload_module(void)
static int load_module(void)
{
char hostname[MAXHOSTNAMELEN] = "";
- pj_sockaddr addr;
CHECK_PJSIP_MODULE_LOADED();
@@ -213,16 +208,6 @@ static int load_module(void)
hostname);
}
- if (!pj_gethostip(pj_AF_INET(), &addr)) {
- pj_sockaddr_print(&addr, host_ipv4, sizeof(host_ipv4), 2);
- ast_verb(3, "Local IPv4 address determined to be: %s\n", host_ipv4);
- }
-
- if (!pj_gethostip(pj_AF_INET6(), &addr)) {
- pj_sockaddr_print(&addr, host_ipv6, sizeof(host_ipv6), 2);
- ast_verb(3, "Local IPv6 address determined to be: %s\n", host_ipv6);
- }
-
if (ast_sip_register_service(&multihomed_module)) {
ast_log(LOG_ERROR, "Could not register multihomed module for incoming and outgoing requests\n");
return AST_MODULE_LOAD_FAILURE;
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index 2b42ad6be..6c3d1014c 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -561,8 +561,19 @@ static void subscription_persistence_update(struct sip_subscription_tree *sub_tr
expires = expires_hdr ? expires_hdr->ivalue : DEFAULT_PUBLISH_EXPIRES;
sub_tree->persistence->expires = ast_tvadd(ast_tvnow(), ast_samp2tv(expires, 1));
- pjsip_msg_print(rdata->msg_info.msg, sub_tree->persistence->packet,
- sizeof(sub_tree->persistence->packet));
+ /* When receiving a packet on an streaming transport, it's possible to receive more than one SIP
+ * message at a time into the rdata->pkt_info.packet buffer. However, the rdata->msg_info.msg_buf
+ * will always point to the proper SIP message that is to be processed. When updating subscription
+ * persistence that is pulled from persistent storage, though, the rdata->pkt_info.packet will
+ * only ever have a single SIP message on it, and so we base persistence on that.
+ */
+ if (rdata->msg_info.msg_buf) {
+ ast_copy_string(sub_tree->persistence->packet, rdata->msg_info.msg_buf,
+ MIN(sizeof(sub_tree->persistence->packet), rdata->msg_info.len));
+ } else {
+ ast_copy_string(sub_tree->persistence->packet, rdata->pkt_info.packet,
+ sizeof(sub_tree->persistence->packet));
+ }
ast_copy_string(sub_tree->persistence->src_name, rdata->pkt_info.src_name,
sizeof(sub_tree->persistence->src_name));
sub_tree->persistence->src_port = rdata->pkt_info.src_port;
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index f1314f528..a66aebb36 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -611,6 +611,9 @@ static enum ast_sip_session_media_encryption get_media_encryption_type(pj_str_t
*optimistic = 0;
+ if (!transport_str) {
+ return AST_SIP_MEDIA_TRANSPORT_INVALID;
+ }
if (strstr(transport_str, "UDP/TLS")) {
return AST_SIP_MEDIA_ENCRYPT_DTLS;
} else if (strstr(transport_str, "SAVP")) {
@@ -1033,7 +1036,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
static const pj_str_t STR_SENDONLY = { "sendonly", 8 };
pjmedia_sdp_media *media;
- char hostip[PJ_INET6_ADDRSTRLEN+2];
+ const char *hostip = NULL;
struct ast_sockaddr addr;
char tmp[512];
pj_str_t stmp;
@@ -1081,16 +1084,16 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
/* Add connection level details */
if (direct_media_enabled) {
- ast_copy_string(hostip, ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR), sizeof(hostip));
+ hostip = ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR);
} else if (ast_strlen_zero(session->endpoint->media.address)) {
- pj_sockaddr localaddr;
-
- if (pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
- return -1;
- }
- pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+ hostip = ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET());
} else {
- ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+ hostip = session->endpoint->media.address;
+ }
+
+ if (ast_strlen_zero(hostip)) {
+ ast_log(LOG_ERROR, "No local host IP available for stream %s\n", session_media->stream_type);
+ return -1;
}
media->conn->net_type = STR_IN;
@@ -1314,6 +1317,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a
* a NAT. This way there won't be an awkward delay before media starts flowing in some
* scenarios.
*/
+ AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
session_media->keepalive_sched_id = ast_sched_add_variable(sched, 500, send_keepalive,
session_media, 1);
}
@@ -1365,13 +1369,23 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
pj_strdup2(tdata->pool, &stream->conn->addr, transport->external_media_address);
}
+/*! \brief Function which stops the RTP instance */
+static void stream_stop(struct ast_sip_session_media *session_media)
+{
+ if (!session_media->rtp) {
+ return;
+ }
+
+ AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
+ AST_SCHED_DEL(sched, session_media->timeout_sched_id);
+ ast_rtp_instance_stop(session_media->rtp);
+}
+
/*! \brief Function which destroys the RTP instance when session ends */
static void stream_destroy(struct ast_sip_session_media *session_media)
{
if (session_media->rtp) {
- AST_SCHED_DEL(sched, session_media->keepalive_sched_id);
- AST_SCHED_DEL(sched, session_media->timeout_sched_id);
- ast_rtp_instance_stop(session_media->rtp);
+ stream_stop(session_media);
ast_rtp_instance_destroy(session_media->rtp);
}
session_media->rtp = NULL;
@@ -1384,6 +1398,7 @@ static struct ast_sip_session_sdp_handler audio_sdp_handler = {
.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+ .stream_stop = stream_stop,
.stream_destroy = stream_destroy,
};
@@ -1394,6 +1409,7 @@ static struct ast_sip_session_sdp_handler video_sdp_handler = {
.create_outgoing_sdp_stream = create_outgoing_sdp_stream,
.apply_negotiated_sdp_stream = apply_negotiated_sdp_stream,
.change_outgoing_sdp_stream_media_address = change_outgoing_sdp_stream_media_address,
+ .stream_stop = stream_stop,
.stream_destroy = stream_destroy,
};
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 625ab8be3..1dcac7e97 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -362,6 +362,13 @@ static int handle_negotiated_sdp_session_media(void *obj, void *arg, int flags)
}
}
}
+
+ if (session_media->handler && session_media->handler->stream_stop) {
+ ast_debug(1, "Stopping SDP media stream '%s' as it is not currently negotiated\n",
+ session_media->stream_type);
+ session_media->handler->stream_stop(session_media);
+ }
+
return CMP_MATCH;
}
@@ -2422,8 +2429,16 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
break;
case PJSIP_EVENT_RX_MSG:
cb = ast_sip_mod_data_get(tsx->mod_data, session_module.id, MOD_DATA_ON_RESPONSE);
- handle_incoming(session, e->body.tsx_state.src.rdata, e->type,
- AST_SIP_SESSION_AFTER_MEDIA);
+ /* As the PJSIP invite session implementation responds with a 200 OK before we have a
+ * chance to be invoked session supplements for BYE requests actually end up executing
+ * in the invite session state callback as well. To prevent session supplements from
+ * running on the BYE request again we explicitly squash invocation of them here.
+ */
+ if ((e->body.tsx_state.src.rdata->msg_info.msg->type != PJSIP_REQUEST_MSG) ||
+ (tsx->method.id != PJSIP_BYE_METHOD)) {
+ handle_incoming(session, e->body.tsx_state.src.rdata, e->type,
+ AST_SIP_SESSION_AFTER_MEDIA);
+ }
if (tsx->method.id == PJSIP_INVITE_METHOD) {
if (tsx->role == PJSIP_ROLE_UAC) {
if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
@@ -2675,12 +2690,7 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru
if (!ast_strlen_zero(session->endpoint->media.address)) {
pj_strdup2(inv->pool_prov, &local->origin.addr, session->endpoint->media.address);
} else {
- pj_sockaddr localaddr;
- char our_ip[PJ_INET6_ADDRSTRLEN];
-
- pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr);
- pj_sockaddr_print(&localaddr, our_ip, sizeof(our_ip), 0);
- pj_strdup2(inv->pool_prov, &local->origin.addr, our_ip);
+ pj_strdup2(inv->pool_prov, &local->origin.addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()));
}
}
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index 43b6e9231..40899bf51 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -707,7 +707,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
static const pj_str_t STR_T38UDPREDUNDANCY = { "t38UDPRedundancy", 16 };
struct t38_state *state;
pjmedia_sdp_media *media;
- char hostip[PJ_INET6_ADDRSTRLEN+2];
+ const char *hostip = NULL;
struct ast_sockaddr addr;
char tmp[512];
pj_str_t stmp;
@@ -732,14 +732,13 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as
media->desc.transport = STR_UDPTL;
if (ast_strlen_zero(session->endpoint->media.address)) {
- pj_sockaddr localaddr;
-
- if (pj_gethostip(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) {
- return -1;
- }
- pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2);
+ hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET());
} else {
- ast_copy_string(hostip, session->endpoint->media.address, sizeof(hostip));
+ hostip = session->endpoint->media.address;
+ }
+
+ if (ast_strlen_zero(hostip)) {
+ return -1;
}
media->conn->net_type = STR_IN;
diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c
index e48b630e7..3157a940f 100644
--- a/res/res_pjsip_transport_websocket.c
+++ b/res/res_pjsip_transport_websocket.c
@@ -419,7 +419,7 @@ static int load_module(void)
CHECK_PJSIP_MODULE_LOADED();
pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws);
- pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WSS", 5060, &transport_type_wss);
+ pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "WSS", 5060, &transport_type_wss);
if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) {
return AST_MODULE_LOAD_DECLINE;
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 545e21634..09a0fef97 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -706,8 +706,7 @@ static void ast_rtp_ice_start(struct ast_rtp_instance *instance)
ao2_iterator_destroy(&i);
if (has_rtp && has_rtcp &&
- pj_ice_sess_create_check_list(rtp->ice, &ufrag, &passwd, ao2_container_count(
- rtp->ice_active_remote_candidates), &candidates[0]) == PJ_SUCCESS) {
+ pj_ice_sess_create_check_list(rtp->ice, &ufrag, &passwd, cand_cnt, &candidates[0]) == PJ_SUCCESS) {
ast_test_suite_event_notify("ICECHECKLISTCREATE", "Result: SUCCESS");
pj_ice_sess_start_check(rtp->ice);
pj_timer_heap_poll(timer_heap, NULL);