diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-01-13 23:22:40 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-01-13 23:22:40 +0000 |
commit | 2fe4e4e9985b9c4cbff7209a9c876a314abc9779 (patch) | |
tree | 216d17b9d93ad17b74f70e76a5913fd18243ddb3 /pjsip | |
parent | 79a935f4554f9b852862e52df82c02b2ef22bae8 (diff) |
More work on ticket #50: binding of PJSUA-API account to specific transport, and minor fixes in PJSIP core implementation. Tested okay.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@881 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 4 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 34 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 14 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_dialog.c | 4 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_errno.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 17 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 72 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 19 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 30 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_im.c | 20 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_pres.c | 20 |
11 files changed, 219 insertions, 16 deletions
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h index 30516de7..1c82c385 100644 --- a/pjsip/include/pjsip/sip_transport.h +++ b/pjsip/include/pjsip/sip_transport.h @@ -917,7 +917,8 @@ PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, * * @param tpmgr The transport manager. * @param pool Pool to allocate memory for the IP address. - * @param h Destination address to contact. + * @param type Destination address to contact. + * @param sel Optional pointer to prefered transport, if any. * @param ip_addr Pointer to receive the IP address. * @param port Pointer to receive the port number. * @@ -926,6 +927,7 @@ PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, PJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, pj_pool_t *pool, pjsip_transport_type_e type, + const pjsip_tpselector *sel, pj_str_t *ip_addr, int *port); diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 02b05ef4..f0bf5775 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1341,6 +1341,19 @@ typedef struct pjsua_acc_config */ pjsip_cred_info cred_info[PJSUA_ACC_MAX_PROXIES]; + /** + * Optionally bind this account to specific transport. This normally is + * not a good idea, as account should be able to send requests using + * any available transports according to the destination. But some + * application may want to have explicit control over the transport to + * use, so in that case it can set this field. + * + * Default: -1 (PJSUA_INVALID_ID) + * + * @see pjsua_acc_set_transport() + */ + pjsua_transport_id transport_id; + } pjsua_acc_config; @@ -1354,6 +1367,7 @@ PJ_INLINE(void) pjsua_acc_config_default(pjsua_acc_config *cfg) pj_bzero(cfg, sizeof(*cfg)); cfg->reg_timeout = PJSUA_REG_INTERVAL; + cfg->transport_id = PJSUA_INVALID_ID; } @@ -1655,6 +1669,26 @@ PJ_DECL(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, pjsip_rx_data *rdata ); +/** + * Lock/bind this account to a specific transport/listener. Normally + * application shouldn't need to do this, as transports will be selected + * automatically by the stack according to the destination. + * + * When account is locked/bound to a specific transport, all outgoing + * requests from this account will use the specified transport (this + * includes SIP registration, dialog (call and event subscription), and + * out-of-dialog requests such as MESSAGE). + * + * Note that transport_id may be specified in pjsua_acc_config too. + * + * @param acc_id The account ID. + * @param tp_id The transport ID. + * + * @return PJ_SUCCESS on success. + */ +PJ_DECL(pj_status_t) pjsua_acc_set_transport(pjsua_acc_id acc_id, + pjsua_transport_id tp_id); + /** * @} diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index 0664b721..43d28591 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -106,7 +106,7 @@ typedef struct pjsua_acc /** *Transport. */ -typedef struct transport_data +typedef struct pjsua_transport_data { int index; pjsip_transport_type_e type; @@ -118,7 +118,7 @@ typedef struct transport_data void *ptr; } data; -} transport_data; +} pjsua_transport_data; /** @@ -179,7 +179,7 @@ struct pjsua_data /* SIP: */ pjsip_endpoint *endpt; /**< Global endpoint. */ pjsip_module mod; /**< pjsua's PJSIP module. */ - transport_data tpdata[8]; /**< Array of transports. */ + pjsua_transport_data tpdata[8]; /**< Array of transports. */ /* Threading: */ pj_bool_t thread_quit_flag; /**< Thread quit flag. */ @@ -379,6 +379,14 @@ void pjsua_parse_media_type( pj_pool_t *pool, pjsip_media_type *media_type); +/* + * Internal function to init transport selector from transport id. + */ +void pjsua_init_tpselector(pjsua_transport_id tp_id, + pjsip_tpselector *sel); + + + PJ_END_DECL #endif /* __PJSUA_INTERNAL_H__ */ diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c index bf8eef40..7b97e5b8 100644 --- a/pjsip/src/pjsip/sip_dialog.c +++ b/pjsip/src/pjsip/sip_dialog.c @@ -101,6 +101,10 @@ static void destroy_dialog( pjsip_dialog *dlg ) pj_mutex_destroy(dlg->mutex_); dlg->mutex_ = NULL; } + if (dlg->tp_sel.type != PJSIP_TPSELECTOR_NONE) { + pjsip_tpselector_dec_ref(&dlg->tp_sel); + pj_bzero(&dlg->tp_sel, sizeof(pjsip_tpselector)); + } pjsip_endpt_release_pool(dlg->endpt, dlg->pool); } diff --git a/pjsip/src/pjsip/sip_errno.c b/pjsip/src/pjsip/sip_errno.c index 7ca4d215..b9ca4dd3 100644 --- a/pjsip/src/pjsip/sip_errno.c +++ b/pjsip/src/pjsip/sip_errno.c @@ -67,6 +67,7 @@ static const struct PJ_BUILD_ERR( PJSIP_EPENDINGTX, "Transmit buffer already pending"), PJ_BUILD_ERR( PJSIP_ERXOVERFLOW, "Rx buffer overflow"), PJ_BUILD_ERR( PJSIP_EBUFDESTROYED, "Buffer destroyed"), + PJ_BUILD_ERR( PJSIP_ETPNOTSUITABLE, "Unsuitable transport selected"), /* Transaction errors */ PJ_BUILD_ERR( PJSIP_ETSXDESTROYED, "Transaction has been destroyed"), diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 9a3ae6a1..b01676bb 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -940,6 +940,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, pj_pool_t *pool, pjsip_transport_type_e type, + const pjsip_tpselector *sel, pj_str_t *ip_addr, int *port) { @@ -954,7 +955,21 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, flag = pjsip_transport_get_flag_from_type(type); - if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { + if (sel && sel->type == PJSIP_TPSELECTOR_TRANSPORT && + sel->u.transport) + { + pj_strdup(pool, ip_addr, &sel->u.transport->local_name.host); + *port = sel->u.transport->local_name.port; + status = PJ_SUCCESS; + + } else if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER && + sel->u.listener) + { + pj_strdup(pool, ip_addr, &sel->u.listener->addr_name.host); + *port = sel->u.listener->addr_name.port; + status = PJ_SUCCESS; + + } else if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { pj_sockaddr_in remote; pjsip_transport *tp; diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index fd71f993..37f36ce7 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -225,7 +225,6 @@ static pj_status_t initialize_acc(unsigned acc_id) if (status != PJ_SUCCESS) return status; - /* Mark account as valid */ pjsua_var.acc[acc_id].valid = PJ_TRUE; @@ -258,7 +257,6 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, PJ_ETOOMANY); /* Must have a transport */ - PJ_TODO(associate_acc_with_transport); PJ_ASSERT_RETURN(pjsua_var.tpdata[0].data.ptr != NULL, PJ_EINVALIDOP); PJSUA_LOCK(); @@ -320,7 +318,7 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid, pjsua_acc_id *p_acc_id) { pjsua_acc_config cfg; - struct transport_data *t = &pjsua_var.tpdata[tid]; + pjsua_transport_data *t = &pjsua_var.tpdata[tid]; char uri[PJSIP_MAX_URL_SIZE]; /* ID must be valid */ @@ -382,7 +380,10 @@ PJ_DEF(pj_status_t) pjsua_acc_del(pjsua_acc_id acc_id) --pjsua_var.acc_cnt; } - PJ_TODO(may_need_to_scan_calls); + /* Leave the calls intact, as I don't think calls need to + * access account once it's created + */ + PJSUA_UNLOCK(); @@ -491,6 +492,7 @@ static pj_status_t pjsua_regc_init(int acc_id) pj_pool_t *pool; pj_status_t status; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; if (acc->cfg.reg_uri.slen == 0) { @@ -538,6 +540,17 @@ static pj_status_t pjsua_regc_init(int acc_id) return status; } + /* If account is locked to specific transport, then set transport to + * the client registration. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_regc_set_transport(acc->regc, &tp_sel); + } + + /* Set credentials */ if (acc->cred_cnt) { @@ -640,6 +653,7 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( pjsua_acc_id acc_id, pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; PJ_ASSERT_RETURN(info != NULL, PJ_EINVAL); + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); pj_bzero(info, sizeof(pjsua_acc_info)); @@ -854,7 +868,7 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->user_part, &sip_uri->user)==0 && + if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0 && pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { /* Match ! */ @@ -868,19 +882,30 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { + if (acc->valid && pj_stricmp(&acc->srv_domain, &sip_uri->host)==0) { /* Match ! */ PJSUA_UNLOCK(); return acc_id; } } - /* No matching account, try match user part only. */ + /* No matching account, try match user part (and transport type) only. */ for (i=0; i < pjsua_var.acc_cnt; ++i) { unsigned acc_id = pjsua_var.acc_ids[i]; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - if (pj_stricmp(&acc->user_part, &sip_uri->user)==0) { + if (acc->valid && pj_stricmp(&acc->user_part, &sip_uri->user)==0) { + + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_transport_type_e type; + type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); + if (type == PJSIP_TRANSPORT_UNSPECIFIED) + type = PJSIP_TRANSPORT_UDP; + + if (pjsua_var.tpdata[acc->cfg.transport_id].type != type) + continue; + } + /* Match ! */ PJSUA_UNLOCK(); return acc_id; @@ -903,10 +928,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, pj_status_t status; pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; pj_str_t local_addr; + pjsip_tpselector tp_sel; unsigned flag; int secure; int local_port; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; /* If route-set is configured for the account, then URI is the @@ -945,9 +972,13 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, flag = pjsip_transport_get_flag_from_type(tp_type); secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + /* Init transport selector. */ + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + /* Get local address suitable to send request from */ status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), - pool, tp_type, &local_addr, &local_port); + pool, tp_type, &tp_sel, + &local_addr, &local_port); if (status != PJ_SUCCESS) return status; @@ -990,10 +1021,12 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, pj_status_t status; pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; pj_str_t local_addr; + pjsip_tpselector tp_sel; unsigned flag; int secure; int local_port; + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); acc = &pjsua_var.acc[acc_id]; /* If Record-Route is present, then URI is the top Record-Route. */ @@ -1038,9 +1071,13 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, flag = pjsip_transport_get_flag_from_type(tp_type); secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + /* Init transport selector. */ + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + /* Get local address suitable to send request from */ status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), - pool, tp_type, &local_addr, &local_port); + pool, tp_type, &tp_sel, + &local_addr, &local_port); if (status != PJ_SUCCESS) return status; @@ -1064,4 +1101,19 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, } +PJ_DEF(pj_status_t) pjsua_acc_set_transport( pjsua_acc_id acc_id, + pjsua_transport_id tp_id) +{ + pjsua_acc *acc; + + PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); + acc = &pjsua_var.acc[acc_id]; + + PJ_ASSERT_RETURN(tp_id >= 0 && tp_id < PJ_ARRAY_SIZE(pjsua_var.tpdata), + PJ_EINVAL); + + acc->cfg.transport_id = tp_id; + + return PJ_SUCCESS; +} diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index f7b77348..6b40becf 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -330,6 +330,16 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, /* Attach user data */ call->user_data = user_data; + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Set dialog Route-Set: */ if (!pj_list_empty(&acc->route_set)) pjsip_dlg_set_route_set(dlg, &acc->route_set); @@ -619,6 +629,15 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) dlg->mod_data[pjsua_var.mod.id] = call; inv->mod_data[pjsua_var.mod.id] = call; + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } /* Must answer with some response to initial INVITE. */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 21864833..b7194111 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -1189,7 +1189,7 @@ PJ_DEF(pj_status_t) pjsua_enum_transports( pjsua_transport_id id[], PJ_DEF(pj_status_t) pjsua_transport_get_info( pjsua_transport_id id, pjsua_transport_info *info) { - struct transport_data *t = &pjsua_var.tpdata[id]; + pjsua_transport_data *t = &pjsua_var.tpdata[id]; pj_status_t status; pj_bzero(info, sizeof(*info)); @@ -1416,6 +1416,34 @@ void pjsua_parse_media_type( pj_pool_t *pool, /* + * Internal function to init transport selector from transport id. + */ +void pjsua_init_tpselector(pjsua_transport_id tp_id, + pjsip_tpselector *sel) +{ + pjsua_transport_data *tpdata; + unsigned flag; + + pj_bzero(sel, sizeof(*sel)); + if (tp_id == PJSUA_INVALID_ID) + return; + + pj_assert(tp_id >= 0 && tp_id < PJ_ARRAY_SIZE(pjsua_var.tpdata)); + tpdata = &pjsua_var.tpdata[tp_id]; + + flag = pjsip_transport_get_flag_from_type(tpdata->type); + + if (flag & PJSIP_TRANSPORT_DATAGRAM) { + sel->type = PJSIP_TPSELECTOR_TRANSPORT; + sel->u.transport = tpdata->data.tp; + } else { + sel->type = PJSIP_TPSELECTOR_LISTENER; + sel->u.listener = tpdata->data.factory; + } +} + + +/* * Verify that valid SIP url is given. */ PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url) diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c index 462796a0..0e29b43e 100644 --- a/pjsip/src/pjsua-lib/pjsua_im.c +++ b/pjsip/src/pjsua-lib/pjsua_im.c @@ -433,6 +433,16 @@ PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, return status; } + /* If account is locked to specific transport, then set transport to + * the request. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_tx_data_set_transport(tdata, &tp_sel); + } + /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); @@ -520,6 +530,16 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, } + /* If account is locked to specific transport, then set transport to + * the request. + */ + if (pjsua_var.acc[acc_id].cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(pjsua_var.acc[acc_id].cfg.transport_id, &tp_sel); + pjsip_tx_data_set_transport(tdata, &tp_sel); + } + /* Add accept header. */ pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 78f913d1..f9f87550 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -501,6 +501,16 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) return PJ_TRUE; } + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Attach our data to the subscription: */ uapres = pj_pool_alloc(dlg->pool, sizeof(pjsua_srv_pres)); uapres->sub = sub; @@ -988,6 +998,16 @@ static void subscribe_buddy_presence(unsigned index) return; } + /* If account is locked to specific transport, then lock dialog + * to this transport too. + */ + if (acc->cfg.transport_id != PJSUA_INVALID_ID) { + pjsip_tpselector tp_sel; + + pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel); + pjsip_dlg_set_transport(dlg, &tp_sel); + } + /* Set route-set */ if (!pj_list_empty(&acc->route_set)) { pjsip_dlg_set_route_set(dlg, &acc->route_set); |