From 643ea6e515fc75d19cd3f0a6dbdb00ac2b2fd167 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sat, 20 Sep 2008 12:16:56 +0000 Subject: Ticket #611: Configuration option to force the route URI to use loose routing git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2301 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 10 +++++ pjsip/include/pjsua-lib/pjsua_internal.h | 5 +++ pjsip/src/pjsua-lib/pjsua_acc.c | 9 ++++- pjsip/src/pjsua-lib/pjsua_call.c | 8 ++++ pjsip/src/pjsua-lib/pjsua_core.c | 63 ++++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) (limited to 'pjsip') diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index f8801776..e377e059 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1114,6 +1114,16 @@ typedef struct pjsua_config */ pj_str_t nameserver[4]; + /** + * Force loose-route to be used in all route/proxy URIs (outbound_proxy + * and account's proxy settings). When this setting is enabled, the + * library will check all the route/proxy URIs specified in the settings + * and append ";lr" parameter to the URI if the parameter is not present. + * + * Default: 1 + */ + pj_bool_t force_lr; + /** * Number of outbound proxies in the \a outbound_proxy array. */ diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index d52b6d52..ef1487a4 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -342,6 +342,11 @@ PJ_INLINE(pjsua_im_data*) pjsua_im_data_dup(pj_pool_t *pool, #define PJSUA_UNLOCK() #endif +/** + * Normalize route URI (check for ";lr" and append one if it doesn't + * exist and pjsua_config.force_lr is set. + */ +pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri); /** * Resolve STUN server. diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index f157da0d..438b63f0 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -256,7 +256,7 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, pjsua_acc_id *p_acc_id) { pjsua_acc *acc; - unsigned id; + unsigned i, id; pj_status_t status; PJ_ASSERT_RETURN(pjsua_var.acc_cnt < PJ_ARRAY_SIZE(pjsua_var.acc), @@ -295,6 +295,13 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, pjsua_var.acc[id].cfg.reg_timeout = PJSUA_REG_INTERVAL; } + /* Check the route URI's and force loose route if required */ + for (i=0; icfg.proxy_cnt; ++i) { + status = normalize_route_uri(acc->pool, &acc->cfg.proxy[i]); + if (status != PJ_SUCCESS) + return status; + } + status = initialize_acc(id); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error adding account", status); diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 9f3b9fc1..7eb061cc 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -140,6 +140,14 @@ pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg) /* Copy config */ pjsua_config_dup(pjsua_var.pool, &pjsua_var.ua_cfg, cfg); + /* Check the route URI's and force loose route if required */ + for (i=0; imax_calls = 4; cfg->thread_cnt = 1; cfg->nat_type_in_sdp = 1; + cfg->force_lr = PJ_TRUE; #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) cfg->use_srtp = PJSUA_DEFAULT_USE_SRTP; cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING; @@ -2076,6 +2077,68 @@ PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url) } +/** + * Normalize route URI (check for ";lr" and append one if it doesn't + * exist and pjsua_config.force_lr is set. + */ +pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri) +{ + pj_str_t tmp_uri; + pj_pool_t *tmp_pool; + pjsip_uri *uri_obj; + pjsip_sip_uri *sip_uri; + + tmp_pool = pjsua_pool_create("tmplr%p", 512, 512); + if (!tmp_pool) + return PJ_ENOMEM; + + pj_strdup_with_null(tmp_pool, &tmp_uri, uri); + + uri_obj = pjsip_parse_uri(tmp_pool, tmp_uri.ptr, tmp_uri.slen, 0); + if (!uri_obj) { + PJ_LOG(1,(THIS_FILE, "Invalid route URI: %.*s", + (int)uri->slen, uri->ptr)); + pj_pool_release(tmp_pool); + return PJSIP_EINVALIDURI; + } + + if (!PJSIP_URI_SCHEME_IS_SIP(uri_obj) && + !PJSIP_URI_SCHEME_IS_SIP(uri_obj)) + { + PJ_LOG(1,(THIS_FILE, "Route URI must be SIP URI: %.*s", + (int)uri->slen, uri->ptr)); + pj_pool_release(tmp_pool); + return PJSIP_EINVALIDSCHEME; + } + + sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri_obj); + + /* Done if force_lr is disabled or if lr parameter is present */ + if (!pjsua_var.ua_cfg.force_lr || sip_uri->lr_param) { + pj_pool_release(tmp_pool); + return PJ_SUCCESS; + } + + /* Set lr param */ + sip_uri->lr_param = 1; + + /* Print the URI */ + tmp_uri.ptr = (char*) pj_pool_alloc(tmp_pool, PJSIP_MAX_URL_SIZE); + tmp_uri.slen = pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR, uri_obj, + tmp_uri.ptr, PJSIP_MAX_URL_SIZE); + if (tmp_uri.slen < 1) { + PJ_LOG(1,(THIS_FILE, "Route URI is too long: %.*s", + (int)uri->slen, uri->ptr)); + pj_pool_release(tmp_pool); + return PJSIP_EURITOOLONG; + } + + /* Clone the URI */ + pj_strdup_with_null(pool, uri, &tmp_uri); + + return PJ_SUCCESS; +} + /* * This is a utility function to dump the stack states to log, using * verbosity level 3. -- cgit v1.2.3