Ticket #611: Configuration option to force the route URI to use loose routing

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2301 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2008-09-20 12:16:56 +00:00
parent 9489e7a098
commit 91d06b6179
6 changed files with 106 additions and 2 deletions

View File

@ -277,6 +277,7 @@ static void usage(void)
puts (" --duration=SEC Set maximum call duration (default:no limit)");
puts (" --norefersub Suppress event subscription when transfering calls");
puts (" --use-compact-form Minimize SIP message size");
puts (" --no-force-lr Allow strict-route to be used (i.e. do not force lr)");
puts ("");
puts ("When URL is specified, pjsua will immediately initiate call to that URL");
@ -481,7 +482,8 @@ static pj_status_t parse_args(int argc, char *argv[],
#ifdef _IONBF
OPT_STDOUT_NO_BUF,
#endif
OPT_AUTO_UPDATE_NAT,OPT_USE_COMPACT_FORM,OPT_DIS_CODEC
OPT_AUTO_UPDATE_NAT,OPT_USE_COMPACT_FORM,OPT_DIS_CODEC,
OPT_NO_FORCE_LR
};
struct pj_getopt_option long_options[] = {
{ "config-file",1, 0, OPT_CONFIG_FILE},
@ -513,6 +515,7 @@ static pj_status_t parse_args(int argc, char *argv[],
{ "contact", 1, 0, OPT_CONTACT},
{ "auto-update-nat", 1, 0, OPT_AUTO_UPDATE_NAT},
{ "use-compact-form", 0, 0, OPT_USE_COMPACT_FORM},
{ "no-force-lr",0, 0, OPT_NO_FORCE_LR},
{ "realm", 1, 0, OPT_REALM},
{ "username", 1, 0, OPT_USERNAME},
{ "password", 1, 0, OPT_PASSWORD},
@ -837,6 +840,10 @@ static pj_status_t parse_args(int argc, char *argv[],
}
break;
case OPT_NO_FORCE_LR:
cfg->cfg.force_lr = PJ_FALSE;
break;
case OPT_NEXT_ACCOUNT: /* Add more account. */
cfg->acc_cnt++;
cur_acc = &cfg->acc_cfg[cfg->acc_cnt];
@ -1800,6 +1807,10 @@ static int write_settings(const struct app_config *config,
pj_strcat2(&cfg, "--use-compact-form\n");
}
if (config->cfg.force_lr) {
pj_strcat2(&cfg, "--no-force-lr\n");
}
pj_strcat2(&cfg, "\n#\n# Buddies:\n#\n");
/* Add buddies. */

View File

@ -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.
*/

View File

@ -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.

View File

@ -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; i<acc->cfg.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);

View File

@ -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; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
status = normalize_route_uri(pjsua_var.pool,
&pjsua_var.ua_cfg.outbound_proxy[i]);
if (status != PJ_SUCCESS)
return status;
}
/* Initialize invite session callback. */
pj_bzero(&inv_cb, sizeof(inv_cb));
inv_cb.on_state_changed = &pjsua_call_on_state_changed;

View File

@ -91,6 +91,7 @@ PJ_DEF(void) pjsua_config_default(pjsua_config *cfg)
cfg->max_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.