summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorGeorge Joseph <george.joseph@fairview5.com>2016-02-11 10:01:05 -0700
committerGeorge Joseph <george.joseph@fairview5.com>2016-02-19 18:57:55 -0600
commitba8adb4ce3ac15198b0dfe38df890d4283ad9bc8 (patch)
treeb739fd5001c12ae8d33c72a20203d65857676c9f /res
parent6fc57b3e1f401fd18e3e4d4462f973094dd0908c (diff)
res_pjsip/config_transport: Allow reloading transports.
The 'reload' mechanism actually involves closing the underlying socket and calling the appropriate udp, tcp or tls start functions again. Only outbound_registration, pubsub and session needed work to reset the transport before sending requests to insure that the pjsip transport didn't get pulled out from under them. In my testing, no calls were dropped when a transport was changed for any of the 3 transport types even if ip addresses or ports were changed. To be on the safe side however, a new transport option was added (allow_reload) which defaults to 'no'. Unless it's explicitly set to 'yes' for a transport, changes to that transport will be ignored on a reload of res_pjsip. This should preserve the current behavior. Change-Id: I5e759850e25958117d4c02f62ceb7244d7ec9edf
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip.c55
-rw-r--r--res/res_pjsip/config_transport.c139
-rw-r--r--res/res_pjsip_outbound_registration.c32
-rw-r--r--res/res_pjsip_pubsub.c31
-rw-r--r--res/res_pjsip_session.c33
5 files changed, 220 insertions, 70 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index e35529253..713d94ec5 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1029,6 +1029,14 @@
Value is in milliseconds; default is 100 ms.</para>
</description>
</configOption>
+ <configOption name="allow_reload" default="no">
+ <synopsis>Allow this transport to be reloaded.</synopsis>
+ <description>
+ <para>Allow this transport to be reloaded when res_pjsip is reloaded.
+ This option defaults to "no" because reloading a transport may disrupt
+ in-progress calls.</para>
+ </description>
+ </configOption>
</configObject>
<configObject name="contact">
<synopsis>A way of creating an aliased name to a SIP URI</synopsis>
@@ -2479,22 +2487,14 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u
return 0;
}
-static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpoint, pjsip_tpselector *selector)
+int ast_sip_set_tpselector_from_transport(const struct ast_sip_transport *transport, pjsip_tpselector *selector)
{
- RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
RAII_VAR(struct ast_sip_transport_state *, transport_state, NULL, ao2_cleanup);
- const char *transport_name = endpoint->transport;
-
- if (ast_strlen_zero(transport_name)) {
- return 0;
- }
-
- transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
- transport_state = ast_sip_get_transport_state(transport_name);
- if (!transport || !transport_state) {
- ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' for endpoint '%s'\n",
- transport_name, ast_sorcery_object_get_id(endpoint));
+ transport_state = ast_sip_get_transport_state(ast_sorcery_object_get_id(transport));
+ if (!transport_state) {
+ ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport state for '%s'\n",
+ ast_sorcery_object_get_id(transport));
return -1;
}
@@ -2517,6 +2517,35 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo
return 0;
}
+int ast_sip_set_tpselector_from_transport_name(const char *transport_name, pjsip_tpselector *selector)
+{
+ RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
+
+ if (ast_strlen_zero(transport_name)) {
+ return 0;
+ }
+
+ transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
+ if (!transport) {
+ ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s'\n",
+ transport_name);
+ return -1;
+ }
+
+ return ast_sip_set_tpselector_from_transport(transport, selector);
+}
+
+static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpoint, pjsip_tpselector *selector)
+{
+ const char *transport_name = endpoint->transport;
+
+ if (ast_strlen_zero(transport_name)) {
+ return 0;
+ }
+
+ return ast_sip_set_tpselector_from_transport_name(endpoint->transport, selector);
+}
+
void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
{
pjsip_sip_uri *sip_uri;
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index 0fcd7d923..e7bda5f05 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -18,6 +18,7 @@
#include "asterisk.h"
+#include <math.h>
#include <pjsip.h>
#include <pjlib.h>
@@ -347,6 +348,44 @@ static void copy_state_to_transport(struct ast_sip_transport *transport)
memcpy(&transport->external_address, &transport->state->external_address, sizeof(transport->external_address));
}
+static int has_state_changed(struct ast_sip_transport_state *a, struct ast_sip_transport_state *b)
+{
+ if (a->type != b->type) {
+ return -1;
+ }
+
+ if (pj_sockaddr_cmp(&a->host, &b->host)) {
+ return -1;
+ }
+
+ if ((a->localnet || b->localnet)
+ && ((!a->localnet != !b->localnet)
+ || ast_sockaddr_cmp(&a->localnet->addr, &b->localnet->addr)
+ || ast_sockaddr_cmp(&a->localnet->netmask, &b->localnet->netmask)))
+ {
+ return -1;
+ }
+
+ if (ast_sockaddr_cmp(&a->external_address, &b->external_address)) {
+ return -1;
+ }
+
+ if (a->tls.method != b->tls.method
+ || a->tls.ciphers_num != b->tls.ciphers_num
+ || a->tls.proto != b->tls.proto
+ || a->tls.verify_client != b->tls.verify_client
+ || a->tls.verify_server != b->tls.verify_server
+ || a->tls.require_client_cert != b->tls.require_client_cert) {
+ return -1;
+ }
+
+ if (memcmp(a->ciphers, b->ciphers, sizeof(pj_ssl_cipher) * fmax(a->tls.ciphers_num, b->tls.ciphers_num))) {
+ return -1;
+ }
+
+ return 0;
+}
+
static void states_cleanup(void *states)
{
if (states) {
@@ -364,6 +403,9 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
RAII_VAR(struct internal_state *, perm_state, NULL, ao2_cleanup);
RAII_VAR(struct ast_variable *, changes, NULL, ast_variables_destroy);
pj_status_t res = -1;
+ int i;
+#define BIND_TRIES 3
+#define BIND_DELAY_US 100000
if (!states) {
return -1;
@@ -376,32 +418,39 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
*/
ao2_wrlock(states);
+ temp_state = internal_state_alloc(transport);
+ if (!temp_state) {
+ ast_log(LOG_ERROR, "Transport '%s' failed to allocate memory\n", transport_id);
+ return -1;
+ }
+
perm_state = find_internal_state_by_transport(transport);
if (perm_state) {
ast_sorcery_diff(sorcery, perm_state->transport, transport, &changes);
- if (changes) {
+ if (!changes && !has_state_changed(perm_state->state, temp_state->state)) {
+ /* In case someone is using the deprecated fields, reset them */
+ transport->state = perm_state->state;
+ copy_state_to_transport(transport);
+ ao2_replace(perm_state->transport, transport);
+ return 0;
+ }
+
+ if (!transport->allow_reload) {
if (!perm_state->change_detected) {
perm_state->change_detected = 1;
ast_log(LOG_WARNING, "Transport '%s' is not reloadable, maintaining previous values\n", transport_id);
}
+ /* In case someone is using the deprecated fields, reset them */
+ transport->state = perm_state->state;
+ copy_state_to_transport(transport);
+ ao2_replace(perm_state->transport, transport);
+ return 0;
}
-
- /* In case someone is using the deprecated fields, reset them */
- transport->state = perm_state->state;
- copy_state_to_transport(transport);
- ao2_replace(perm_state->transport, transport);
- return 0;
- }
-
- temp_state = internal_state_alloc(transport);
- if (!temp_state) {
- ast_log(LOG_ERROR, "Transport '%s' failed to allocate memory\n", transport_id);
- goto error;
}
if (temp_state->state->host.addr.sa_family != PJ_AF_INET && temp_state->state->host.addr.sa_family != PJ_AF_INET6) {
ast_log(LOG_ERROR, "Transport '%s' could not be started as binding not specified\n", transport_id);
- goto error;
+ return -1;
}
/* Set default port if not present */
@@ -418,20 +467,33 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
} else {
ast_log(LOG_ERROR, "Unknown address family for transport '%s', could not get external signaling address\n",
transport_id);
- goto error;
+ return -1;
}
if (ast_dnsmgr_lookup(transport->external_signaling_address, &temp_state->state->external_address, &temp_state->state->external_address_refresher, NULL) < 0) {
ast_log(LOG_ERROR, "Could not create dnsmgr for external signaling address on '%s'\n", transport_id);
- goto error;
+ return -1;
}
}
if (transport->type == AST_TRANSPORT_UDP) {
- if (temp_state->state->host.addr.sa_family == pj_AF_INET()) {
- res = pjsip_udp_transport_start(ast_sip_get_pjsip_endpoint(), &temp_state->state->host.ipv4, NULL, transport->async_operations, &temp_state->state->transport);
- } else if (temp_state->state->host.addr.sa_family == pj_AF_INET6()) {
- res = pjsip_udp_transport_start6(ast_sip_get_pjsip_endpoint(), &temp_state->state->host.ipv6, NULL, transport->async_operations, &temp_state->state->transport);
+
+ for (i = 0; i < BIND_TRIES && res != PJ_SUCCESS; i++) {
+ if (perm_state && perm_state->state && perm_state->state->transport) {
+ pjsip_udp_transport_pause(perm_state->state->transport,
+ PJSIP_UDP_TRANSPORT_DESTROY_SOCKET);
+ usleep(BIND_DELAY_US);
+ }
+
+ if (temp_state->state->host.addr.sa_family == pj_AF_INET()) {
+ res = pjsip_udp_transport_start(ast_sip_get_pjsip_endpoint(),
+ &temp_state->state->host.ipv4, NULL, transport->async_operations,
+ &temp_state->state->transport);
+ } else if (temp_state->state->host.addr.sa_family == pj_AF_INET6()) {
+ res = pjsip_udp_transport_start6(ast_sip_get_pjsip_endpoint(),
+ &temp_state->state->host.ipv6, NULL, transport->async_operations,
+ &temp_state->state->transport);
+ }
}
if (res == PJ_SUCCESS && (transport->tos || transport->cos)) {
@@ -451,18 +513,37 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
cfg.async_cnt = transport->async_operations;
set_qos(transport, &cfg.qos_params);
- res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg, &temp_state->state->factory);
+ for (i = 0; i < BIND_TRIES && res != PJ_SUCCESS; i++) {
+ if (perm_state && perm_state->state && perm_state->state->factory
+ && perm_state->state->factory->destroy) {
+ perm_state->state->factory->destroy(perm_state->state->factory);
+ usleep(BIND_DELAY_US);
+ }
+
+ res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg,
+ &temp_state->state->factory);
+ }
} else if (transport->type == AST_TRANSPORT_TLS) {
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));
- goto error;
+ return -1;
}
temp_state->state->tls.password = pj_str((char*)transport->password);
set_qos(transport, &temp_state->state->tls.qos_params);
- res = pjsip_tls_transport_start2(ast_sip_get_pjsip_endpoint(), &temp_state->state->tls, &temp_state->state->host, NULL, transport->async_operations, &temp_state->state->factory);
+ for (i = 0; i < BIND_TRIES && res != PJ_SUCCESS; i++) {
+ if (perm_state && perm_state->state && perm_state->state->factory
+ && perm_state->state->factory->destroy) {
+ perm_state->state->factory->destroy(perm_state->state->factory);
+ usleep(BIND_DELAY_US);
+ }
+
+ res = pjsip_tls_transport_start2(ast_sip_get_pjsip_endpoint(), &temp_state->state->tls,
+ &temp_state->state->host, NULL, transport->async_operations,
+ &temp_state->state->factory);
+ }
} else if ((transport->type == AST_TRANSPORT_WS) || (transport->type == AST_TRANSPORT_WSS)) {
if (transport->cos || transport->tos) {
ast_log(LOG_WARNING, "TOS and COS values ignored for websocket transport\n");
@@ -475,17 +556,16 @@ static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
pj_strerror(res, msg, sizeof(msg));
ast_log(LOG_ERROR, "Transport '%s' could not be started: %s\n", ast_sorcery_object_get_id(obj), msg);
- goto error;
+ return -1;
}
copy_state_to_transport(transport);
- ao2_link(states, temp_state);
+ if (perm_state) {
+ ao2_unlink_flags(states, perm_state, OBJ_NOLOCK);
+ }
+ ao2_link_flags(states, temp_state, OBJ_NOLOCK);
return 0;
-
-error:
- ao2_unlink(states, temp_state);
- return -1;
}
/*! \brief Custom handler for type just makes sure the state is created */
@@ -1209,6 +1289,7 @@ int ast_sip_initialize_sorcery_transport(void)
ast_sorcery_object_field_register_custom(sorcery, "transport", "tos", "0", transport_tos_handler, tos_to_str, NULL, 0, 0);
ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));
ast_sorcery_object_field_register(sorcery, "transport", "websocket_write_timeout", AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, write_timeout), 1, INT_MAX);
+ ast_sorcery_object_field_register(sorcery, "transport", "allow_reload", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_transport, allow_reload));
internal_sip_register_endpoint_formatter(&endpoint_transport_formatter);
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 0ff609a63..dd69ff20e 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -346,6 +346,8 @@ struct sip_outbound_registration_client_state {
unsigned int destroy:1;
/*! \brief Non-zero if we have attempted sending a REGISTER with authentication */
unsigned int auth_attempted:1;
+ /*! \brief The name of the transport to be used for the registration */
+ char *transport_name;
};
/*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
@@ -508,6 +510,7 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli
{
pj_status_t status;
int *callback_invoked;
+ pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
callback_invoked = ast_threadstorage_get(&register_callback_invoked, sizeof(int));
if (!callback_invoked) {
@@ -517,6 +520,13 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli
/* Due to the message going out the callback may now be invoked, so bump the count */
ao2_ref(client_state, +1);
+ /*
+ * Set the transport in case transports were reloaded.
+ * When pjproject removes the extraneous error messages produced,
+ * we can check status and only set the transport and resend if there was an error
+ */
+ ast_sip_set_tpselector_from_transport_name(client_state->transport_name, &selector);
+ pjsip_regc_set_transport(client_state->client, &selector);
status = pjsip_regc_send(client_state->client, tdata);
/* If the attempt to send the message failed and the callback was not invoked we need to
@@ -966,6 +976,7 @@ static void sip_outbound_registration_client_state_destroy(void *obj)
{
struct sip_outbound_registration_client_state *client_state = obj;
+ ast_free(client_state->transport_name);
ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "-1", 1.0);
ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "-1", 1.0,
sip_outbound_registration_status_str(client_state->status));
@@ -1003,6 +1014,7 @@ static struct sip_outbound_registration_state *sip_outbound_registration_state_a
state->client_state->status = SIP_REGISTRATION_UNREGISTERED;
state->client_state->timer.user_data = state->client_state;
state->client_state->timer.cb = sip_outbound_registration_timer_cb;
+ state->client_state->transport_name = ast_strdup(registration->transport);
ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0);
ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0,
@@ -1171,25 +1183,6 @@ static int sip_outbound_registration_regc_alloc(void *data)
pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
- if (!ast_strlen_zero(registration->transport)) {
- RAII_VAR(struct ast_sip_transport_state *, transport_state, ast_sip_get_transport_state(registration->transport), ao2_cleanup);
-
- if (!transport_state) {
- ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' "
- " for outbound registration", registration->transport);
- return -1;
- }
-
- if (transport_state->transport) {
- selector.type = PJSIP_TPSELECTOR_TRANSPORT;
- selector.u.transport = transport_state->transport;
- } else if (transport_state->factory) {
- selector.type = PJSIP_TPSELECTOR_LISTENER;
- selector.u.listener = transport_state->factory;
- } else {
- return -1;
- }
- }
ast_assert(state->client_state->client == NULL);
if (pjsip_regc_create(ast_sip_get_pjsip_endpoint(), state->client_state,
@@ -1198,6 +1191,7 @@ static int sip_outbound_registration_regc_alloc(void *data)
return -1;
}
+ ast_sip_set_tpselector_from_transport_name(registration->transport, &selector);
pjsip_regc_set_transport(state->client_state->client, &selector);
if (!ast_strlen_zero(registration->outbound_proxy)) {
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index bde7075dd..0da43190c 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -1559,6 +1559,28 @@ void *ast_sip_subscription_get_header(const struct ast_sip_subscription *sub, co
return pjsip_msg_find_hdr_by_name(msg, &name, NULL);
}
+/*!
+ * \internal
+ * \brief Wrapper for pjsip_evsub_send_request
+ *
+ * This function (re)sets the transport before sending to catch cases
+ * where the transport might have changed.
+ *
+ * If pjproject gives us the ability to resend, we'll only reset the transport
+ * if PJSIP_ETPNOTAVAIL is returned from send.
+ *
+ * \returns pj_status_t
+ */
+static pj_status_t internal_pjsip_evsub_send_request(struct sip_subscription_tree *sub_tree, pjsip_tx_data *tdata)
+{
+ pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
+
+ ast_sip_set_tpselector_from_transport_name(sub_tree->endpoint->transport, &selector);
+ pjsip_dlg_set_transport(sub_tree->dlg, &selector);
+
+ return pjsip_evsub_send_request(sub_tree->evsub, tdata);
+}
+
/* XXX This function is not used. */
struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_subscription_handler *handler,
struct ast_sip_endpoint *endpoint, const char *resource)
@@ -1606,7 +1628,7 @@ struct ast_sip_subscription *ast_sip_create_subscription(const struct ast_sip_su
evsub = sub_tree->evsub;
if (pjsip_evsub_initiate(evsub, NULL, -1, &tdata) == PJ_SUCCESS) {
- pjsip_evsub_send_request(evsub, tdata);
+ internal_pjsip_evsub_send_request(sub_tree, tdata);
} else {
/* pjsip_evsub_terminate will result in pubsub_on_evsub_state,
* being called and terminating the subscription. Therefore, we don't
@@ -1687,8 +1709,8 @@ static int sip_subscription_send_request(struct sip_subscription_tree *sub_tree,
{
#ifdef TEST_FRAMEWORK
struct ast_sip_endpoint *endpoint = sub_tree->endpoint;
-#endif
pjsip_evsub *evsub = sub_tree->evsub;
+#endif
int res;
if (allocate_tdata_buffer(tdata)) {
@@ -1696,7 +1718,8 @@ static int sip_subscription_send_request(struct sip_subscription_tree *sub_tree,
return -1;
}
- res = pjsip_evsub_send_request(evsub, tdata) == PJ_SUCCESS ? 0 : -1;
+ res = internal_pjsip_evsub_send_request(sub_tree, tdata);
+
subscription_persistence_update(sub_tree, NULL);
ast_test_suite_event_notify("SUBSCRIPTION_STATE_SET",
@@ -1705,7 +1728,7 @@ static int sip_subscription_send_request(struct sip_subscription_tree *sub_tree,
pjsip_evsub_get_state_name(evsub),
ast_sorcery_object_get_id(endpoint));
- return res;
+ return (res == PJ_SUCCESS ? 0 : -1);
}
/*!
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index e7dd5b91d..983687174 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -888,10 +888,32 @@ int ast_sip_session_refresh(struct ast_sip_session *session,
return 0;
}
+/*!
+ * \internal
+ * \brief Wrapper for pjsip_inv_send_msg
+ *
+ * This function (re)sets the transport before sending to catch cases
+ * where the transport might have changed.
+ *
+ * If pjproject gives us the ability to resend, we'll only reset the transport
+ * if PJSIP_ETPNOTAVAIL is returned from send.
+ *
+ * \returns pj_status_t
+ */
+static pj_status_t internal_pjsip_inv_send_msg(pjsip_inv_session *inv, const char *transport_name, pjsip_tx_data *tdata)
+{
+ pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
+
+ ast_sip_set_tpselector_from_transport_name(transport_name, &selector);
+ pjsip_dlg_set_transport(inv->dlg, &selector);
+
+ return pjsip_inv_send_msg(inv, tdata);
+}
+
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
{
handle_outgoing_response(session, tdata);
- pjsip_inv_send_msg(session->inv_session, tdata);
+ internal_pjsip_inv_send_msg(session->inv_session, session->endpoint->transport, tdata);
return;
}
@@ -1087,7 +1109,8 @@ void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip
}
handle_outgoing_request(session, tdata);
- pjsip_inv_send_msg(session->inv_session, tdata);
+ internal_pjsip_inv_send_msg(session->inv_session, session->endpoint->transport, tdata);
+
return;
}
@@ -1852,7 +1875,7 @@ static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct a
if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) != PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
}
- pjsip_inv_send_msg(inv_session, tdata);
+ internal_pjsip_inv_send_msg(inv_session, endpoint->transport, tdata);
return NULL;
}
return inv_session;
@@ -2005,7 +2028,7 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
} else {
- pjsip_inv_send_msg(inv_session, tdata);
+ internal_pjsip_inv_send_msg(inv_session, endpoint->transport, tdata);
}
return;
}
@@ -2015,7 +2038,7 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
if (pjsip_inv_initial_answer(inv_session, rdata, 500, NULL, NULL, &tdata) == PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
} else {
- pjsip_inv_send_msg(inv_session, tdata);
+ internal_pjsip_inv_send_msg(inv_session, endpoint->transport, tdata);
}
ao2_cleanup(invite);
}