summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_config.h14
-rw-r--r--pjsip/include/pjsip/sip_endpoint.h22
-rw-r--r--pjsip/include/pjsip/sip_transport.h7
-rw-r--r--pjsip/include/pjsip/sip_transport_tls.h28
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h2
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c38
-rw-r--r--pjsip/src/pjsip-ua/sip_replaces.c7
-rw-r--r--pjsip/src/pjsip-ua/sip_timer.c6
-rw-r--r--pjsip/src/pjsip/sip_auth_aka.c37
-rw-r--r--pjsip/src/pjsip/sip_auth_client.c6
-rw-r--r--pjsip/src/pjsip/sip_config.c4
-rw-r--r--pjsip/src/pjsip/sip_endpoint.c40
-rw-r--r--pjsip/src/pjsip/sip_transaction.c50
-rw-r--r--pjsip/src/pjsip/sip_transport_tls.c5
-rw-r--r--pjsip/src/pjsip/sip_util.c5
-rw-r--r--pjsip/src/pjsua-lib/pjsua_aud.c68
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c37
-rw-r--r--pjsip/src/pjsua-lib/pjsua_dump.c1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c4
19 files changed, 292 insertions, 89 deletions
diff --git a/pjsip/include/pjsip/sip_config.h b/pjsip/include/pjsip/sip_config.h
index 6398e774..3d0c0946 100644
--- a/pjsip/include/pjsip/sip_config.h
+++ b/pjsip/include/pjsip/sip_config.h
@@ -81,6 +81,13 @@ typedef struct pjsip_cfg_t
* Disable rport in request.
*/
pj_bool_t disable_rport;
+
+ /**
+ * Disable automatic switching from UDP to TCP if outgoing request
+ * is greater than 1300 bytes. See PJSIP_DONT_SWITCH_TO_TCP.
+ */
+ pj_bool_t disable_tcp_switch;
+
} endpt;
/** Transaction layer settings. */
@@ -251,6 +258,9 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
* Disable the behavior of automatic switching to TCP whenever UDP packet
* size exceeds the threshold defined in PJSIP_UDP_SIZE_THRESHOLD.
*
+ * This option can also be controlled at run-time by the \a disable_tcp_switch
+ * setting in pjsip_cfg_t.
+ *
* Default is 0 (no).
*/
#ifndef PJSIP_DONT_SWITCH_TO_TCP
@@ -420,10 +430,10 @@ PJ_INLINE(pjsip_cfg_t*) pjsip_cfg(void)
* Idle timeout interval to be applied to transports with no usage
* before the transport is destroyed. Value is in seconds.
*
- * Default: 600
+ * Default: 30
*/
#ifndef PJSIP_TRANSPORT_IDLE_TIME
-# define PJSIP_TRANSPORT_IDLE_TIME 600
+# define PJSIP_TRANSPORT_IDLE_TIME 30
#endif
diff --git a/pjsip/include/pjsip/sip_endpoint.h b/pjsip/include/pjsip/sip_endpoint.h
index e957271c..c6cf6d65 100644
--- a/pjsip/include/pjsip/sip_endpoint.h
+++ b/pjsip/include/pjsip/sip_endpoint.h
@@ -62,6 +62,13 @@ PJ_BEGIN_DECL
* @{
*/
+
+/**
+ * Type of callback to register to pjsip_endpt_atexit().
+ */
+typedef void (*pjsip_endpt_exit_callback)(pjsip_endpoint *endpt);
+
+
/**
* Create an instance of SIP endpoint from the specified pool factory.
* The pool factory reference then will be kept by the endpoint, so that
@@ -511,6 +518,21 @@ PJ_DECL(const pjsip_hdr*) pjsip_endpt_get_request_headers(pjsip_endpoint *e);
PJ_DECL(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail );
+/**
+ * Register cleanup function to be called by SIP endpoint when
+ * #pjsip_endpt_destroy() is called. Note that application should not
+ * use or access any endpoint resource (such as pool, ioqueue, timer heap)
+ * from within the callback as such resource may have been released when
+ * the callback function is invoked.
+ *
+ * @param endpt The SIP endpoint.
+ * @param func The function to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_endpt_atexit(pjsip_endpoint *endpt,
+ pjsip_endpt_exit_callback func);
+
/**
* @}
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index a567d1a1..99f006a6 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -574,6 +574,13 @@ struct pjsip_tx_data
pjsip_tpselector tp_sel;
/**
+ * Special flag to indicate that this transmit data is a request that has
+ * been updated with proper authentication response and is ready to be
+ * sent for retry.
+ */
+ pj_bool_t auth_retry;
+
+ /**
* Arbitrary data attached by PJSIP modules.
*/
void *mod_data[PJSIP_MAX_MODULE];
diff --git a/pjsip/include/pjsip/sip_transport_tls.h b/pjsip/include/pjsip/sip_transport_tls.h
index f9426412..ae823f36 100644
--- a/pjsip/include/pjsip/sip_transport_tls.h
+++ b/pjsip/include/pjsip/sip_transport_tls.h
@@ -26,6 +26,7 @@
*/
#include <pjsip/sip_transport.h>
+#include <pj/pool.h>
#include <pj/ssl_sock.h>
#include <pj/string.h>
#include <pj/sock_qos.h>
@@ -106,20 +107,19 @@ typedef struct pjsip_tls_setting
int method;
/**
- * TLS cipher list string in OpenSSL format. If empty, then default
- * cipher list of the backend will be used.
+ * Number of ciphers contained in the specified cipher preference.
+ * If this is set to zero, then default cipher list of the backend
+ * will be used.
+ *
+ * Default: 0 (zero).
*/
- pj_str_t ciphers;
+ unsigned ciphers_num;
/**
- * Optionally specify the server name instance to be contacted when
- * making outgoing TLS connection. This setting is useful when the
- * server is hosting multiple domains for the same TLS listening
- * socket.
- *
- * Default: empty.
+ * Ciphers and order preference. The #pj_ssl_cipher_get_availables()
+ * can be used to check the available ciphers supported by backend.
*/
- pj_str_t server_name;
+ pj_ssl_cipher *ciphers;
/**
* Specifies TLS transport behavior on the server TLS certificate
@@ -246,7 +246,13 @@ PJ_INLINE(void) pjsip_tls_setting_copy(pj_pool_t *pool,
pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file);
pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file);
pj_strdup_with_null(pool, &dst->password, &src->password);
- pj_strdup_with_null(pool, &dst->ciphers, &src->ciphers);
+ if (src->ciphers_num) {
+ unsigned i;
+ dst->ciphers = (pj_ssl_cipher*) pj_pool_calloc(pool, src->ciphers_num,
+ sizeof(pj_ssl_cipher));
+ for (i=0; i<src->ciphers_num; ++i)
+ dst->ciphers[i] = src->ciphers[i];
+ }
}
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index b0f6c6bd..18085201 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -4886,7 +4886,7 @@ PJ_DECL(pj_status_t) pjsua_im_typing(pjsua_acc_id acc_id,
{
pjsua_player_id player_id;
- status = pjsua_player_create("mysong.wav", 0, NULL, &player_id);
+ status = pjsua_player_create("mysong.wav", 0, &player_id);
if (status != PJ_SUCCESS)
return status;
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 8c2c92d0..a36cfed4 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -212,7 +212,16 @@ void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
* otherwise disconnect the session.
*/
if (state == PJSIP_INV_STATE_CONFIRMED) {
- if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) {
+ struct tsx_inv_data *tsx_inv_data = NULL;
+
+ if (inv->invite_tsx) {
+ tsx_inv_data = (struct tsx_inv_data*)
+ inv->invite_tsx->mod_data[mod_inv.mod.id];
+ }
+
+ if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE &&
+ (tsx_inv_data && !tsx_inv_data->sdp_done) )
+ {
pjsip_tx_data *bye;
PJ_LOG(4,(inv->obj_name, "SDP offer/answer incomplete, ending the "
@@ -3954,6 +3963,32 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e)
} else if (tsx->role == PJSIP_ROLE_UAS &&
tsx->state == PJSIP_TSX_STATE_TRYING &&
+ pjsip_method_cmp(&tsx->method, &pjsip_invite_method)==0)
+ {
+ pjsip_rx_data *rdata = e->body.tsx_state.src.rdata;
+ pjsip_tx_data *tdata;
+ pj_status_t status;
+
+ /* See https://trac.pjsip.org/repos/ticket/1455
+ * Handle incoming re-INVITE before current INVITE is confirmed.
+ * According to RFC 5407:
+ * - answer with 200 if we don't have pending offer-answer
+ * - answer with 491 if we *have* pending offer-answer
+ *
+ * But unfortunately accepting the re-INVITE would mean we have
+ * two outstanding INVITEs, and we don't support that because
+ * we will get confused when we handle the ACK.
+ */
+ status = pjsip_dlg_create_response(inv->dlg, rdata,
+ PJSIP_SC_REQUEST_PENDING,
+ NULL, &tdata);
+ if (status != PJ_SUCCESS)
+ return;
+ pjsip_timer_update_resp(inv, tdata);
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+
+ } else if (tsx->role == PJSIP_ROLE_UAS &&
+ tsx->state == PJSIP_TSX_STATE_TRYING &&
pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)
{
/*
@@ -3986,6 +4021,7 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e)
/* Generic handling for UAC tsx completion */
handle_uac_tsx_response(inv, e);
+
}
}
diff --git a/pjsip/src/pjsip-ua/sip_replaces.c b/pjsip/src/pjsip-ua/sip_replaces.c
index 4707a510..70329f97 100644
--- a/pjsip/src/pjsip-ua/sip_replaces.c
+++ b/pjsip/src/pjsip-ua/sip_replaces.c
@@ -162,8 +162,10 @@ static pjsip_hdr *parse_hdr_replaces(pjsip_parse_ctx *ctx)
/* Deinitialize Replaces */
-static void pjsip_replaces_deinit_module(void)
+static void pjsip_replaces_deinit_module(pjsip_endpoint *endpt)
{
+ PJ_TODO(provide_initialized_flag_for_each_endpoint);
+ PJ_UNUSED_ARG(endpt);
is_initialized = PJ_FALSE;
}
@@ -191,7 +193,8 @@ PJ_DEF(pj_status_t) pjsip_replaces_init_module(pjsip_endpoint *endpt)
1, &STR_REPLACES);
/* Register deinit module to be executed when PJLIB shutdown */
- if (pj_atexit(&pjsip_replaces_deinit_module) != PJ_SUCCESS) {
+ if (pjsip_endpt_atexit(endpt, &pjsip_replaces_deinit_module) != PJ_SUCCESS)
+ {
/* Failure to register this function may cause this module won't
* work properly when the stack is restarted (without quitting
* application).
diff --git a/pjsip/src/pjsip-ua/sip_timer.c b/pjsip/src/pjsip-ua/sip_timer.c
index d907794f..17c83c24 100644
--- a/pjsip/src/pjsip-ua/sip_timer.c
+++ b/pjsip/src/pjsip-ua/sip_timer.c
@@ -495,8 +495,10 @@ static void stop_timer(pjsip_inv_session *inv)
}
/* Deinitialize Session Timers */
-static void pjsip_timer_deinit_module(void)
+static void pjsip_timer_deinit_module(pjsip_endpoint *endpt)
{
+ PJ_TODO(provide_initialized_flag_for_each_endpoint);
+ PJ_UNUSED_ARG(endpt);
is_initialized = PJ_FALSE;
}
@@ -531,7 +533,7 @@ PJ_DEF(pj_status_t) pjsip_timer_init_module(pjsip_endpoint *endpt)
return status;
/* Register deinit module to be executed when PJLIB shutdown */
- if (pj_atexit(&pjsip_timer_deinit_module) != PJ_SUCCESS) {
+ if (pjsip_endpt_atexit(endpt, &pjsip_timer_deinit_module) != PJ_SUCCESS) {
/* Failure to register this function may cause this module won't
* work properly when the stack is restarted (without quitting
* application).
diff --git a/pjsip/src/pjsip/sip_auth_aka.c b/pjsip/src/pjsip/sip_auth_aka.c
index 29deab7f..82efbaf9 100644
--- a/pjsip/src/pjsip/sip_auth_aka.c
+++ b/pjsip/src/pjsip/sip_auth_aka.c
@@ -152,22 +152,39 @@ PJ_DEF(pj_status_t) pjsip_auth_create_aka_response(
&auth->uri, &chal->realm, &aka_cred, method);
} else if (aka_version == 2) {
+
/*
* For AKAv2, password is base64 encoded [1] parameters:
* PRF(RES||IK||CK,"http-digest-akav2-password")
*
* The pseudo-random function (PRF) is HMAC-MD5 in this case.
- *
- * Hmmm.. but those above doesn't seem to work, and this below does!
*/
- aka_cred.data.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN +
- PJSIP_AKA_CKLEN;
- aka_cred.data.ptr = pj_pool_alloc(pool, aka_cred.data.slen);
-
- pj_memcpy(aka_cred.data.ptr + 0, res, PJSIP_AKA_RESLEN);
- pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN);
- pj_memcpy(aka_cred.data.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN,
- ck, PJSIP_AKA_CKLEN);
+
+ pj_str_t resikck;
+ const pj_str_t AKAv2_Passwd = { "http-digest-akav2-password", 26 };
+ pj_uint8_t hmac_digest[16];
+ char tmp_buf[48];
+ int hmac64_len;
+
+ resikck.slen = PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN + PJSIP_AKA_CKLEN;
+ pj_assert(resikck.slen <= PJ_ARRAY_SIZE(tmp_buf));
+ resikck.ptr = tmp_buf;
+ pj_memcpy(resikck.ptr + 0, res, PJSIP_AKA_RESLEN);
+ pj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN, ik, PJSIP_AKA_IKLEN);
+ pj_memcpy(resikck.ptr + PJSIP_AKA_RESLEN + PJSIP_AKA_IKLEN,
+ ck, PJSIP_AKA_CKLEN);
+
+ pj_hmac_md5((const pj_uint8_t*)AKAv2_Passwd.ptr, AKAv2_Passwd.slen,
+ (const pj_uint8_t*)resikck.ptr, resikck.slen,
+ hmac_digest);
+
+ aka_cred.data.slen = hmac64_len =
+ PJ_BASE256_TO_BASE64_LEN(PJ_ARRAY_SIZE(hmac_digest));
+ pj_assert(aka_cred.data.slen+1 <= PJ_ARRAY_SIZE(tmp_buf));
+ aka_cred.data.ptr = tmp_buf;
+ pj_base64_encode(hmac_digest, PJ_ARRAY_SIZE(hmac_digest),
+ aka_cred.data.ptr, &len);
+ aka_cred.data.slen = hmac64_len;
pjsip_auth_create_digest(&auth->response, &chal->nonce,
&auth->nc, &auth->cnonce, &auth->qop,
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index 8684cc9b..4bde8539 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -1103,7 +1103,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
PJSIP_EINVALIDSTATUS);
tdata = old_request;
-
+ tdata->auth_retry = PJ_FALSE;
+
/*
* Respond to each authentication challenge.
*/
@@ -1174,6 +1175,9 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
/* Must invalidate the message! */
pjsip_tx_data_invalidate_msg(tdata);
+ /* Retrying.. */
+ tdata->auth_retry = PJ_TRUE;
+
/* Increment reference counter. */
pjsip_tx_data_add_ref(tdata);
diff --git a/pjsip/src/pjsip/sip_config.c b/pjsip/src/pjsip/sip_config.c
index 37a66a67..ce970e8a 100644
--- a/pjsip/src/pjsip/sip_config.c
+++ b/pjsip/src/pjsip/sip_config.c
@@ -25,7 +25,9 @@ pjsip_cfg_t pjsip_sip_cfg_var =
{
/* Global settings */
{
- PJSIP_ALLOW_PORT_IN_FROMTO_HDR
+ PJSIP_ALLOW_PORT_IN_FROMTO_HDR,
+ 0,
+ PJSIP_DONT_SWITCH_TO_TCP
},
/* Transaction settings */
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index d39b9355..3eb865b1 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -40,6 +40,15 @@
#define MAX_METHODS 32
+
+/* List of SIP endpoint exit callback. */
+typedef struct exit_cb
+{
+ PJ_DECL_LIST_MEMBER (struct exit_cb);
+ pjsip_endpt_exit_callback func;
+} exit_cb;
+
+
/**
* The SIP endpoint.
*/
@@ -86,6 +95,9 @@ struct pjsip_endpoint
/** Additional request headers. */
pjsip_hdr req_hdr;
+
+ /** List of exit callback. */
+ exit_cb exit_cb_list;
};
@@ -445,6 +457,9 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
/* Init modules list. */
pj_list_init(&endpt->module_list);
+ /* Initialize exit callback list. */
+ pj_list_init(&endpt->exit_cb_list);
+
/* Create R/W mutex for module manipulation. */
status = pj_rwmutex_create(endpt->pool, "ept%p", &endpt->mod_mutex);
if (status != PJ_SUCCESS)
@@ -559,6 +574,7 @@ on_error:
PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)
{
pjsip_module *mod;
+ exit_cb *ecb;
PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance.."));
@@ -592,6 +608,13 @@ PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)
/* Destroy timer heap */
pj_timer_heap_destroy(endpt->timer_heap);
+ /* Call all registered exit callbacks */
+ ecb = endpt->exit_cb_list.next;
+ while (ecb != &endpt->exit_cb_list) {
+ (*ecb->func)(endpt);
+ ecb = ecb->next;
+ }
+
/* Delete endpoint mutex. */
pj_mutex_destroy(endpt->mutex);
@@ -1182,3 +1205,20 @@ PJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail )
#endif
}
+
+PJ_DEF(pj_status_t) pjsip_endpt_atexit( pjsip_endpoint *endpt,
+ pjsip_endpt_exit_callback func)
+{
+ exit_cb *new_cb;
+
+ PJ_ASSERT_RETURN(endpt && func, PJ_EINVAL);
+
+ new_cb = PJ_POOL_ZALLOC_T(endpt->pool, exit_cb);
+ new_cb->func = func;
+
+ pj_mutex_lock(endpt->mutex);
+ pj_list_push_back(&endpt->exit_cb_list, new_cb);
+ pj_mutex_unlock(endpt->mutex);
+
+ return PJ_SUCCESS;
+}
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index c127162b..3acef980 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -714,23 +714,17 @@ static pj_status_t mod_tsx_layer_stop(void)
}
pj_mutex_unlock(mod_tsx_layer.mutex);
+
+ PJ_LOG(4,(THIS_FILE, "Stopped transaction layer module"));
+
return PJ_SUCCESS;
}
-/* This module callback is called when module is being unloaded by
- * endpoint.
- */
-static pj_status_t mod_tsx_layer_unload(void)
+/* Destroy this module */
+static void tsx_layer_destroy(pjsip_endpoint *endpt)
{
- /* Only self destroy when there's no transaction in the table.
- * Transaction may refuse to destroy when it has pending
- * transmission. If we destroy the module now, application will
- * crash when the pending transaction finally got error response
- * from transport and when it tries to unregister itself.
- */
- if (pj_hash_count(mod_tsx_layer.htable) != 0)
- return PJ_EBUSY;
+ PJ_UNUSED_ARG(endpt);
/* Destroy mutex. */
pj_mutex_destroy(mod_tsx_layer.mutex);
@@ -745,6 +739,31 @@ static pj_status_t mod_tsx_layer_unload(void)
mod_tsx_layer.endpt = NULL;
PJ_LOG(4,(THIS_FILE, "Transaction layer module destroyed"));
+}
+
+
+/* This module callback is called when module is being unloaded by
+ * endpoint.
+ */
+static pj_status_t mod_tsx_layer_unload(void)
+{
+ /* Only self destroy when there's no transaction in the table.
+ * Transaction may refuse to destroy when it has pending
+ * transmission. If we destroy the module now, application will
+ * crash when the pending transaction finally got error response
+ * from transport and when it tries to unregister itself.
+ */
+ if (pj_hash_count(mod_tsx_layer.htable) != 0) {
+ if (pjsip_endpt_atexit(mod_tsx_layer.endpt, &tsx_layer_destroy) !=
+ PJ_SUCCESS)
+ {
+ PJ_LOG(3,(THIS_FILE, "Failed to register transaction layer "
+ "module destroy."));
+ }
+ return PJ_EBUSY;
+ }
+
+ tsx_layer_destroy(mod_tsx_layer.endpt);
return PJ_SUCCESS;
}
@@ -3239,7 +3258,10 @@ static pj_status_t tsx_on_state_destroyed(pjsip_transaction *tsx,
{
PJ_UNUSED_ARG(tsx);
PJ_UNUSED_ARG(event);
- pj_assert(!"Not expecting any events!!");
- return PJ_EBUG;
+
+ // See https://trac.pjsip.org/repos/ticket/1432
+ //pj_assert(!"Not expecting any events!!");
+
+ return PJ_EIGNORED;
}
diff --git a/pjsip/src/pjsip/sip_transport_tls.c b/pjsip/src/pjsip/sip_transport_tls.c
index face6b88..bae3ffd1 100644
--- a/pjsip/src/pjsip/sip_transport_tls.c
+++ b/pjsip/src/pjsip/sip_transport_tls.c
@@ -293,6 +293,8 @@ PJ_DEF(pj_status_t) pjsip_tls_transport_start (pjsip_endpoint *endpt,
ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;
if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+ ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+ ssock_param.ciphers = listener->tls_setting.ciphers;
ssock_param.qos_type = listener->tls_setting.qos_type;
ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,
@@ -862,7 +864,6 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
ssock_param.cb.on_data_sent = &on_data_sent;
ssock_param.async_cnt = 1;
ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt);
- PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type);
ssock_param.server_name = remote_name;
ssock_param.timeout = listener->tls_setting.timeout;
ssock_param.user_data = NULL; /* pending, must be set later */
@@ -872,6 +873,8 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN;
if (ssock_param.read_buffer_size < PJSIP_MAX_PKT_LEN)
ssock_param.read_buffer_size = PJSIP_MAX_PKT_LEN;
+ ssock_param.ciphers_num = listener->tls_setting.ciphers_num;
+ ssock_param.ciphers = listener->tls_setting.ciphers;
ssock_param.qos_type = listener->tls_setting.qos_type;
ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
pj_memcpy(&ssock_param.qos_params, &listener->tls_setting.qos_params,
diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
index 4f82a1a6..f238f524 100644
--- a/pjsip/src/pjsip/sip_util.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -1248,14 +1248,14 @@ stateless_send_resolver_callback( pj_status_t status,
}
pj_assert(tdata->dest_info.addr.count != 0);
-#if !defined(PJSIP_DONT_SWITCH_TO_TCP) || PJSIP_DONT_SWITCH_TO_TCP==0
/* RFC 3261 section 18.1.1:
* If a request is within 200 bytes of the path MTU, or if it is larger
* than 1300 bytes and the path MTU is unknown, the request MUST be sent
* using an RFC 2914 [43] congestion controlled transport protocol, such
* as TCP.
*/
- if (tdata->msg->type == PJSIP_REQUEST_MSG &&
+ if (pjsip_cfg()->endpt.disable_tcp_switch==0 &&
+ tdata->msg->type == PJSIP_REQUEST_MSG &&
tdata->dest_info.addr.count > 0 &&
tdata->dest_info.addr.entry[0].type == PJSIP_TRANSPORT_UDP)
{
@@ -1297,7 +1297,6 @@ stateless_send_resolver_callback( pj_status_t status,
tdata->dest_info.addr.count = count * 2;
}
}
-#endif /* !PJSIP_DONT_SWITCH_TO_TCP */
/* Process the addresses. */
stateless_send_transport_cb( stateless_data, tdata, -PJ_EPENDING);
diff --git a/pjsip/src/pjsua-lib/pjsua_aud.c b/pjsip/src/pjsua-lib/pjsua_aud.c
index d80981d6..cbe52daf 100644
--- a/pjsip/src/pjsua-lib/pjsua_aud.c
+++ b/pjsip/src/pjsua-lib/pjsua_aud.c
@@ -26,7 +26,7 @@
#define NULL_SND_DEV_ID -99
/*****************************************************************************
-/*
+ *
* Prototypes
*/
/* Open sound dev */
@@ -43,7 +43,7 @@ static pj_status_t create_aud_param(pjmedia_aud_param *param,
unsigned bits_per_sample);
/*****************************************************************************
-/*
+ *
* Call API that are closely tied to PJMEDIA
*/
/*
@@ -223,7 +223,7 @@ on_return:
/*****************************************************************************
-/*
+ *
* Audio media with PJMEDIA backend
*/
@@ -806,13 +806,13 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
source, sink));
pj_log_push_indent();
- /* If sound device idle timer is active, cancel it first. */
PJSUA_LOCK();
+
+ /* If sound device idle timer is active, cancel it first. */
if (pjsua_var.snd_idle_timer.id) {
pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer);
pjsua_var.snd_idle_timer.id = PJ_FALSE;
}
- PJSUA_UNLOCK();
/* For audio switchboard (i.e. APS-Direct):
@@ -910,8 +910,6 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&
!pjsua_var.no_snd)
{
- pj_status_t status;
-
status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
@@ -926,9 +924,13 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
}
}
- status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);
-
on_return:
+ PJSUA_UNLOCK();
+
+ if (status == PJ_SUCCESS) {
+ status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);
+ }
+
pj_log_pop_indent();
return status;
}
@@ -1851,8 +1853,11 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
capture_dev, playback_dev));
pj_log_push_indent();
+ PJSUA_LOCK();
+
/* Null-sound */
if (capture_dev==NULL_SND_DEV_ID && playback_dev==NULL_SND_DEV_ID) {
+ PJSUA_UNLOCK();
status = pjsua_set_null_snd_dev();
pj_log_pop_indent();
return status;
@@ -1903,10 +1908,12 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
pjsua_var.no_snd = PJ_FALSE;
pjsua_var.snd_is_on = PJ_TRUE;
+ PJSUA_UNLOCK();
pj_log_pop_indent();
return PJ_SUCCESS;
on_error:
+ PJSUA_UNLOCK();
pj_log_pop_indent();
return status;
}
@@ -1920,6 +1927,8 @@ on_error:
PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
int *playback_dev)
{
+ PJSUA_LOCK();
+
if (capture_dev) {
*capture_dev = pjsua_var.cap_dev;
}
@@ -1927,6 +1936,7 @@ PJ_DEF(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
*playback_dev = pjsua_var.play_dev;
}
+ PJSUA_UNLOCK();
return PJ_SUCCESS;
}
@@ -1942,6 +1952,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
PJ_LOG(4,(THIS_FILE, "Setting null sound device.."));
pj_log_push_indent();
+ PJSUA_LOCK();
/* Close existing sound device */
close_snd_dev();
@@ -1969,6 +1980,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create null sound device",
status);
+ PJSUA_UNLOCK();
pj_log_pop_indent();
return status;
}
@@ -1983,6 +1995,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
pjsua_var.no_snd = PJ_FALSE;
pjsua_var.snd_is_on = PJ_TRUE;
+ PJSUA_UNLOCK();
pj_log_pop_indent();
return PJ_SUCCESS;
}
@@ -1994,10 +2007,14 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
*/
PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
{
+ PJSUA_LOCK();
+
/* Close existing sound device */
close_snd_dev();
-
pjsua_var.no_snd = PJ_TRUE;
+
+ PJSUA_UNLOCK();
+
return pjmedia_conf_get_master_port(pjsua_var.mconf);
}
@@ -2007,13 +2024,18 @@ PJ_DEF(pjmedia_port*) pjsua_set_no_snd_dev(void)
*/
PJ_DEF(pj_status_t) pjsua_set_ec(unsigned tail_ms, unsigned options)
{
+ pj_status_t status = PJ_SUCCESS;
+
+ PJSUA_LOCK();
+
pjsua_var.media_cfg.ec_tail_len = tail_ms;
if (pjsua_var.snd_port)
- return pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool,
- tail_ms, options);
+ status = pjmedia_snd_port_set_ec(pjsua_var.snd_port, pjsua_var.pool,
+ tail_ms, options);
- return PJ_SUCCESS;
+ PJSUA_UNLOCK();
+ return status;
}
@@ -2050,6 +2072,8 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
return PJMEDIA_EAUD_INVCAP;
}
+ PJSUA_LOCK();
+
/* If sound is active, set it immediately */
if (pjsua_snd_is_active()) {
pjmedia_aud_stream *strm;
@@ -2060,8 +2084,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
status = PJ_SUCCESS;
}
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
+ PJSUA_UNLOCK();
return status;
+ }
/* Save in internal param for later device open */
if (keep) {
@@ -2069,6 +2095,7 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
cap, pval);
}
+ PJSUA_UNLOCK();
return status;
}
@@ -2078,6 +2105,10 @@ PJ_DEF(pj_status_t) pjsua_snd_set_setting( pjmedia_aud_dev_cap cap,
PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap,
void *pval)
{
+ pj_status_t status;
+
+ PJSUA_LOCK();
+
/* If sound device has never been opened before, open it to
* retrieve the initial setting from the device (e.g. audio
* volume)
@@ -2093,12 +2124,15 @@ PJ_DEF(pj_status_t) pjsua_snd_get_setting( pjmedia_aud_dev_cap cap,
pjmedia_aud_stream *strm;
strm = pjmedia_snd_port_get_snd_stream(pjsua_var.snd_port);
- return pjmedia_aud_stream_get_cap(strm, cap, pval);
+ status = pjmedia_aud_stream_get_cap(strm, cap, pval);
} else {
/* Otherwise retrieve from internal param */
- return pjmedia_aud_param_get_cap(&pjsua_var.aud_param,
- cap, pval);
+ status = pjmedia_aud_param_get_cap(&pjsua_var.aud_param,
+ cap, pval);
}
+
+ PJSUA_UNLOCK();
+ return status;
}
#endif /* PJSUA_MEDIA_HAS_PJMEDIA */
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 6a4e4dc7..6f0d1048 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -2929,12 +2929,10 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
pjsua_call *call;
pj_log_push_indent();
- PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
if (!call) {
- PJSUA_UNLOCK();
pj_log_pop_indent();
return;
}
@@ -3077,21 +3075,21 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
/* Destroy media session when invite session is disconnected. */
if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
- pj_assert(call != NULL);
-
- if (call)
- pjsua_media_channel_deinit(call->index);
+ PJSUA_LOCK();
+
+ pjsua_media_channel_deinit(call->index);
/* Free call */
call->inv = NULL;
+
+ pj_assert(pjsua_var.call_cnt > 0);
--pjsua_var.call_cnt;
/* Reset call */
reset_call(call->index);
+ PJSUA_UNLOCK();
}
-
- PJSUA_UNLOCK();
pj_log_pop_indent();
}
@@ -3202,7 +3200,6 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv,
//const pj_str_t st_update = {"UPDATE", 6};
pj_log_push_indent();
- PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
@@ -3279,7 +3276,6 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv,
pjsua_var.ua_cfg.cb.on_call_media_state(call->index);
on_return:
- PJSUA_UNLOCK();
pj_log_pop_indent();
}
@@ -3392,8 +3388,6 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
unsigned i;
pj_status_t status;
- PJSUA_LOCK();
-
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
/* Supply candidate answer */
@@ -3480,7 +3474,6 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv,
}
on_return:
- PJSUA_UNLOCK();
pj_log_pop_indent();
}
@@ -3495,7 +3488,6 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
pj_status_t status;
pj_log_push_indent();
- PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
@@ -3520,7 +3512,6 @@ static void pjsua_call_on_create_offer(pjsip_inv_session *inv,
}
on_return:
- PJSUA_UNLOCK();
pj_log_pop_indent();
}
@@ -3983,7 +3974,6 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
pjsua_call *call;
pj_log_push_indent();
- PJSUA_LOCK();
call = (pjsua_call*) inv->dlg->mod_data[pjsua_var.mod.id];
@@ -3999,6 +3989,17 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
goto on_return;
}
+ /* https://trac.pjsip.org/repos/ticket/1452:
+ * If a request is retried due to 401/407 challenge, don't process the
+ * transaction first but wait until we've retried it.
+ */
+ if (tsx->role == PJSIP_ROLE_UAC &&
+ (tsx->status_code==401 || tsx->status_code==407) &&
+ tsx->last_tx && tsx->last_tx->auth_retry)
+ {
+ goto on_return;
+ }
+
/* Notify application callback first */
if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);
@@ -4124,8 +4125,6 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
}
on_return:
-
- PJSUA_UNLOCK();
pj_log_pop_indent();
}
@@ -4139,7 +4138,6 @@ static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
pjsip_redirect_op op;
pj_log_push_indent();
- PJSUA_LOCK();
if (pjsua_var.ua_cfg.cb.on_call_redirected) {
op = (*pjsua_var.ua_cfg.cb.on_call_redirected)(call->index,
@@ -4152,7 +4150,6 @@ static pjsip_redirect_op pjsua_call_on_redirected(pjsip_inv_session *inv,
op = PJSIP_REDIRECT_STOP;
}
- PJSUA_UNLOCK();
pj_log_pop_indent();
return op;
diff --git a/pjsip/src/pjsua-lib/pjsua_dump.c b/pjsip/src/pjsua-lib/pjsua_dump.c
index 7279e512..c629e106 100644
--- a/pjsip/src/pjsua-lib/pjsua_dump.c
+++ b/pjsip/src/pjsua-lib/pjsua_dump.c
@@ -413,7 +413,6 @@ static void dump_media_session(const char *indent,
const char *type2 = pj_ice_get_cand_type_name(ii->comp[jj].rcand_type);
char addr1[PJ_INET6_ADDRSTRLEN+10];
char addr2[PJ_INET6_ADDRSTRLEN+10];
- const char *comp_name[2] = {"rtp ", "rtcp"};
if (pj_sockaddr_has_addr(&ii->comp[jj].lcand_addr))
pj_sockaddr_print(&ii->comp[jj].lcand_addr, addr1, sizeof(addr1), 3);
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 2810a24b..56e5bce2 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -97,8 +97,8 @@ pj_status_t pjsua_media_subsys_init(const pjsua_media_config *cfg)
goto on_error;
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
- /* Initialize SRTP library. */
- status = pjmedia_srtp_init_lib();
+ /* Initialize SRTP library (ticket #788). */
+ status = pjmedia_srtp_init_lib(pjsua_var.med_endpt);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error initializing SRTP library",
status);