Fixed account's route set update when modifying account (#3825)

This commit is contained in:
sauwming 2024-01-16 10:12:09 +08:00 committed by GitHub
parent b6cc71ad19
commit 98d51a0e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 65 deletions

View File

@ -170,6 +170,27 @@ PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,
pj_list_type *nodes);
/**
* Insert a list to another list before the specified element position.
*
* @param pos The element to which the node will be inserted before.
* @param lst The list to be inserted.
*/
PJ_IDECL(void) pj_list_insert_list_before(pj_list_type *pos,
pj_list_type *lst);
/**
* Insert a list to another list after the specified element position.
*
* @param pos The element in the list which will precede the inserted
* list.
* @param lst The list to be inserted.
*/
PJ_IDECL(void) pj_list_insert_list_after(pj_list_type *pos,
pj_list_type *lst);
/**
* Remove elements from the source list, and insert them to the destination
* list. The elements of the source list will occupy the

View File

@ -54,6 +54,23 @@ PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)
pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);
}
PJ_IDEF(void) pj_list_insert_list_after(pj_list_type *pos, pj_list_type *lst)
{
if (!pj_list_empty(lst)) {
pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;
pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;
pj_link_node(pos, (pj_list *) ((pj_list*)lst)->next);
pj_link_node(lst_last, pos_next);
pj_list_init(lst);
}
}
PJ_IDEF(void) pj_list_insert_list_before(pj_list_type *pos, pj_list_type *lst)
{
pj_list_insert_list_after(((pj_list*)pos)->prev, lst);
}
PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)
{
if (!pj_list_empty(lst2)) {

View File

@ -834,8 +834,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
pjsip_name_addr *id_name_addr = NULL;
pjsip_sip_uri *id_sip_uri = NULL;
pjsip_sip_uri *reg_sip_uri = NULL;
pj_uint32_t local_route_crc, global_route_crc;
pjsip_route_hdr global_route;
pj_uint32_t local_route_crc;
pjsip_route_hdr local_route;
pj_str_t acc_proxy[PJSUA_ACC_MAX_PROXIES];
pj_bool_t update_reg = PJ_FALSE;
@ -887,6 +886,7 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
/* Registrar URI */
if (pj_strcmp(&acc->cfg.reg_uri, &cfg->reg_uri) && cfg->reg_uri.slen) {
pjsip_uri *reg_uri;
unsigned rcnt;
/* Need to parse reg_uri to get the elements: */
reg_uri = pjsip_parse_uri(acc->pool, cfg->reg_uri.ptr,
@ -907,6 +907,23 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
}
reg_sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(reg_uri);
/* Clear route headers from the previous registrar. */
rcnt = (unsigned)pj_list_size(&acc->route_set);
if (rcnt != pjsua_var.ua_cfg.outbound_proxy_cnt + acc->cfg.proxy_cnt) {
pjsip_route_hdr *hr;
unsigned i;
for (i=pjsua_var.ua_cfg.outbound_proxy_cnt + acc->cfg.proxy_cnt,
hr=acc->route_set.prev;
i<rcnt;
++i)
{
pjsip_route_hdr *prev = hr->prev;
pj_list_erase(hr);
hr = prev;
}
}
}
/* REGISTER header list */
@ -918,22 +935,6 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
/* SUBSCRIBE header list */
update_hdr_list(acc->pool, &acc->cfg.sub_hdr_list, &cfg->sub_hdr_list);
/* Global outbound proxy */
global_route_crc = calc_proxy_crc(pjsua_var.ua_cfg.outbound_proxy,
pjsua_var.ua_cfg.outbound_proxy_cnt);
if (global_route_crc != acc->global_route_crc) {
pjsip_route_hdr *r;
/* Copy from global outbound proxies */
pj_list_init(&global_route);
r = pjsua_var.outbound_proxy.next;
while (r != &pjsua_var.outbound_proxy) {
pj_list_push_back(&global_route,
pjsip_hdr_shallow_clone(acc->pool, r));
r = r->next;
}
}
/* Account proxy */
local_route_crc = calc_proxy_crc(cfg->proxy, cfg->proxy_cnt);
if (local_route_crc != acc->local_route_crc) {
@ -966,6 +967,33 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
local_route_crc = calc_proxy_crc(acc_proxy, cfg->proxy_cnt);
}
if (local_route_crc != acc->local_route_crc) {
unsigned i;
pjsip_route_hdr *r = &acc->route_set;
/* Remove the current account proxies from the route set */
for (i = 0; i < pjsua_var.ua_cfg.outbound_proxy_cnt; i++)
r = r->next;
for (i = 0; i < acc->cfg.proxy_cnt; ++i) {
pjsip_route_hdr *r_ = r->next;
pj_list_erase(r_);
}
/* Insert new proxy setting to the route set */
pj_list_insert_list_after(r, &local_route);
/* Update the proxy setting */
acc->cfg.proxy_cnt = cfg->proxy_cnt;
for (i = 0; i < cfg->proxy_cnt; ++i)
acc->cfg.proxy[i] = acc_proxy[i];
/* Update local route CRC */
acc->local_route_crc = local_route_crc;
update_reg = PJ_TRUE;
unreg_first = PJ_TRUE;
}
/* == Apply the new config == */
@ -1160,53 +1188,6 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
unreg_first = PJ_TRUE;
}
/* Global outbound proxy */
if (global_route_crc != acc->global_route_crc) {
unsigned i;
pj_size_t rcnt;
/* Remove the outbound proxies from the route set */
rcnt = pj_list_size(&acc->route_set);
for (i=0; i < rcnt - acc->cfg.proxy_cnt; ++i) {
pjsip_route_hdr *r = acc->route_set.next;
pj_list_erase(r);
}
/* Insert the outbound proxies to the beginning of route set */
pj_list_merge_first(&acc->route_set, &global_route);
/* Update global route CRC */
acc->global_route_crc = global_route_crc;
update_reg = PJ_TRUE;
unreg_first = PJ_TRUE;
}
/* Account proxy */
if (local_route_crc != acc->local_route_crc) {
unsigned i;
/* Remove the current account proxies from the route set */
for (i=0; i < acc->cfg.proxy_cnt; ++i) {
pjsip_route_hdr *r = acc->route_set.prev;
pj_list_erase(r);
}
/* Insert new proxy setting to the route set */
pj_list_merge_last(&acc->route_set, &local_route);
/* Update the proxy setting */
acc->cfg.proxy_cnt = cfg->proxy_cnt;
for (i = 0; i < cfg->proxy_cnt; ++i)
acc->cfg.proxy[i] = acc_proxy[i];
/* Update local route CRC */
acc->local_route_crc = local_route_crc;
update_reg = PJ_TRUE;
unreg_first = PJ_TRUE;
}
/* Credential info */
{
unsigned i;