From f714655a4e13f6b0d57d0a9a6a5b227f6edc753d Mon Sep 17 00:00:00 2001 From: Daniel-Constantin Mierla Date: Thu, 9 Mar 2017 11:17:35 +0100 Subject: [PATCH] topos: reworked dialog update in order to refresh contact values - related to GH #1005 (cherry picked from commit 639013a14d46790dd5605f58f683317eb6b9f3f4) --- src/modules/topos/api.h | 3 +- src/modules/topos/tps_msg.c | 100 +++++++++++++++++--------------- src/modules/topos/tps_storage.c | 42 +++++++++----- src/modules/topos/tps_storage.h | 7 ++- 4 files changed, 90 insertions(+), 62 deletions(-) diff --git a/src/modules/topos/api.h b/src/modules/topos/api.h index ab3667243de..baf5cd61c9f 100644 --- a/src/modules/topos/api.h +++ b/src/modules/topos/api.h @@ -38,7 +38,8 @@ typedef int (*tps_insert_branch_f)(tps_data_t *td); typedef int (*tps_clean_branches_f)(void); typedef int (*tps_load_branch_f)(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); typedef int (*tps_load_dialog_f)(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); -typedef int (*tps_update_dialog_f)(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); +typedef int (*tps_update_dialog_f)(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, + uint32_t mode); typedef int (*tps_end_dialog_f)(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); typedef struct tps_storage_api { diff --git a/src/modules/topos/tps_msg.c b/src/modules/topos/tps_msg.c index aa470e2e01b..f60867de7a8 100644 --- a/src/modules/topos/tps_msg.c +++ b/src/modules/topos/tps_msg.c @@ -258,6 +258,35 @@ int tps_skip_msg(sip_msg_t *msg) return 0; } +/** + * + */ +int tps_dlg_detect_direction(sip_msg_t *msg, tps_data_t *ptsd, + uint32_t *direction) +{ + str ftag = {0, 0}; + /* detect direction - get from-tag */ + if(parse_from_header(msg)<0 || msg->from==NULL) { + LM_ERR("failed getting 'from' header!\n"); + goto error; + } + ftag = get_from(msg)->tag_value; + + if(ptsd->a_tag.len!=ftag.len) { + *direction = TPS_DIR_UPSTREAM; + } else { + if(memcmp(ptsd->a_tag.s, ftag.s, ftag.len)==0) { + *direction = TPS_DIR_DOWNSTREAM; + } else { + *direction = TPS_DIR_UPSTREAM; + } + } + return 0; + +error: + return -1; +} + /** * */ @@ -723,22 +752,10 @@ int tps_request_received(sip_msg_t *msg, int dialog) goto error; } - /* detect direction - get from-tag */ - if(parse_from_header(msg)<0 || msg->from==NULL) { - LM_ERR("failed getting 'from' header!\n"); + /* detect direction - via from-tag */ + if(tps_dlg_detect_direction(msg, &stsd, &direction)<0) { goto error; } - ftag = get_from(msg)->tag_value; - - if(stsd.a_tag.len!=ftag.len) { - direction = TPS_DIR_UPSTREAM; - } else { - if(memcmp(stsd.a_tag.s, ftag.s, ftag.len)==0) { - direction = TPS_DIR_DOWNSTREAM; - } else { - direction = TPS_DIR_UPSTREAM; - } - } mtsd.direction = direction; tps_storage_lock_release(&lkey); @@ -791,7 +808,7 @@ int tps_response_received(sip_msg_t *msg) tps_data_t btsd; str lkey; str ftag; - uint32_t direction; + uint32_t direction = TPS_DIR_DOWNSTREAM; LM_DBG("handling incoming response\n"); @@ -820,27 +837,15 @@ int tps_response_received(sip_msg_t *msg) goto error; } - /* detect direction - get from-tag */ - if(parse_from_header(msg)<0 || msg->from==NULL) { - LM_ERR("failed getting 'from' header!\n"); + /* detect direction - via from-tag */ + if(tps_dlg_detect_direction(msg, &stsd, &direction)<0) { goto error; } - ftag = get_from(msg)->tag_value; - - if(stsd.a_tag.len!=ftag.len) { - direction = TPS_DIR_UPSTREAM; - } else { - if(memcmp(stsd.a_tag.s, ftag.s, ftag.len)==0) { - direction = TPS_DIR_DOWNSTREAM; - } else { - direction = TPS_DIR_UPSTREAM; - } - } mtsd.direction = direction; if(tps_storage_update_branch(msg, &mtsd, &btsd)<0) { goto error; } - if(tps_storage_update_dialog(msg, &mtsd, &stsd)<0) { + if(tps_storage_update_dialog(msg, &mtsd, &stsd, TPS_DBU_RPLATTRS)<0) { goto error; } tps_storage_lock_release(&lkey); @@ -869,7 +874,7 @@ int tps_request_sent(sip_msg_t *msg, int dialog, int local) str lkey; str ftag; str xuuid; - int direction = TPS_DIR_DOWNSTREAM; + uint32_t direction = TPS_DIR_DOWNSTREAM; LM_DBG("handling outgoing request\n"); @@ -908,22 +913,10 @@ int tps_request_sent(sip_msg_t *msg, int dialog, int local) if(tps_storage_load_dialog(msg, &mtsd, &stsd)==0) { ptsd = &stsd; } - /* detect direction - get from-tag */ - if(parse_from_header(msg)<0 || msg->from==NULL) { - LM_ERR("failed getting 'from' header!\n"); + /* detect direction - via from-tag */ + if(tps_dlg_detect_direction(msg, &stsd, &direction)<0) { goto error; } - ftag = get_from(msg)->tag_value; - - if(stsd.a_tag.len!=ftag.len) { - direction = TPS_DIR_UPSTREAM; - } else { - if(memcmp(stsd.a_tag.s, ftag.s, ftag.len)==0) { - direction = TPS_DIR_DOWNSTREAM; - } else { - direction = TPS_DIR_UPSTREAM; - } - } mtsd.direction = direction; } @@ -955,6 +948,9 @@ int tps_request_sent(sip_msg_t *msg, int dialog, int local) if(dialog!=0) { tps_storage_end_dialog(msg, &mtsd, ptsd); } + if(tps_storage_update_dialog(msg, &mtsd, &stsd, TPS_DBU_CONTACT)<0) { + goto error; + } done: tps_storage_lock_release(&lkey); @@ -974,7 +970,7 @@ int tps_response_sent(sip_msg_t *msg) tps_data_t stsd; tps_data_t btsd; str lkey; - int direction = TPS_DIR_UPSTREAM; + uint32_t direction = TPS_DIR_UPSTREAM; str xvbranch = {0, 0}; LM_DBG("handling outgoing response\n"); @@ -1007,13 +1003,19 @@ int tps_response_sent(sip_msg_t *msg) if(tps_storage_load_branch(msg, &mtsd, &btsd)<0) { goto error; } - LM_DBG("loaded dialog a_uuid [%.*s]\n", + LM_DBG("loaded branch a_uuid [%.*s]\n", btsd.a_uuid.len, ZSW(btsd.a_uuid.s)); if(tps_storage_load_dialog(msg, &btsd, &stsd)<0) { goto error; } tps_storage_lock_release(&lkey); + /* detect direction - via from-tag */ + if(tps_dlg_detect_direction(msg, &stsd, &direction)<0) { + goto error1; + } + mtsd.direction = direction; + tps_remove_headers(msg, HDR_RECORDROUTE_T); tps_remove_headers(msg, HDR_CONTACT_T); @@ -1024,9 +1026,13 @@ int tps_response_sent(sip_msg_t *msg) } tps_reappend_rr(msg, &btsd, &btsd.x_rr); + if(tps_storage_update_dialog(msg, &mtsd, &stsd, TPS_DBU_CONTACT)<0) { + goto error1; + } return 0; error: tps_storage_lock_release(&lkey); +error1: return -1; } diff --git a/src/modules/topos/tps_storage.c b/src/modules/topos/tps_storage.c index 1d815ae2fd8..6817d5f89e6 100644 --- a/src/modules/topos/tps_storage.c +++ b/src/modules/topos/tps_storage.c @@ -65,7 +65,8 @@ int tps_db_insert_branch(tps_data_t *td); int tps_db_clean_branches(void); int tps_db_load_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); int tps_db_load_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); -int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); +int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, + uint32_t mode); int tps_db_end_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); /** @@ -1038,10 +1039,21 @@ int tps_storage_update_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) return 0; } +#define TPS_DB_ADD_STRV(dcol, dval, cnr, cname, cval) \ + do { \ + if(cval.len>0) { \ + dcol[cnr] = &cname; \ + dval[cnr].type = DB1_STR; \ + dval[cnr].val.str_val = TPS_STRZ(cval); \ + cnr++; \ + } \ + } while(0) + /** * */ -int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) +int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, + uint32_t mode) { db_key_t db_keys[4]; db_op_t db_ops[4]; @@ -1075,12 +1087,14 @@ int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) } nr_keys++; - db_ucols[nr_ucols] = &td_col_b_contact; - db_uvals[nr_ucols].type = DB1_STR; - db_uvals[nr_ucols].val.str_val = TPS_STRZ(md->b_contact); - nr_ucols++; + if(mode & TPS_DBU_CONTACT) { + TPS_DB_ADD_STRV(db_ucols, db_uvals, nr_ucols, + td_col_a_contact, md->a_contact); + TPS_DB_ADD_STRV(db_ucols, db_uvals, nr_ucols, + td_col_b_contact, md->b_contact); + } - if(msg->first_line.type==SIP_REPLY) { + if((mode & TPS_DBU_RPLATTRS) && msg->first_line.type==SIP_REPLY) { if(sd->b_tag.len<=0 && msg->first_line.u.reply.statuscode>=200 && msg->first_line.u.reply.statuscode<300) { @@ -1092,10 +1106,8 @@ int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) nr_ucols++; } - db_ucols[nr_ucols] = &td_col_b_tag; - db_uvals[nr_ucols].type = DB1_STR; - db_uvals[nr_ucols].val.str_val = TPS_STRZ(md->b_tag); - nr_ucols++; + TPS_DB_ADD_STRV(db_ucols, db_uvals, nr_ucols, + td_col_b_tag, md->b_tag); db_ucols[nr_ucols] = &td_col_iflags; db_uvals[nr_ucols].type = DB1_INT; @@ -1103,6 +1115,9 @@ int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) nr_ucols++; } } + if(nr_ucols==0) { + return 0; + } if (_tpsdbf.use_table(_tps_db_handle, &td_table_name) < 0) { LM_ERR("failed to perform use table\n"); return -1; @@ -1120,7 +1135,8 @@ int tps_db_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) /** * */ -int tps_storage_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) +int tps_storage_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, + uint32_t mode) { int ret; @@ -1138,7 +1154,7 @@ int tps_storage_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd) ret = tps_storage_link_msg(msg, md, md->direction); if(ret<0) return -1; - return _tps_storage_api.update_dialog(msg, md, sd); + return _tps_storage_api.update_dialog(msg, md, sd, mode); } /** diff --git a/src/modules/topos/tps_storage.h b/src/modules/topos/tps_storage.h index 18976cf5910..65657284583 100644 --- a/src/modules/topos/tps_storage.h +++ b/src/modules/topos/tps_storage.h @@ -37,6 +37,10 @@ #define TPS_IFLAG_INIT 1 #define TPS_IFLAG_DLGON 2 +#define TPS_DBU_CONTACT (1<<0) +#define TPS_DBU_RPLATTRS (1<<1) +#define TPS_DBU_ALL (0xffffffff) + #define TPS_DATA_SIZE 8192 typedef struct tps_data { char cbuf[TPS_DATA_SIZE]; @@ -87,7 +91,8 @@ int tps_storage_record(sip_msg_t *msg, tps_data_t *td, int dialog); int tps_storage_load_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); int tps_storage_update_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); int tps_storage_load_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); -int tps_storage_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); +int tps_storage_update_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, + uint32_t mode); int tps_storage_end_dialog(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd); int tps_storage_lock_set_init(void);