Merge "channels/pjsip/dialplan_functions: Add an option for extracting the SIP call-id"
authorMatt Jordan <mjordan@digium.com>
Sat, 5 Sep 2015 23:43:50 +0000 (18:43 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Sat, 5 Sep 2015 23:43:50 +0000 (18:43 -0500)
17 files changed:
channels/chan_pjsip.c
channels/chan_sip.c
contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py [new file with mode: 0644]
include/asterisk/res_pjsip.h
include/asterisk/res_pjsip_session.h
main/pbx.c
main/sched.c
main/taskprocessor.c
res/res_pjsip.c
res/res_pjsip/config_global.c
res/res_pjsip_multihomed.c
res/res_pjsip_pubsub.c
res/res_pjsip_sdp_rtp.c
res/res_pjsip_session.c
res/res_pjsip_t38.c
res/res_pjsip_transport_websocket.c
res/res_rtp_asterisk.c

index d3ba0a2..9603f05 100644 (file)
@@ -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;
index 1888091..e385ddb 100644 (file)
@@ -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 (file)
index 0000000..7e6cf99
--- /dev/null
@@ -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')
index decb417..b7b875d 100644 (file)
@@ -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 */
index 734a887..6139847 100644 (file)
@@ -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
index fcf0aa6..5e4f0a4 100644 (file)
@@ -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)));
 
index d50a31e..062b2fd 100644 (file)
@@ -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 */
        }
 
index 1edbaa3..5c513ee 100644 (file)
@@ -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;
 }
index 04e16c4..4af886b 100644 (file)
                                         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);
index 42ba234..b348896 100644 (file)
@@ -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;
index 68a4311..7062fc6 100644 (file)
 #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;
index 2b42ad6..6c3d101 100644 (file)
@@ -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;
index f1314f5..a66aebb 100644 (file)
@@ -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,
 };
 
index 625ab8b..1dcac7e 100644 (file)
@@ -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()));
                }
        }
 
index 43b6e92..40899bf 100644 (file)
@@ -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;
index e48b630..3157a94 100644 (file)
@@ -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;
index 545e216..09a0fef 100644 (file)
@@ -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);