diff --git a/src/modules/ims_dialog/dlg_cb.c b/src/modules/ims_dialog/dlg_cb.c index 47687120096..070fce337f0 100644 --- a/src/modules/ims_dialog/dlg_cb.c +++ b/src/modules/ims_dialog/dlg_cb.c @@ -36,26 +36,25 @@ #include "dlg_cb.h" -static struct dlg_head_cbl* create_cbs = 0; +static struct dlg_head_cbl *create_cbs = 0; -static struct dlg_head_cbl* load_cbs = 0; +static struct dlg_head_cbl *load_cbs = 0; static struct dlg_cb_params params = {NULL, NULL, DLG_DIR_NONE, NULL, NULL}; -#define POINTER_CLOSED_MARKER ((void *)(-1)) +#define POINTER_CLOSED_MARKER ((void *)(-1)) static void run_load_callback(struct dlg_callback *cb); - -static struct dlg_head_cbl* init_dlg_callback(void) +static struct dlg_head_cbl *init_dlg_callback(void) { struct dlg_head_cbl *new_cbs; - new_cbs = (struct dlg_head_cbl*)shm_malloc(sizeof(struct dlg_head_cbl)); - if (new_cbs==0) { + new_cbs = (struct dlg_head_cbl *)shm_malloc(sizeof(struct dlg_head_cbl)); + if(new_cbs == 0) { LM_ERR("no more shm mem\n"); return 0; } @@ -73,7 +72,7 @@ void destroy_dlg_callbacks_list(struct dlg_callback *cb) while(cb) { cb_t = cb; cb = cb->next; - if (cb_t->callback_param_free && cb_t->param) { + if(cb_t->callback_param_free && cb_t->param) { cb_t->callback_param_free(cb_t->param); cb_t->param = NULL; } @@ -84,15 +83,15 @@ void destroy_dlg_callbacks_list(struct dlg_callback *cb) void destroy_dlg_callbacks(unsigned int types) { - if (types&DLGCB_CREATED) { - if (create_cbs && create_cbs!=POINTER_CLOSED_MARKER) { + if(types & DLGCB_CREATED) { + if(create_cbs && create_cbs != POINTER_CLOSED_MARKER) { destroy_dlg_callbacks_list(create_cbs->first); shm_free(create_cbs); create_cbs = POINTER_CLOSED_MARKER; } } - if (types&DLGCB_LOADED) { - if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) { + if(types & DLGCB_LOADED) { + if(load_cbs && load_cbs != POINTER_CLOSED_MARKER) { destroy_dlg_callbacks_list(load_cbs->first); shm_free(load_cbs); load_cbs = POINTER_CLOSED_MARKER; @@ -102,44 +101,44 @@ void destroy_dlg_callbacks(unsigned int types) int register_dlgcb_nodlg(struct dlg_cell *dlg, int types, dialog_cb f, - void *param, param_free_cb ff ) + void *param, param_free_cb ff) { - if (!dlg) { - LM_ERR("Can't find dialog to register callback\n"); - return -1; - } - - int ret = register_dlgcb(dlg, types, f, param, ff); - unref_dlg(dlg, 1); - - return ret; + if(!dlg) { + LM_ERR("Can't find dialog to register callback\n"); + return -1; + } + + int ret = register_dlgcb(dlg, types, f, param, ff); + unref_dlg(dlg, 1); + + return ret; } -int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, - void *param, param_free_cb ff ) +int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, void *param, + param_free_cb ff) { struct dlg_callback *cb; - if ( types&DLGCB_LOADED ) { - if (types!=DLGCB_LOADED) { + if(types & DLGCB_LOADED) { + if(types != DLGCB_LOADED) { LM_CRIT("DLGCB_LOADED type must be registered alone!\n"); return -1; } - } else if ( types&DLGCB_CREATED ) { - if (types!=DLGCB_CREATED) { + } else if(types & DLGCB_CREATED) { + if(types != DLGCB_CREATED) { LM_CRIT("DLGCB_CREATED type must be registered alone!\n"); return -1; } } else { - if (dlg==0) { + if(dlg == 0) { LM_CRIT("non-DLGCB_CREATED type " - "must be registered to a dialog (dlg missing)!\n"); + "must be registered to a dialog (dlg missing)!\n"); return -1; } } - cb = (struct dlg_callback*)shm_malloc(sizeof(struct dlg_callback)); - if (cb==0) { + cb = (struct dlg_callback *)shm_malloc(sizeof(struct dlg_callback)); + if(cb == 0) { LM_ERR("no more shm mem\n"); return -1; } @@ -149,14 +148,14 @@ int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, cb->param = param; cb->callback_param_free = ff; - if ( types==DLGCB_CREATED ) { - if (load_cbs==POINTER_CLOSED_MARKER) { + if(types == DLGCB_CREATED) { + if(load_cbs == POINTER_CLOSED_MARKER) { LM_CRIT("DLGCB_CREATED type registered after shutdown!?!\n"); goto error; } - if (create_cbs==0) { + if(create_cbs == 0) { /* not initialized yet */ - if ( (create_cbs=init_dlg_callback())==NULL ) { + if((create_cbs = init_dlg_callback()) == NULL) { LM_ERR("no more shm mem\n"); goto error; } @@ -164,16 +163,16 @@ int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, cb->next = create_cbs->first; create_cbs->first = cb; create_cbs->types |= types; - } else if (types==DLGCB_LOADED) { - if (load_cbs==POINTER_CLOSED_MARKER) { + } else if(types == DLGCB_LOADED) { + if(load_cbs == POINTER_CLOSED_MARKER) { /* run the callback on the spot */ run_load_callback(cb); destroy_dlg_callbacks_list(cb); return 0; } - if (load_cbs==0) { + if(load_cbs == 0) { /* not initialized yet */ - if ( (load_cbs=init_dlg_callback())==NULL ) { + if((load_cbs = init_dlg_callback()) == NULL) { LM_ERR("no more shm mem\n"); goto error; } @@ -204,22 +203,22 @@ static void run_load_callback(struct dlg_callback *cb) params.direction = DLG_DIR_NONE; params.param = &cb->param; - for( i=0 ; isize ; i++ ) { - for( dlg=d_table->entries[i].first ; dlg ; dlg=dlg->next ) - cb->callback( dlg, DLGCB_LOADED, ¶ms ); + for(i = 0; i < d_table->size; i++) { + for(dlg = d_table->entries[i].first; dlg; dlg = dlg->next) + cb->callback(dlg, DLGCB_LOADED, ¶ms); } return; } -void run_load_callbacks( void ) +void run_load_callbacks(void) { struct dlg_callback *cb; - if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) { - for ( cb=load_cbs->first; cb; cb=cb->next ) - run_load_callback( cb ); + if(load_cbs && load_cbs != POINTER_CLOSED_MARKER) { + for(cb = load_cbs->first; cb; cb = cb->next) + run_load_callback(cb); } return; @@ -229,9 +228,10 @@ void run_load_callbacks( void ) void run_create_callbacks(struct dlg_cell *dlg, struct sip_msg *msg) { struct dlg_callback *cb; - LM_DBG("Running DLG_CREATED callbacks\n"); + LM_DBG("Running DLG_CREATED callbacks\n"); - if (create_cbs==NULL || create_cbs==POINTER_CLOSED_MARKER || create_cbs->first==NULL) + if(create_cbs == NULL || create_cbs == POINTER_CLOSED_MARKER + || create_cbs->first == NULL) return; params.req = msg; @@ -242,20 +242,17 @@ void run_create_callbacks(struct dlg_cell *dlg, struct sip_msg *msg) params.param = NULL; params.dlg_data = NULL; - for ( cb=create_cbs->first; cb; cb=cb->next) { - LM_DBG("dialog=%p\n",dlg); + for(cb = create_cbs->first; cb; cb = cb->next) { + LM_DBG("dialog=%p\n", dlg); params.param = &cb->param; - cb->callback( dlg, DLGCB_CREATED, ¶ms ); + cb->callback(dlg, DLGCB_CREATED, ¶ms); } return; } -void run_dlg_callbacks( int type , - struct dlg_cell *dlg, - struct sip_msg *req, - struct sip_msg *rpl, - unsigned int dir, void *dlg_data) +void run_dlg_callbacks(int type, struct dlg_cell *dlg, struct sip_msg *req, + struct sip_msg *rpl, unsigned int dir, void *dlg_data) { struct dlg_callback *cb; @@ -264,14 +261,14 @@ void run_dlg_callbacks( int type , params.direction = dir; params.dlg_data = dlg_data; - if (dlg->cbs.first==0 || ((dlg->cbs.types)&type)==0 ) + if(dlg->cbs.first == 0 || ((dlg->cbs.types) & type) == 0) return; - for ( cb=dlg->cbs.first; cb; cb=cb->next) { - if ( (cb->types)&type ) { + for(cb = dlg->cbs.first; cb; cb = cb->next) { + if((cb->types) & type) { LM_DBG("dialog=%p, type=%d\n", dlg, type); params.param = &cb->param; - cb->callback( dlg, type, ¶ms ); + cb->callback(dlg, type, ¶ms); } } return; diff --git a/src/modules/ims_dialog/dlg_cb.h b/src/modules/ims_dialog/dlg_cb.h index 13d76d5a749..fa53ed7cdbf 100644 --- a/src/modules/ims_dialog/dlg_cb.h +++ b/src/modules/ims_dialog/dlg_cb.h @@ -34,65 +34,69 @@ struct dlg_cell; -struct dlg_cb_params { - struct sip_msg* req; /* sip request msg related to the callback event */ - struct sip_msg* rpl; /* sip reply msg related to the callback event */ - unsigned int direction; /* direction of the sip msg */ - void *dlg_data; /* generic paramter, specific to callback */ - void **param; /* parameter passed at callback registration*/ +struct dlg_cb_params +{ + struct sip_msg *req; /* sip request msg related to the callback event */ + struct sip_msg *rpl; /* sip reply msg related to the callback event */ + unsigned int direction; /* direction of the sip msg */ + void *dlg_data; /* generic paramter, specific to callback */ + void **param; /* parameter passed at callback registration*/ }; /* callback function prototype */ -typedef void (dialog_cb) (struct dlg_cell* dlg, int type, - struct dlg_cb_params * params); +typedef void(dialog_cb)( + struct dlg_cell *dlg, int type, struct dlg_cb_params *params); /* function to free the callback param */ -typedef void (param_free_cb) (void *param); +typedef void(param_free_cb)(void *param); /* register callback function prototype */ -typedef int (*ims_register_dlgcb_f)(struct dlg_cell* dlg, int cb_types, +typedef int (*ims_register_dlgcb_f)(struct dlg_cell *dlg, int cb_types, dialog_cb f, void *param, param_free_cb ff); -typedef int (*ims_register_dlgcb_nodlg_f)(struct dlg_cell* dlg, int cb_types, dialog_cb f, void *param, param_free_cb ff); +typedef int (*ims_register_dlgcb_nodlg_f)(struct dlg_cell *dlg, int cb_types, + dialog_cb f, void *param, param_free_cb ff); /* method to set a variable within a dialog */ //typedef int (*set_dlg_variable_f)( struct dlg_cell* dlg, // str* key, // str* val); -typedef int (*ims_set_dlg_variable_f)( str* callid, str* ftag, str* ttag, - str* key, str* val); +typedef int (*ims_set_dlg_variable_f)( + str *callid, str *ftag, str *ttag, str *key, str *val); /* method to get a variable from a dialog */ //typedef str* (*get_dlg_variable_f)( struct dlg_cell* dlg, // str* key); -typedef str* (*ims_get_dlg_variable_f)( str *callid, str *ftag, str *ttag, - str* key); - -#define DLGCB_LOADED (1<<0) -#define DLGCB_CREATED (1<<1) -#define DLGCB_FAILED (1<<2) -#define DLGCB_CONFIRMED_NA (1<<3) -#define DLGCB_CONFIRMED (1<<4) -#define DLGCB_REQ_WITHIN (1<<5) -#define DLGCB_TERMINATED (1<<6) -#define DLGCB_EXPIRED (1<<7) -#define DLGCB_EARLY (1<<8) -#define DLGCB_RESPONSE_FWDED (1<<9) -#define DLGCB_RESPONSE_WITHIN (1<<10) -#define DLGCB_MI_CONTEXT (1<<11) -#define DLGCB_RPC_CONTEXT (1<<12) -#define DLGCB_DESTROY (1<<13) -#define DLGCB_SPIRALED (1<<14) -#define DLGCB_TERMINATED_CONFIRMED (1<<14) - -struct dlg_callback { +typedef str *(*ims_get_dlg_variable_f)( + str *callid, str *ftag, str *ttag, str *key); + +#define DLGCB_LOADED (1 << 0) +#define DLGCB_CREATED (1 << 1) +#define DLGCB_FAILED (1 << 2) +#define DLGCB_CONFIRMED_NA (1 << 3) +#define DLGCB_CONFIRMED (1 << 4) +#define DLGCB_REQ_WITHIN (1 << 5) +#define DLGCB_TERMINATED (1 << 6) +#define DLGCB_EXPIRED (1 << 7) +#define DLGCB_EARLY (1 << 8) +#define DLGCB_RESPONSE_FWDED (1 << 9) +#define DLGCB_RESPONSE_WITHIN (1 << 10) +#define DLGCB_MI_CONTEXT (1 << 11) +#define DLGCB_RPC_CONTEXT (1 << 12) +#define DLGCB_DESTROY (1 << 13) +#define DLGCB_SPIRALED (1 << 14) +#define DLGCB_TERMINATED_CONFIRMED (1 << 14) + +struct dlg_callback +{ int types; - dialog_cb* callback; + dialog_cb *callback; void *param; - param_free_cb* callback_param_free; - struct dlg_callback* next; + param_free_cb *callback_param_free; + struct dlg_callback *next; }; -struct dlg_head_cbl { +struct dlg_head_cbl +{ struct dlg_callback *first; int types; }; @@ -102,19 +106,17 @@ void destroy_dlg_callbacks(unsigned int type); void destroy_dlg_callbacks_list(struct dlg_callback *cb); -int register_dlgcb_nodlg(struct dlg_cell* dlg, int types, dialog_cb f, void *param, param_free_cb ff); -int register_dlgcb( struct dlg_cell* dlg, int types, dialog_cb f, void *param, param_free_cb ff); +int register_dlgcb_nodlg(struct dlg_cell *dlg, int types, dialog_cb f, + void *param, param_free_cb ff); +int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, void *param, + param_free_cb ff); void run_create_callbacks(struct dlg_cell *dlg, struct sip_msg *msg); -void run_dlg_callbacks( int type , - struct dlg_cell *dlg, - struct sip_msg *req, - struct sip_msg *rpl, - unsigned int dir, - void *dlg_data); +void run_dlg_callbacks(int type, struct dlg_cell *dlg, struct sip_msg *req, + struct sip_msg *rpl, unsigned int dir, void *dlg_data); -void run_load_callbacks( void ); +void run_load_callbacks(void); /*! @@ -126,15 +128,15 @@ static inline struct sip_msg *dlg_get_valid_msg(struct dlg_cb_params *cb_params) { struct sip_msg *msg; - if (cb_params == NULL) { + if(cb_params == NULL) { LM_ERR("no dialog parameters given\n"); return NULL; } msg = cb_params->req; - if (msg == NULL) { + if(msg == NULL) { msg = cb_params->rpl; - if (msg == NULL || msg == FAKED_REPLY) { + if(msg == NULL || msg == FAKED_REPLY) { return NULL; } } diff --git a/src/modules/ims_dialog/dlg_db_handler.c b/src/modules/ims_dialog/dlg_db_handler.c index 52a325bfdca..70a4247a107 100644 --- a/src/modules/ims_dialog/dlg_db_handler.c +++ b/src/modules/ims_dialog/dlg_db_handler.c @@ -44,36 +44,37 @@ #include "dlg_db_handler.h" #include "dlg_ng_stats.h" -str id_column = str_init(ID_COL); // 0 -str h_entry_column = str_init(HASH_ENTRY_COL); // 1 -str h_id_column = str_init(HASH_ID_COL); // 2 -str did_column = str_init(DID_COL); // 3 -str call_id = str_init(CALL_ID_COL); // 4 -str from_uri_column = str_init(FROM_URI_COL); // 5 -str from_tag_column = str_init(FROM_TAG_COL); // 6 -str caller_original_cseq_column = str_init(CALLER_ORIGINAL_CSEQ_COL); // 7 -str req_uri_column = str_init(REQ_URI_COL); // 8 -str caller_route_set_column = str_init(CALLER_ROUTESET_COL);// 9 -str caller_contact_column = str_init(CALLER_CONTACT_COL); // 10 -str caller_sock_column = str_init(CALLER_SOCK); // 11 -str timeout_column = str_init(TIMEOUT_COL); // 12 -str state_column = str_init(STATE_COL); // 13 -str start_time_column = str_init(START_TIME_COL); // 14 -str sflags_column = str_init(SFLAGS_COL); // 15 -str to_route_name_column = str_init(TOROUTE_NAME_COL); // 16 -str to_route_index_column = str_init(TOROUTE_INDEX_COL); // 17 +str id_column = str_init(ID_COL); // 0 +str h_entry_column = str_init(HASH_ENTRY_COL); // 1 +str h_id_column = str_init(HASH_ID_COL); // 2 +str did_column = str_init(DID_COL); // 3 +str call_id = str_init(CALL_ID_COL); // 4 +str from_uri_column = str_init(FROM_URI_COL); // 5 +str from_tag_column = str_init(FROM_TAG_COL); // 6 +str caller_original_cseq_column = str_init(CALLER_ORIGINAL_CSEQ_COL); // 7 +str req_uri_column = str_init(REQ_URI_COL); // 8 +str caller_route_set_column = str_init(CALLER_ROUTESET_COL); // 9 +str caller_contact_column = str_init(CALLER_CONTACT_COL); // 10 +str caller_sock_column = str_init(CALLER_SOCK); // 11 +str timeout_column = str_init(TIMEOUT_COL); // 12 +str state_column = str_init(STATE_COL); // 13 +str start_time_column = str_init(START_TIME_COL); // 14 +str sflags_column = str_init(SFLAGS_COL); // 15 +str to_route_name_column = str_init(TOROUTE_NAME_COL); // 16 +str to_route_index_column = str_init(TOROUTE_INDEX_COL); // 17 // dialog_out exclusive columns -str to_uri_column = str_init(TO_URI_COL); -str to_tag_column = str_init(TO_TAG_COL); -str caller_cseq_column = str_init(CALLER_CSEQ_COL); -str callee_cseq_column = str_init(CALLEE_CSEQ_COL); -str callee_contact_column = str_init(CALLEE_CONTACT_COL); -str callee_routeset_column = str_init(CALLEE_ROUTESET_COL); -str callee_sock_column = str_init(CALLEE_SOCK); - -typedef enum dialog_in_field_idx { - DLGI_ID_COL_IDX = 0, +str to_uri_column = str_init(TO_URI_COL); +str to_tag_column = str_init(TO_TAG_COL); +str caller_cseq_column = str_init(CALLER_CSEQ_COL); +str callee_cseq_column = str_init(CALLEE_CSEQ_COL); +str callee_contact_column = str_init(CALLEE_CONTACT_COL); +str callee_routeset_column = str_init(CALLEE_ROUTESET_COL); +str callee_sock_column = str_init(CALLEE_SOCK); + +typedef enum dialog_in_field_idx +{ + DLGI_ID_COL_IDX = 0, DLGI_HASH_ENTRY_COL_IDX, DLGI_HASH_ID_COL_IDX, DLGI_DID_COL_IDX, @@ -93,8 +94,9 @@ typedef enum dialog_in_field_idx { DLGI_TOROUTE_INDEX_COL_IDX } dialog_in_field_idx_t; -typedef enum dialog_out_field_idx { - DLGO_ID_COL_IDX = 0, +typedef enum dialog_out_field_idx +{ + DLGO_ID_COL_IDX = 0, DLGO_HASH_ENTRY_COL_IDX, DLGO_HASH_ID_COL_IDX, DLGO_DID_COL_IDX, @@ -108,113 +110,119 @@ typedef enum dialog_out_field_idx { } dialog_out_field_idx_t; -str dialog_in_table_name = str_init(DIALOG_IN_TABLE_NAME); -str dialog_out_table_name = str_init(DIALOG_OUT_TABLE_NAME); +str dialog_in_table_name = str_init(DIALOG_IN_TABLE_NAME); +str dialog_out_table_name = str_init(DIALOG_OUT_TABLE_NAME); -int dlg_db_mode = DB_MODE_NONE; +int dlg_db_mode = DB_MODE_NONE; -str vars_h_id_column = str_init(VARS_HASH_ID_COL); -str vars_h_entry_column = str_init(VARS_HASH_ENTRY_COL); -str vars_key_column = str_init(VARS_KEY_COL); -str vars_value_column = str_init(VARS_VALUE_COL); -str dialog_vars_table_name = str_init(DIALOG_VARS_TABLE_NAME); +str vars_h_id_column = str_init(VARS_HASH_ID_COL); +str vars_h_entry_column = str_init(VARS_HASH_ENTRY_COL); +str vars_key_column = str_init(VARS_KEY_COL); +str vars_value_column = str_init(VARS_VALUE_COL); +str dialog_vars_table_name = str_init(DIALOG_VARS_TABLE_NAME); -static db1_con_t* dialog_db_handle = 0; /* database connection handle */ +static db1_con_t *dialog_db_handle = 0; /* database connection handle */ static db_func_t dialog_dbf; extern int dlg_enable_stats; extern struct dialog_ng_counters_h dialog_ng_cnts_h; -#define GET_FIELD_IDX(_val, _idx)\ - (_val + _idx) - -#define SET_STR_VALUE(_val, _str)\ - do{\ - VAL_STR((_val)).s = (_str).s;\ - VAL_STR((_val)).len = (_str).len;\ - }while(0); - -#define SET_NULL_FLAG(_vals, _i, _max, _flag)\ - do{\ - for((_i) = 0;(_i)<(_max); (_i)++)\ - VAL_NULL((_vals)+(_i)) = (_flag);\ - }while(0); - -#define SET_PROPER_NULL_FLAG(_str, _vals, _index)\ - do{\ - if( (_str).len == 0)\ - VAL_NULL( (_vals)+(_index) ) = 1;\ - else\ - VAL_NULL( (_vals)+(_index) ) = 0;\ - }while(0); - -#define GET_STR_VALUE(_res, _values, _index, _not_null, _unref)\ - do{\ - if (VAL_NULL((_values)+ (_index))) { \ - if (_not_null) {\ - if (_unref) unref_dlg(dlg,1);\ - goto next_dialog; \ - } else { \ - (_res).s = 0; \ - (_res).len = 0; \ - }\ - } else { \ - (_res).s = VAL_STR((_values)+ (_index)).s;\ - (_res).len = strlen(VAL_STR((_values)+ (_index)).s);\ - } \ - }while(0); - -static int select_dialog_out_by_did(str *did, db1_res_t ** res, int fetch_num_rows); +#define GET_FIELD_IDX(_val, _idx) (_val + _idx) + +#define SET_STR_VALUE(_val, _str) \ + do { \ + VAL_STR((_val)).s = (_str).s; \ + VAL_STR((_val)).len = (_str).len; \ + } while(0); + +#define SET_NULL_FLAG(_vals, _i, _max, _flag) \ + do { \ + for((_i) = 0; (_i) < (_max); (_i)++) \ + VAL_NULL((_vals) + (_i)) = (_flag); \ + } while(0); + +#define SET_PROPER_NULL_FLAG(_str, _vals, _index) \ + do { \ + if((_str).len == 0) \ + VAL_NULL((_vals) + (_index)) = 1; \ + else \ + VAL_NULL((_vals) + (_index)) = 0; \ + } while(0); + +#define GET_STR_VALUE(_res, _values, _index, _not_null, _unref) \ + do { \ + if(VAL_NULL((_values) + (_index))) { \ + if(_not_null) { \ + if(_unref) \ + unref_dlg(dlg, 1); \ + goto next_dialog; \ + } else { \ + (_res).s = 0; \ + (_res).len = 0; \ + } \ + } else { \ + (_res).s = VAL_STR((_values) + (_index)).s; \ + (_res).len = strlen(VAL_STR((_values) + (_index)).s); \ + } \ + } while(0); + +static int select_dialog_out_by_did( + str *did, db1_res_t **res, int fetch_num_rows); static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows); static int load_dialog_vars_from_db(int fetch_num_rows); int dlg_connect_db(const str *db_url) { - if (dialog_db_handle) { + if(dialog_db_handle) { LM_CRIT("BUG - db connection found already open\n"); return -1; } - if ((dialog_db_handle = dialog_dbf.init(db_url)) == 0) + if((dialog_db_handle = dialog_dbf.init(db_url)) == 0) return -1; return 0; } -int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period, int fetch_num_rows) +int init_dlg_db(const str *db_url, int dlg_hash_size, int db_update_period, + int fetch_num_rows) { /* Find a database module */ - if (db_bind_mod(db_url, &dialog_dbf) < 0){ + if(db_bind_mod(db_url, &dialog_dbf) < 0) { LM_ERR("Unable to bind to a database driver\n"); return -1; } - if (dlg_connect_db(db_url)!=0){ + if(dlg_connect_db(db_url) != 0) { LM_ERR("unable to connect to the database\n"); return -1; } - if(db_check_table_version(&dialog_dbf, dialog_db_handle, &dialog_in_table_name, DLG_TABLE_VERSION) < 0) { + if(db_check_table_version(&dialog_dbf, dialog_db_handle, + &dialog_in_table_name, DLG_TABLE_VERSION) + < 0) { DB_TABLE_VERSION_ERROR(dialog_in_table_name); goto dberror; } - if(db_check_table_version(&dialog_dbf, dialog_db_handle, &dialog_vars_table_name, DLG_VARS_TABLE_VERSION) < 0) { + if(db_check_table_version(&dialog_dbf, dialog_db_handle, + &dialog_vars_table_name, DLG_VARS_TABLE_VERSION) + < 0) { DB_TABLE_VERSION_ERROR(dialog_vars_table_name); goto dberror; } - if( (dlg_db_mode==DB_MODE_DELAYED) && - (register_timer( dialog_update_db, 0, db_update_period)<0 )) { + if((dlg_db_mode == DB_MODE_DELAYED) + && (register_timer(dialog_update_db, 0, db_update_period) < 0)) { LM_ERR("failed to register update db\n"); goto dberror; } - if( (load_dialog_info_from_db(dlg_hash_size, fetch_num_rows) ) !=0 ){ + if((load_dialog_info_from_db(dlg_hash_size, fetch_num_rows)) != 0) { LM_ERR("unable to load the dialog data\n"); goto dberror; } - if( (load_dialog_vars_from_db(fetch_num_rows) ) !=0 ){ + if((load_dialog_vars_from_db(fetch_num_rows)) != 0) { LM_ERR("unable to load the dialog data\n"); goto dberror; } @@ -233,7 +241,7 @@ int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period, int void destroy_dlg_db(void) { /* close the DB connection */ - if (dialog_db_handle) { + if(dialog_db_handle) { dialog_dbf.close(dialog_db_handle); dialog_db_handle = 0; } @@ -241,12 +249,12 @@ void destroy_dlg_db(void) static int use_dialog_out_table(void) { - if(!dialog_db_handle){ + if(!dialog_db_handle) { LM_ERR("invalid database handle\n"); return -1; } - if (dialog_dbf.use_table(dialog_db_handle, &dialog_out_table_name) < 0) { + if(dialog_dbf.use_table(dialog_db_handle, &dialog_out_table_name) < 0) { LM_ERR("Error in use_table\n"); return -1; } @@ -256,12 +264,12 @@ static int use_dialog_out_table(void) static int use_dialog_table(void) { - if(!dialog_db_handle){ + if(!dialog_db_handle) { LM_ERR("invalid database handle\n"); return -1; } - if (dialog_dbf.use_table(dialog_db_handle, &dialog_in_table_name) < 0) { + if(dialog_dbf.use_table(dialog_db_handle, &dialog_in_table_name) < 0) { LM_ERR("Error in use_table\n"); return -1; } @@ -271,12 +279,12 @@ static int use_dialog_table(void) static int use_dialog_vars_table(void) { - if(!dialog_db_handle){ + if(!dialog_db_handle) { LM_ERR("invalid database handle\n"); return -1; } - if (dialog_dbf.use_table(dialog_db_handle, &dialog_vars_table_name) < 0) { + if(dialog_dbf.use_table(dialog_db_handle, &dialog_vars_table_name) < 0) { LM_ERR("Error in use_table\n"); return -1; } @@ -284,19 +292,15 @@ static int use_dialog_vars_table(void) return 0; } -static int select_dialog_out_by_did(str *did, db1_res_t ** res, int fetch_num_rows) +static int select_dialog_out_by_did( + str *did, db1_res_t **res, int fetch_num_rows) { - db_key_t query_cols[DIALOG_IN_TABLE_COL_NO] = { - &id_column, &h_entry_column, - &h_id_column, &did_column, - &to_uri_column, &to_tag_column, - &caller_cseq_column, &callee_cseq_column, - &callee_contact_column, &callee_routeset_column, - &callee_sock_column }; - - db_key_t where[1] = { - &did_column - }; + db_key_t query_cols[DIALOG_IN_TABLE_COL_NO] = {&id_column, &h_entry_column, + &h_id_column, &did_column, &to_uri_column, &to_tag_column, + &caller_cseq_column, &callee_cseq_column, &callee_contact_column, + &callee_routeset_column, &callee_sock_column}; + + db_key_t where[1] = {&did_column}; db_val_t values[1]; if(use_dialog_out_table() != 0) { @@ -308,8 +312,10 @@ static int select_dialog_out_by_did(str *did, db1_res_t ** res, int fetch_num_ro SET_STR_VALUE(values, (*did)); - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.query(dialog_db_handle, where, 0, values, query_cols, 1, DIALOG_OUT_TABLE_COL_NO, 0, 0) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.query(dialog_db_handle, where, 0, values, query_cols, 1, + DIALOG_OUT_TABLE_COL_NO, 0, 0) + < 0) { LM_ERR("Error while querying (fetch) database\n"); return -1; } @@ -317,9 +323,10 @@ static int select_dialog_out_by_did(str *did, db1_res_t ** res, int fetch_num_ro LM_ERR("fetching rows failed\n"); return -1; } - } - else { - if(dialog_dbf.query(dialog_db_handle, where, 0, values, query_cols, 1, DIALOG_OUT_TABLE_COL_NO, 0, res) < 0) { + } else { + if(dialog_dbf.query(dialog_db_handle, where, 0, values, query_cols, 1, + DIALOG_OUT_TABLE_COL_NO, 0, res) + < 0) { LM_ERR("Error while querying database\n"); return -1; } @@ -328,27 +335,25 @@ static int select_dialog_out_by_did(str *did, db1_res_t ** res, int fetch_num_ro return 0; } -static int select_entire_dialog_in_table(db1_res_t ** res, int fetch_num_rows) +static int select_entire_dialog_in_table(db1_res_t **res, int fetch_num_rows) { - db_key_t query_cols[DIALOG_IN_TABLE_COL_NO] = { - &id_column, &h_entry_column, - &h_id_column, &did_column, - &call_id, &from_uri_column, - &from_tag_column, &caller_original_cseq_column, - &req_uri_column, &caller_route_set_column, - &caller_contact_column, &caller_sock_column, &timeout_column, - &state_column, &start_time_column, - &sflags_column, - &to_route_name_column, &to_route_index_column }; + db_key_t query_cols[DIALOG_IN_TABLE_COL_NO] = {&id_column, &h_entry_column, + &h_id_column, &did_column, &call_id, &from_uri_column, + &from_tag_column, &caller_original_cseq_column, &req_uri_column, + &caller_route_set_column, &caller_contact_column, + &caller_sock_column, &timeout_column, &state_column, + &start_time_column, &sflags_column, &to_route_name_column, + &to_route_index_column}; if(use_dialog_table() != 0) { return -1; } /* select the whole table and all the columns */ - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, - DIALOG_IN_TABLE_COL_NO, 0, 0) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.query(dialog_db_handle, 0, 0, 0, query_cols, 0, + DIALOG_IN_TABLE_COL_NO, 0, 0) + < 0) { LM_ERR("Error while querying (fetch) database\n"); return -1; } @@ -357,8 +362,9 @@ static int select_entire_dialog_in_table(db1_res_t ** res, int fetch_num_rows) return -1; } } else { - if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, - DIALOG_IN_TABLE_COL_NO, 0, res) < 0) { + if(dialog_dbf.query(dialog_db_handle, 0, 0, 0, query_cols, 0, + DIALOG_IN_TABLE_COL_NO, 0, res) + < 0) { LM_ERR("Error while querying database\n"); return -1; } @@ -367,26 +373,26 @@ static int select_entire_dialog_in_table(db1_res_t ** res, int fetch_num_rows) return 0; } -struct socket_info * create_socket_info(db_val_t * vals, int n){ +struct socket_info *create_socket_info(db_val_t *vals, int n) +{ - struct socket_info * sock; - char* p; + struct socket_info *sock; + char *p; str host; int port, proto; /* socket name */ - p = (VAL_STR(vals+n)).s; + p = (VAL_STR(vals + n)).s; - if (VAL_NULL(vals+n) || p==0 || p[0]==0){ + if(VAL_NULL(vals + n) || p == 0 || p[0] == 0) { sock = 0; } else { - if (parse_phostport( p, &host.s, &host.len, - &port, &proto)!=0) { + if(parse_phostport(p, &host.s, &host.len, &port, &proto) != 0) { LM_ERR("bad socket <%s>\n", p); return 0; } - sock = grep_sock_info( &host, (unsigned short)port, proto); - if (sock==0) { + sock = grep_sock_info(&host, (unsigned short)port, proto); + if(sock == 0) { LM_WARN("non-local socket <%s>...ignoring\n", p); } } @@ -394,15 +400,15 @@ struct socket_info * create_socket_info(db_val_t * vals, int n){ return sock; } -static int load_dialog_out_from_db(struct dlg_cell *dlg, str *did, int fetch_num_rows) +static int load_dialog_out_from_db( + struct dlg_cell *dlg, str *did, int fetch_num_rows) { - db1_res_t * res = NULL; - db_val_t * values; - db_row_t * rows; + db1_res_t *res = NULL; + db_val_t *values; + db_row_t *rows; int i, nr_rows; str to_uri, to_tag, /*caller_cseq,*/ - callee_cseq, callee_contact, - callee_route_set; + callee_cseq, callee_contact, callee_route_set; struct dlg_cell_out *dlg_out; if((nr_rows = select_dialog_out_by_did(did, &res, fetch_num_rows)) < 0) { @@ -415,49 +421,55 @@ static int load_dialog_out_from_db(struct dlg_cell *dlg, str *did, int fetch_num rows = RES_ROWS(res); do { - for(i=0; icallee_bind_addr = create_socket_info(values, DLGO_CALLEE_SOCK_IDX); + dlg_out->callee_bind_addr = + create_socket_info(values, DLGO_CALLEE_SOCK_IDX); update_dlg_out_did(dlg_out, did); link_dlg_out(dlg, dlg_out, 0); - if (dlg_set_leg_info(dlg, &to_tag, &callee_route_set, &callee_contact, &callee_cseq, dlg_out->callee_bind_addr, DLG_CALLEE_LEG) < 0) { + if(dlg_set_leg_info(dlg, &to_tag, &callee_route_set, + &callee_contact, &callee_cseq, dlg_out->callee_bind_addr, + DLG_CALLEE_LEG) + < 0) { LM_ERR("Error setting leg info"); return -1; } - next_dialog: - ; + next_dialog:; } /* any more data to be fetched ?*/ - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) + < 0) { LM_ERR("re-fetching rows failed\n"); return -1; } @@ -465,25 +477,23 @@ static int load_dialog_out_from_db(struct dlg_cell *dlg, str *did, int fetch_num rows = RES_ROWS(res); } else nr_rows = 0; - } - while(nr_rows>0); + } while(nr_rows > 0); return 0; } static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) { - db1_res_t * res; - db_val_t * values; - db_row_t * rows; + db1_res_t *res; + db_val_t *values; + db_row_t *rows; struct dlg_entry *d_entry; int i, nr_rows; - struct dlg_cell *dlg = NULL; - str callid, from_uri, from_tag, req_uri, - caller_cseq, caller_contact, caller_rroute, - toroute_name, did; + struct dlg_cell *dlg = NULL; + str callid, from_uri, from_tag, req_uri, caller_cseq, caller_contact, + caller_rroute, toroute_name, did; unsigned int next_id; - + res = 0; if((nr_rows = select_entire_dialog_in_table(&res, fetch_num_rows)) < 0) goto end; @@ -496,42 +506,46 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) do { /* for every row---dialog */ - for(i=0; i skipping\n", - h_entry_column.len, h_entry_column.s, - h_id_column.len, h_id_column.s); + h_entry_column.len, h_entry_column.s, h_id_column.len, + h_id_column.s); continue; } - if (VAL_NULL(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)) || - VAL_NULL(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX))) { + if(VAL_NULL(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)) + || VAL_NULL(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX))) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", - start_time_column.len, start_time_column.s, - state_column.len, state_column.s); + start_time_column.len, start_time_column.s, + state_column.len, state_column.s); continue; } /*restore the dialog info*/ - GET_STR_VALUE(callid, values, DLGI_CALLID_COL_IDX, 1, 0); - GET_STR_VALUE(from_uri, values, DLGI_FROM_URI_COL_IDX, 1, 0); - GET_STR_VALUE(from_tag, values, DLGI_FROM_TAG_COL_IDX, 1, 0); - GET_STR_VALUE(req_uri, values, DLGI_REQ_URI_COL_IDX, 1, 0); + GET_STR_VALUE(callid, values, DLGI_CALLID_COL_IDX, 1, 0); + GET_STR_VALUE(from_uri, values, DLGI_FROM_URI_COL_IDX, 1, 0); + GET_STR_VALUE(from_tag, values, DLGI_FROM_TAG_COL_IDX, 1, 0); + GET_STR_VALUE(req_uri, values, DLGI_REQ_URI_COL_IDX, 1, 0); - if((dlg=build_new_dlg(&callid, &from_uri, &from_tag, &req_uri))==0) { + if((dlg = build_new_dlg(&callid, &from_uri, &from_tag, &req_uri)) + == 0) { LM_ERR("failed to build new dialog\n"); goto error; } - if(dlg->h_entry != VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX))) { + if(dlg->h_entry + != VAL_INT( + GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX))) { LM_ERR("inconsistent hash data in the dialog database: " - "you may have restarted Kamailio using a different " - "hash_size: please erase %.*s database and restart\n", - dialog_in_table_name.len, dialog_in_table_name.s); + "you may have restarted Kamailio using a different " + "hash_size: please erase %.*s database and restart\n", + dialog_in_table_name.len, dialog_in_table_name.s); shm_free(dlg); goto error; } @@ -539,76 +553,85 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) /*link the dialog*/ link_dlg(dlg, 0, 0); - GET_STR_VALUE(did, values, DLGI_DID_COL_IDX, 1, 0); + GET_STR_VALUE(did, values, DLGI_DID_COL_IDX, 1, 0); update_dlg_did(dlg, &did); dlg->h_id = VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ID_COL_IDX)); next_id = d_table->entries[dlg->h_entry].next_id; - d_table->entries[dlg->h_entry].next_id = (next_id < dlg->h_id) ? (dlg->h_id+1) : next_id; + d_table->entries[dlg->h_entry].next_id = + (next_id < dlg->h_id) ? (dlg->h_id + 1) : next_id; - dlg->start_ts = VAL_INT(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)); - dlg->state = VAL_INT(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX)); + dlg->start_ts = + VAL_INT(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)); + dlg->state = VAL_INT(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX)); - if (dlg->state==DLG_STATE_CONFIRMED) { + if(dlg->state == DLG_STATE_CONFIRMED) { counter_inc(dialog_ng_cnts_h.active); - } - else if (dlg->state==DLG_STATE_EARLY) { + } else if(dlg->state == DLG_STATE_EARLY) { counter_inc(dialog_ng_cnts_h.active); } - dlg->tl.timeout = (unsigned int)(VAL_INT(GET_FIELD_IDX(values, DLGI_TIMEOUT_COL_IDX))); - LM_DBG("db dialog timeout is %u (%u/%u)\n", dlg->tl.timeout, get_ticks(), (unsigned int)time(0)); + dlg->tl.timeout = (unsigned int)(VAL_INT( + GET_FIELD_IDX(values, DLGI_TIMEOUT_COL_IDX))); + LM_DBG("db dialog timeout is %u (%u/%u)\n", dlg->tl.timeout, + get_ticks(), (unsigned int)time(0)); - if (dlg->tl.timeout<=(unsigned int)time(0)) + if(dlg->tl.timeout <= (unsigned int)time(0)) dlg->tl.timeout = 0; else dlg->tl.timeout -= (unsigned int)time(0); dlg->lifetime = dlg->tl.timeout; - GET_STR_VALUE(caller_cseq, values, DLGI_CALLER_CSEQ_COL_IDX , 1, 1); - GET_STR_VALUE(caller_rroute, values, DLGI_CALLER_ROUTESET_COL_IDX, 0, 0); - GET_STR_VALUE(caller_contact, values,DLGI_CALLER_CONTACT_COL_IDX, 1, 1); + GET_STR_VALUE(caller_cseq, values, DLGI_CALLER_CSEQ_COL_IDX, 1, 1); + GET_STR_VALUE( + caller_rroute, values, DLGI_CALLER_ROUTESET_COL_IDX, 0, 0); + GET_STR_VALUE( + caller_contact, values, DLGI_CALLER_CONTACT_COL_IDX, 1, 1); - dlg->caller_bind_addr = create_socket_info(values, DLGI_CALLER_SOCK_IDX); + dlg->caller_bind_addr = + create_socket_info(values, DLGI_CALLER_SOCK_IDX); //dlg->bind_addr[DLG_CALLEE_LEG] = create_socket_info(values, 17); - if ( (dlg_set_leg_info( dlg, &from_tag, &caller_rroute, - &caller_contact, &caller_cseq, dlg->caller_bind_addr, - DLG_CALLER_LEG) != 0) ) { + if((dlg_set_leg_info(dlg, &from_tag, &caller_rroute, + &caller_contact, &caller_cseq, dlg->caller_bind_addr, + DLG_CALLER_LEG) + != 0)) { LM_ERR("dlg_set_leg_info failed\n"); - unref_dlg(dlg,1); + unref_dlg(dlg, 1); continue; } - dlg->sflags = (unsigned int)VAL_INT(GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)); + dlg->sflags = (unsigned int)VAL_INT( + GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)); - GET_STR_VALUE(toroute_name, values, DLGI_TOROUTE_NAME_COL_IDX, 0, 0); + GET_STR_VALUE( + toroute_name, values, DLGI_TOROUTE_NAME_COL_IDX, 0, 0); dlg_set_toroute(dlg, &toroute_name); /*restore the timer values */ - if (0 != insert_dlg_timer( &(dlg->tl), (int)dlg->tl.timeout )) { + if(0 != insert_dlg_timer(&(dlg->tl), (int)dlg->tl.timeout)) { LM_CRIT("Unable to insert dlg %p [%u:%u] " - "with clid '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s); - unref_dlg(dlg,1); + "with clid '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s); + unref_dlg(dlg, 1); continue; } - ref_dlg(dlg,1); + ref_dlg(dlg, 1); LM_DBG("current dialog timeout is %u (%u)\n", dlg->tl.timeout, get_ticks()); dlg->dflags = 0; - next_dialog: - ; + next_dialog:; } /* any more data to be fetched ?*/ - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) + < 0) { LM_ERR("re-fetching rows failed\n"); goto error; } @@ -618,21 +641,20 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) nr_rows = 0; } - } - while (nr_rows>0); + } while(nr_rows > 0); - if (dlg != NULL) { + if(dlg != NULL) { d_entry = &(d_table->entries[dlg->h_entry]); - dlg = d_entry->first; + dlg = d_entry->first; - while (dlg) { + while(dlg) { load_dialog_out_from_db(dlg, &dlg->did, fetch_num_rows); dlg = dlg->next; } } - if (dlg_db_mode==DB_MODE_SHUTDOWN) { - if (dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { + if(dlg_db_mode == DB_MODE_SHUTDOWN) { + if(dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { LM_ERR("failed to clear dialog table\n"); goto error; } @@ -644,25 +666,22 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows) error: dialog_dbf.free_result(dialog_db_handle, res); return -1; - } -static int select_entire_dialog_vars_table(db1_res_t ** res, int fetch_num_rows) +static int select_entire_dialog_vars_table(db1_res_t **res, int fetch_num_rows) { - db_key_t query_cols[DIALOG_VARS_TABLE_COL_NO] = { - &vars_h_entry_column, - &vars_h_id_column, - &vars_key_column, - &vars_value_column }; + db_key_t query_cols[DIALOG_VARS_TABLE_COL_NO] = {&vars_h_entry_column, + &vars_h_id_column, &vars_key_column, &vars_value_column}; - if(use_dialog_vars_table() != 0){ + if(use_dialog_vars_table() != 0) { return -1; } /* select the whole tabel and all the columns */ - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, - DIALOG_VARS_TABLE_COL_NO, 0, 0) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.query(dialog_db_handle, 0, 0, 0, query_cols, 0, + DIALOG_VARS_TABLE_COL_NO, 0, 0) + < 0) { LM_ERR("Error while querying (fetch) database\n"); return -1; } @@ -671,8 +690,9 @@ static int select_entire_dialog_vars_table(db1_res_t ** res, int fetch_num_rows) return -1; } } else { - if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, - DIALOG_VARS_TABLE_COL_NO, 0, res) < 0) { + if(dialog_dbf.query(dialog_db_handle, 0, 0, 0, query_cols, 0, + DIALOG_VARS_TABLE_COL_NO, 0, res) + < 0) { LM_ERR("Error while querying database\n"); return -1; } @@ -683,10 +703,10 @@ static int select_entire_dialog_vars_table(db1_res_t ** res, int fetch_num_rows) static int load_dialog_vars_from_db(int fetch_num_rows) { - db1_res_t * res; - db_val_t * values; - db_row_t * rows; - struct dlg_cell * dlg; + db1_res_t *res; + db_val_t *values; + db_row_t *rows; + struct dlg_cell *dlg; int i, nr_rows; res = 0; @@ -701,45 +721,50 @@ static int load_dialog_vars_from_db(int fetch_num_rows) do { /* for every row---dialog */ - for(i=0; i skipping\n", - vars_h_entry_column.len, vars_h_entry_column.s, - vars_h_id_column.len, vars_h_id_column.s); + vars_h_entry_column.len, vars_h_entry_column.s, + vars_h_id_column.len, vars_h_id_column.s); continue; } - if (VAL_NULL(values+2) || VAL_NULL(values+3)) { + if(VAL_NULL(values + 2) || VAL_NULL(values + 3)) { LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n", - vars_key_column.len, vars_key_column.s, - vars_value_column.len, vars_value_column.s); + vars_key_column.len, vars_key_column.s, + vars_value_column.len, vars_value_column.s); continue; } - if (VAL_INT(values) < d_table->size) { + if(VAL_INT(values) < d_table->size) { dlg = (d_table->entries)[VAL_INT(values)].first; - while (dlg) { - if (dlg->h_id == VAL_INT(values+1)) { - str key = { VAL_STR(values+2).s, strlen(VAL_STRING(values+2)) }; - str value = { VAL_STR(values+3).s, strlen(VAL_STRING(values+3)) }; + while(dlg) { + if(dlg->h_id == VAL_INT(values + 1)) { + str key = {VAL_STR(values + 2).s, + strlen(VAL_STRING(values + 2))}; + str value = {VAL_STR(values + 3).s, + strlen(VAL_STRING(values + 3))}; set_dlg_variable_unsafe(dlg, &key, &value); break; } dlg = dlg->next; - if (!dlg) { - LM_WARN("inconsistent data: the dialog h_entry/h_id does not exist!\n"); + if(!dlg) { + LM_WARN("inconsistent data: the dialog h_entry/h_id " + "does not exist!\n"); } } } else { - LM_WARN("inconsistent data: the h_entry in the DB does not exist!\n"); + LM_WARN("inconsistent data: the h_entry in the DB does not " + "exist!\n"); } } /* any more data to be fetched ?*/ - if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { - if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) < 0) { + if(DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) { + if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) + < 0) { LM_ERR("re-fetching rows failed\n"); goto error; } @@ -749,11 +774,10 @@ static int load_dialog_vars_from_db(int fetch_num_rows) nr_rows = 0; } - } - while (nr_rows>0); + } while(nr_rows > 0); - if (dlg_db_mode==DB_MODE_SHUTDOWN) { - if (dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { + if(dlg_db_mode == DB_MODE_SHUTDOWN) { + if(dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) { LM_ERR("failed to clear dialog variable table\n"); goto error; } @@ -765,25 +789,23 @@ static int load_dialog_vars_from_db(int fetch_num_rows) error: dialog_dbf.free_result(dialog_db_handle, res); return -1; - } /*this is only called from destroy_dlg, where the cell's entry lock is acquired*/ -int remove_dialog_in_from_db(struct dlg_cell * cell) +int remove_dialog_in_from_db(struct dlg_cell *cell) { db_val_t values[2]; - db_key_t match_keys[2] = { &h_entry_column, &h_id_column}; - db_key_t vars_match_keys[2] = { &vars_h_entry_column, &vars_h_id_column}; - struct dlg_cell_out *dlg_out = cell->dlg_entry_out.first; + db_key_t match_keys[2] = {&h_entry_column, &h_id_column}; + db_key_t vars_match_keys[2] = {&vars_h_entry_column, &vars_h_id_column}; + struct dlg_cell_out *dlg_out = cell->dlg_entry_out.first; /*if the dialog hasn 't been yet inserted in the database*/ LM_DBG("trying to remove dialog [%.*s], update_flag is %i\n", - cell->callid.len, cell->callid.s, - cell->dflags); - if (cell->dflags & DLG_FLAG_NEW) + cell->callid.len, cell->callid.s, cell->dflags); + if(cell->dflags & DLG_FLAG_NEW) return 0; - if (use_dialog_table()!=0) + if(use_dialog_table() != 0) return -1; VAL_TYPE(values) = DB1_INT; @@ -792,7 +814,7 @@ int remove_dialog_in_from_db(struct dlg_cell * cell) VAL_NULL(values) = 0; VAL_NULL(values + 1) = 0; - VAL_INT(values) = cell->h_entry; + VAL_INT(values) = cell->h_entry; VAL_INT(values + 1) = cell->h_id; if(dialog_dbf.delete(dialog_db_handle, match_keys, 0, values, 2) < 0) { @@ -800,7 +822,7 @@ int remove_dialog_in_from_db(struct dlg_cell * cell) return -1; } - if (use_dialog_vars_table()!=0) + if(use_dialog_vars_table() != 0) return -1; if(dialog_dbf.delete(dialog_db_handle, vars_match_keys, 0, values, 2) < 0) { @@ -808,73 +830,80 @@ int remove_dialog_in_from_db(struct dlg_cell * cell) return -1; } - if (use_dialog_out_table() !=0 ) + if(use_dialog_out_table() != 0) return -1; while(dlg_out) { - LM_DBG("deleting dlg_out from db with h_entry:h_id [%u:%u]\n", dlg_out->h_entry, dlg_out->h_id); - VAL_INT(values) = dlg_out->h_entry; + LM_DBG("deleting dlg_out from db with h_entry:h_id [%u:%u]\n", + dlg_out->h_entry, dlg_out->h_id); + VAL_INT(values) = dlg_out->h_entry; VAL_INT(values + 1) = dlg_out->h_id; if(dialog_dbf.delete(dialog_db_handle, match_keys, 0, values, 2) < 0) { LM_ERR("failed to delete dlg_out row\n"); return -1; } - dlg_out = dlg_out->next; + dlg_out = dlg_out->next; } - LM_DBG("callid was %.*s\n", cell->callid.len, cell->callid.s ); + LM_DBG("callid was %.*s\n", cell->callid.len, cell->callid.s); return 0; } -int update_dialog_vars_dbinfo(struct dlg_cell * cell, struct dlg_var * var) +int update_dialog_vars_dbinfo(struct dlg_cell *cell, struct dlg_var *var) { db_val_t values[DIALOG_VARS_TABLE_COL_NO]; - db_key_t insert_keys[DIALOG_VARS_TABLE_COL_NO] = { &vars_h_entry_column, - &vars_h_id_column, &vars_key_column, &vars_value_column }; + db_key_t insert_keys[DIALOG_VARS_TABLE_COL_NO] = {&vars_h_entry_column, + &vars_h_id_column, &vars_key_column, &vars_value_column}; - if(use_dialog_vars_table()!=0) + if(use_dialog_vars_table() != 0) return -1; - VAL_TYPE(values) = VAL_TYPE(values+1) = DB1_INT; - VAL_TYPE(values+2) = VAL_TYPE(values+3) = DB1_STR; - VAL_NULL(values) = VAL_NULL(values+1) = VAL_NULL(values+2) = VAL_NULL(values+3) = 0; - SET_STR_VALUE(values+2, var->key); + VAL_TYPE(values) = VAL_TYPE(values + 1) = DB1_INT; + VAL_TYPE(values + 2) = VAL_TYPE(values + 3) = DB1_STR; + VAL_NULL(values) = VAL_NULL(values + 1) = VAL_NULL(values + 2) = + VAL_NULL(values + 3) = 0; + SET_STR_VALUE(values + 2, var->key); + + VAL_INT(values) = cell->h_entry; + VAL_INT(values + 1) = cell->h_id; - VAL_INT(values) = cell->h_entry; - VAL_INT(values+1) = cell->h_id; - if((var->vflags & DLG_FLAG_DEL) != 0) { /* delete the current variable */ - db_key_t vars_match_keys[3] = { &vars_h_entry_column, &vars_h_id_column, &vars_key_column}; + db_key_t vars_match_keys[3] = { + &vars_h_entry_column, &vars_h_id_column, &vars_key_column}; - if (use_dialog_vars_table()!=0) + if(use_dialog_vars_table() != 0) return -1; - if(dialog_dbf.delete(dialog_db_handle, vars_match_keys, 0, values, 3) < 0) { + if(dialog_dbf.delete(dialog_db_handle, vars_match_keys, 0, values, 3) + < 0) { LM_ERR("failed to delete database information\n"); return -1; } } else if((var->vflags & DLG_FLAG_NEW) != 0) { /* save all the current dialogs information*/ - SET_STR_VALUE(values+3, var->value); + SET_STR_VALUE(values + 3, var->value); - LM_DBG("Inserting into dlg vars table for [%u:%u]\n", cell->h_entry, cell->h_id); - if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, - DIALOG_VARS_TABLE_COL_NO)) !=0){ + LM_DBG("Inserting into dlg vars table for [%u:%u]\n", cell->h_entry, + cell->h_id); + if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, + DIALOG_VARS_TABLE_COL_NO)) + != 0) { LM_ERR("could not add another dialog-var to db\n"); goto error; } - var->vflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED); + var->vflags &= ~(DLG_FLAG_NEW | DLG_FLAG_CHANGED); } else if((var->vflags & DLG_FLAG_CHANGED) != 0) { /* save only dialog's state and timeout */ - SET_STR_VALUE(values+3, var->value); + SET_STR_VALUE(values + 3, var->value); - if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, - values, (insert_keys+3), (values+3), 3, 1)) !=0){ + if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, values, + (insert_keys + 3), (values + 3), 3, 1)) + != 0) { LM_ERR("could not update database info\n"); goto error; } @@ -887,104 +916,120 @@ int update_dialog_vars_dbinfo(struct dlg_cell * cell, struct dlg_var * var) return -1; } -int update_dialog_out_dbinfo_unsafe(struct dlg_cell * cell) +int update_dialog_out_dbinfo_unsafe(struct dlg_cell *cell) { - str x = {0,0}; - - struct dlg_cell_out *dlg_out = cell->dlg_entry_out.first; - if (!dlg_out) { - LM_DBG("no out dialogs to update\n"); - return 0; - } - - if(use_dialog_out_table()!=0) + str x = {0, 0}; + + struct dlg_cell_out *dlg_out = cell->dlg_entry_out.first; + if(!dlg_out) { + LM_DBG("no out dialogs to update\n"); + return 0; + } + + if(use_dialog_out_table() != 0) return -1; - if ((cell->dflags & DLG_FLAG_NEW) != 0) { + if((cell->dflags & DLG_FLAG_NEW) != 0) { db_val_t values[DIALOG_OUT_TABLE_COL_NO]; - db_key_t insert_keys[DIALOG_OUT_TABLE_COL_NO] = { - &id_column, &h_entry_column, - &h_id_column, &did_column, - &to_uri_column, &to_tag_column, - &caller_cseq_column, &callee_cseq_column, - &callee_contact_column, &callee_routeset_column, - &callee_sock_column }; - - VAL_TYPE(GET_FIELD_IDX(values, DLGO_ID_COL_IDX)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX))= DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = DB1_INT; - - VAL_TYPE(GET_FIELD_IDX(values, DLGO_DID_COL_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_TO_URI_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_TO_TAG_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLER_CSEQ_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_CSEQ_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX))= DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_ROUTESET_IDX))= DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX)) = DB1_STR; - - VAL_NULL(GET_FIELD_IDX(values, DLGO_ID_COL_IDX))= 1; - VAL_NULL(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX))= 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_DID_COL_IDX)) = 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_TO_URI_IDX)) = 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_TO_TAG_IDX)) = 0; + db_key_t insert_keys[DIALOG_OUT_TABLE_COL_NO] = {&id_column, + &h_entry_column, &h_id_column, &did_column, &to_uri_column, + &to_tag_column, &caller_cseq_column, &callee_cseq_column, + &callee_contact_column, &callee_routeset_column, + &callee_sock_column}; + + VAL_TYPE(GET_FIELD_IDX(values, DLGO_ID_COL_IDX)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = DB1_INT; + + VAL_TYPE(GET_FIELD_IDX(values, DLGO_DID_COL_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_TO_URI_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_TO_TAG_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLER_CSEQ_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_CSEQ_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_ROUTESET_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX)) = DB1_STR; + + VAL_NULL(GET_FIELD_IDX(values, DLGO_ID_COL_IDX)) = 1; + VAL_NULL(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_DID_COL_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_TO_URI_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_TO_TAG_IDX)) = 0; //VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLER_CSEQ_IDX)) = 0; //VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLEE_CSEQ_IDX)) = 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX))= 0; - VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX)) = 0; + VAL_NULL(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX)) = 0; do { - VAL_INT(GET_FIELD_IDX(values, DLGO_ID_COL_IDX)) = 0; - VAL_INT(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX)) = dlg_out->h_entry; - VAL_INT(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = dlg_out->h_id; - - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_DID_COL_IDX), dlg_out->did); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_TO_URI_IDX), dlg_out->to_uri); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_TO_TAG_IDX), dlg_out->to_tag); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLER_CSEQ_IDX), dlg_out->caller_cseq); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_CSEQ_IDX), dlg_out->callee_cseq); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX), dlg_out->callee_contact); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_ROUTESET_IDX), dlg_out->callee_route_set); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX), dlg_out->callee_bind_addr?dlg_out->callee_bind_addr->sock_str:x); - - SET_PROPER_NULL_FLAG(dlg_out->callee_route_set, values, DLGO_CALLEE_ROUTESET_IDX); - SET_PROPER_NULL_FLAG(dlg_out->caller_cseq, values, DLGO_CALLER_CSEQ_IDX); - SET_PROPER_NULL_FLAG(dlg_out->callee_cseq, values, DLGO_CALLEE_CSEQ_IDX); - - LM_DBG("Inserting into dialog out table for dlg_in: [%u:%u] and dlg_out [%u:%u]\n", cell->h_entry, cell->h_id, dlg_out->h_entry, dlg_out->h_id); - if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, DIALOG_OUT_TABLE_COL_NO)) !=0){ - LM_ERR("could not add another dialog_out to db\n"); - goto error; - } - dlg_out = dlg_out->next; - } - while(dlg_out && dlg_out != cell->dlg_entry_out.first); - } - else if((cell->dflags & DLG_FLAG_CHANGED) != 0) { + VAL_INT(GET_FIELD_IDX(values, DLGO_ID_COL_IDX)) = 0; + VAL_INT(GET_FIELD_IDX(values, DLGO_HASH_ENTRY_COL_IDX)) = + dlg_out->h_entry; + VAL_INT(GET_FIELD_IDX(values, DLGO_HASH_ID_COL_IDX)) = + dlg_out->h_id; + + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGO_DID_COL_IDX), dlg_out->did); + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGO_TO_URI_IDX), dlg_out->to_uri); + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGO_TO_TAG_IDX), dlg_out->to_tag); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLER_CSEQ_IDX), + dlg_out->caller_cseq); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_CSEQ_IDX), + dlg_out->callee_cseq); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_CONTACT_IDX), + dlg_out->callee_contact); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_ROUTESET_IDX), + dlg_out->callee_route_set); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGO_CALLEE_SOCK_IDX), + dlg_out->callee_bind_addr + ? dlg_out->callee_bind_addr->sock_str + : x); + + SET_PROPER_NULL_FLAG(dlg_out->callee_route_set, values, + DLGO_CALLEE_ROUTESET_IDX); + SET_PROPER_NULL_FLAG( + dlg_out->caller_cseq, values, DLGO_CALLER_CSEQ_IDX); + SET_PROPER_NULL_FLAG( + dlg_out->callee_cseq, values, DLGO_CALLEE_CSEQ_IDX); + + LM_DBG("Inserting into dialog out table for dlg_in: [%u:%u] and " + "dlg_out [%u:%u]\n", + cell->h_entry, cell->h_id, dlg_out->h_entry, dlg_out->h_id); + if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, + DIALOG_OUT_TABLE_COL_NO)) + != 0) { + LM_ERR("could not add another dialog_out to db\n"); + goto error; + } + dlg_out = dlg_out->next; + } while(dlg_out && dlg_out != cell->dlg_entry_out.first); + } else if((cell->dflags & DLG_FLAG_CHANGED) != 0) { db_val_t values[4]; - db_key_t insert_keys[4] = { &h_entry_column, &h_id_column, - &caller_cseq_column,&callee_cseq_column - }; + db_key_t insert_keys[4] = {&h_entry_column, &h_id_column, + &caller_cseq_column, &callee_cseq_column}; /* save only dialog's state and timeout */ - VAL_TYPE(GET_FIELD_IDX(values, 0)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 1)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 2)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, 3)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, 0)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 1)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 2)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, 3)) = DB1_STR; - VAL_INT(GET_FIELD_IDX(values, 0)) = dlg_out->h_entry; - VAL_INT(GET_FIELD_IDX(values, 1)) = dlg_out->h_id; + VAL_INT(GET_FIELD_IDX(values, 0)) = dlg_out->h_entry; + VAL_INT(GET_FIELD_IDX(values, 1)) = dlg_out->h_id; SET_STR_VALUE(GET_FIELD_IDX(values, 2), dlg_out->caller_cseq); SET_STR_VALUE(GET_FIELD_IDX(values, 3), dlg_out->callee_cseq); - VAL_NULL(GET_FIELD_IDX(values, 0)) = 0; - VAL_NULL(GET_FIELD_IDX(values, 1)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 0)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 1)) = 0; SET_PROPER_NULL_FLAG(dlg_out->caller_cseq, values, 2); SET_PROPER_NULL_FLAG(dlg_out->callee_cseq, values, 3); - if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, values, insert_keys, values, 2, 4)) !=0 ){ + if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, values, + insert_keys, values, 2, 4)) + != 0) { LM_ERR("could not update database info\n"); goto error; } @@ -996,48 +1041,48 @@ int update_dialog_out_dbinfo_unsafe(struct dlg_cell * cell) return -1; } -int update_dialog_dbinfo_unsafe(struct dlg_cell * cell) +int update_dialog_dbinfo_unsafe(struct dlg_cell *cell) { struct dlg_var *var; - if( (cell->dflags & DLG_FLAG_NEW) != 0 || (cell->dflags & DLG_FLAG_CHANGED_VARS) != 0) { + if((cell->dflags & DLG_FLAG_NEW) != 0 + || (cell->dflags & DLG_FLAG_CHANGED_VARS) != 0) { /* iterate the list */ - for(var=cell->vars ; var ; var=var->next) { - if (update_dialog_vars_dbinfo(cell, var) != 0) + for(var = cell->vars; var; var = var->next) { + if(update_dialog_vars_dbinfo(cell, var) != 0) return -1; } /* Remove the flag */ cell->dflags &= ~DLG_FLAG_CHANGED_VARS; } - if (update_dialog_out_dbinfo_unsafe(cell) != 0) + if(update_dialog_out_dbinfo_unsafe(cell) != 0) goto error; - if(use_dialog_table()!=0) + if(use_dialog_table() != 0) return -1; - if((cell->dflags & DLG_FLAG_NEW) != 0){ + if((cell->dflags & DLG_FLAG_NEW) != 0) { db_val_t values[DIALOG_IN_TABLE_COL_NO]; - db_key_t insert_keys[DIALOG_IN_TABLE_COL_NO] = { - &id_column, &h_entry_column, - &h_id_column, &did_column, - &call_id, &from_uri_column, - &from_tag_column, &caller_original_cseq_column, - &req_uri_column, &caller_route_set_column, - &caller_contact_column, &caller_sock_column, &timeout_column, - &state_column, &start_time_column, - &sflags_column, &to_route_name_column, &to_route_index_column }; + db_key_t insert_keys[DIALOG_IN_TABLE_COL_NO] = {&id_column, + &h_entry_column, &h_id_column, &did_column, &call_id, + &from_uri_column, &from_tag_column, + &caller_original_cseq_column, &req_uri_column, + &caller_route_set_column, &caller_contact_column, + &caller_sock_column, &timeout_column, &state_column, + &start_time_column, &sflags_column, &to_route_name_column, + &to_route_index_column}; /* save all the current dialogs information*/ VAL_TYPE(GET_FIELD_IDX(values, DLGI_ID_COL_IDX)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX))= DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_HASH_ID_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_TIMEOUT_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, DLGI_TOROUTE_INDEX_COL_IDX)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, DLGI_TOROUTE_INDEX_COL_IDX)) = DB1_INT; VAL_TYPE(GET_FIELD_IDX(values, DLGI_DID_COL_IDX)) = DB1_STR; VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLID_COL_IDX)) = DB1_STR; @@ -1045,45 +1090,61 @@ int update_dialog_dbinfo_unsafe(struct dlg_cell * cell) VAL_TYPE(GET_FIELD_IDX(values, DLGI_FROM_TAG_COL_IDX)) = DB1_STR; VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_CSEQ_COL_IDX)) = DB1_STR; VAL_TYPE(GET_FIELD_IDX(values, DLGI_REQ_URI_COL_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_ROUTESET_COL_IDX))= DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_CONTACT_COL_IDX))= DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_ROUTESET_COL_IDX)) = DB1_STR; + VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_CONTACT_COL_IDX)) = DB1_STR; VAL_TYPE(GET_FIELD_IDX(values, DLGI_CALLER_SOCK_IDX)) = DB1_STR; - VAL_TYPE(GET_FIELD_IDX(values, DLGI_TOROUTE_NAME_COL_IDX)) = DB1_STR; - - VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX)) = cell->h_entry; - VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ID_COL_IDX)) = cell->h_id; - VAL_INT(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)) = cell->start_ts; - VAL_INT(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX)) = cell->state; - VAL_INT(GET_FIELD_IDX(values, DLGI_TIMEOUT_COL_IDX)) = (unsigned int)( (unsigned int)time(0) + cell->tl.timeout - get_ticks() ); - VAL_INT(GET_FIELD_IDX(values, DLGI_TOROUTE_INDEX_COL_IDX)) = cell->toroute; + VAL_TYPE(GET_FIELD_IDX(values, DLGI_TOROUTE_NAME_COL_IDX)) = DB1_STR; + + VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX)) = cell->h_entry; + VAL_INT(GET_FIELD_IDX(values, DLGI_HASH_ID_COL_IDX)) = cell->h_id; + VAL_INT(GET_FIELD_IDX(values, DLGI_START_TIME_COL_IDX)) = + cell->start_ts; + VAL_INT(GET_FIELD_IDX(values, DLGI_STATE_COL_IDX)) = cell->state; + VAL_INT(GET_FIELD_IDX(values, DLGI_TIMEOUT_COL_IDX)) = + (unsigned int)((unsigned int)time(0) + cell->tl.timeout + - get_ticks()); + VAL_INT(GET_FIELD_IDX(values, DLGI_TOROUTE_INDEX_COL_IDX)) = + cell->toroute; SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLID_COL_IDX), cell->callid); SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_DID_COL_IDX), cell->did); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_FROM_URI_COL_IDX), cell->from_uri); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_FROM_TAG_COL_IDX), cell->from_tag); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_CSEQ_COL_IDX), cell->first_req_cseq); + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGI_FROM_URI_COL_IDX), cell->from_uri); + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGI_FROM_TAG_COL_IDX), cell->from_tag); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_CSEQ_COL_IDX), + cell->first_req_cseq); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_SOCK_IDX), cell->caller_bind_addr->sock_str); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_SOCK_IDX), + cell->caller_bind_addr->sock_str); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_ROUTESET_COL_IDX), cell->caller_route_set); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_CONTACT_COL_IDX), cell->caller_contact); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_ROUTESET_COL_IDX), + cell->caller_route_set); + SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_CALLER_CONTACT_COL_IDX), + cell->caller_contact); - SET_PROPER_NULL_FLAG(cell->caller_route_set, values, DLGI_CALLER_ROUTESET_COL_IDX); + SET_PROPER_NULL_FLAG( + cell->caller_route_set, values, DLGI_CALLER_ROUTESET_COL_IDX); VAL_NULL(GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)) = 0; - VAL_INT(GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)) = cell->sflags; - - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_TOROUTE_NAME_COL_IDX), cell->toroute_name); - SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_REQ_URI_COL_IDX), cell->req_uri); - - SET_PROPER_NULL_FLAG(cell->callid, values, DLGI_CALLID_COL_IDX); - SET_PROPER_NULL_FLAG(cell->did, values, DLGI_DID_COL_IDX); - SET_PROPER_NULL_FLAG(cell->from_uri,values, DLGI_FROM_URI_COL_IDX); - SET_PROPER_NULL_FLAG(cell->from_tag,values, DLGI_FROM_TAG_COL_IDX); - SET_PROPER_NULL_FLAG(cell->caller_route_set,values, DLGI_CALLER_ROUTESET_COL_IDX); + VAL_INT(GET_FIELD_IDX(values, DLGI_SFLAGS_COL_IDX)) = cell->sflags; + + SET_STR_VALUE(GET_FIELD_IDX(values, DLGI_TOROUTE_NAME_COL_IDX), + cell->toroute_name); + SET_STR_VALUE( + GET_FIELD_IDX(values, DLGI_REQ_URI_COL_IDX), cell->req_uri); + + SET_PROPER_NULL_FLAG(cell->callid, values, DLGI_CALLID_COL_IDX); + SET_PROPER_NULL_FLAG(cell->did, values, DLGI_DID_COL_IDX); + SET_PROPER_NULL_FLAG(cell->from_uri, values, DLGI_FROM_URI_COL_IDX); + SET_PROPER_NULL_FLAG(cell->from_tag, values, DLGI_FROM_TAG_COL_IDX); + SET_PROPER_NULL_FLAG( + cell->caller_route_set, values, DLGI_CALLER_ROUTESET_COL_IDX); SET_PROPER_NULL_FLAG(cell->req_uri, values, DLGI_REQ_URI_COL_IDX); - SET_PROPER_NULL_FLAG(cell->toroute_name, values, DLGI_TOROUTE_NAME_COL_IDX); - SET_PROPER_NULL_FLAG(cell->first_req_cseq, values, DLGI_CALLER_CSEQ_COL_IDX); + SET_PROPER_NULL_FLAG( + cell->toroute_name, values, DLGI_TOROUTE_NAME_COL_IDX); + SET_PROPER_NULL_FLAG( + cell->first_req_cseq, values, DLGI_CALLER_CSEQ_COL_IDX); VAL_NULL(GET_FIELD_IDX(values, DLGI_ID_COL_IDX)) = 1; VAL_NULL(GET_FIELD_IDX(values, DLGI_HASH_ENTRY_COL_IDX)) = 0; @@ -1094,43 +1155,50 @@ int update_dialog_dbinfo_unsafe(struct dlg_cell * cell) VAL_NULL(GET_FIELD_IDX(values, DLGI_CALLER_CONTACT_COL_IDX)) = 0; VAL_NULL(GET_FIELD_IDX(values, DLGI_CALLER_SOCK_IDX)) = 0; - LM_DBG("Inserting dialog into dialog_in table [%u:%u]\n", cell->h_entry, cell->h_id); - if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, DIALOG_IN_TABLE_COL_NO)) !=0){ + LM_DBG("Inserting dialog into dialog_in table [%u:%u]\n", cell->h_entry, + cell->h_id); + if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, + DIALOG_IN_TABLE_COL_NO)) + != 0) { LM_ERR("could not add another dialog_in to db\n"); goto error; } - cell->dflags &= ~(DLG_FLAG_NEW|DLG_FLAG_CHANGED); + cell->dflags &= ~(DLG_FLAG_NEW | DLG_FLAG_CHANGED); cell->dflags |= DLG_FLAG_INSERTED; - + } else if((cell->dflags & DLG_FLAG_CHANGED) != 0) { db_val_t values[5]; - db_key_t insert_keys[5] = { &h_entry_column, &h_id_column, - &state_column, &timeout_column, - &caller_original_cseq_column}; + db_key_t insert_keys[5] = {&h_entry_column, &h_id_column, &state_column, + &timeout_column, &caller_original_cseq_column}; /* save only dialog's state and timeout */ - VAL_TYPE(GET_FIELD_IDX(values, 0)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 1)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 2)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 3)) = DB1_INT; - VAL_TYPE(GET_FIELD_IDX(values, 4)) = DB1_STR; - - VAL_INT(GET_FIELD_IDX(values, 0)) = cell->h_entry; - VAL_INT(GET_FIELD_IDX(values, 1)) = cell->h_id; - VAL_INT(GET_FIELD_IDX(values, 2)) = cell->state; - VAL_INT(GET_FIELD_IDX(values, 3)) = (unsigned int)( (unsigned int)time(0) + cell->tl.timeout - get_ticks() ); + VAL_TYPE(GET_FIELD_IDX(values, 0)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 1)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 2)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 3)) = DB1_INT; + VAL_TYPE(GET_FIELD_IDX(values, 4)) = DB1_STR; + + VAL_INT(GET_FIELD_IDX(values, 0)) = cell->h_entry; + VAL_INT(GET_FIELD_IDX(values, 1)) = cell->h_id; + VAL_INT(GET_FIELD_IDX(values, 2)) = cell->state; + VAL_INT(GET_FIELD_IDX(values, 3)) = + (unsigned int)((unsigned int)time(0) + cell->tl.timeout + - get_ticks()); SET_STR_VALUE(GET_FIELD_IDX(values, 4), cell->first_req_cseq); - VAL_NULL(GET_FIELD_IDX(values, 0)) = 0; - VAL_NULL(GET_FIELD_IDX(values, 1)) = 0; - VAL_NULL(GET_FIELD_IDX(values, 2)) = 0; - VAL_NULL(GET_FIELD_IDX(values, 3)) = 0; - VAL_NULL(GET_FIELD_IDX(values, 4)) = 0; - - LM_DBG("Updating dialog in dialog_in table [%u:%u]\n", cell->h_entry, cell->h_id); - if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, values, insert_keys, values, 2, 4)) !=0 ){ + VAL_NULL(GET_FIELD_IDX(values, 0)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 1)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 2)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 3)) = 0; + VAL_NULL(GET_FIELD_IDX(values, 4)) = 0; + + LM_DBG("Updating dialog in dialog_in table [%u:%u]\n", cell->h_entry, + cell->h_id); + if((dialog_dbf.update(dialog_db_handle, insert_keys, 0, values, + insert_keys, values, 2, 4)) + != 0) { LM_ERR("could not update database info\n"); goto error; } @@ -1144,45 +1212,44 @@ int update_dialog_dbinfo_unsafe(struct dlg_cell * cell) return -1; } -int update_dialog_dbinfo(struct dlg_cell * cell) +int update_dialog_dbinfo(struct dlg_cell *cell) { struct dlg_entry entry; /* lock the entry */ entry = (d_table->entries)[cell->h_entry]; - dlg_lock( d_table, &entry); - if (update_dialog_dbinfo_unsafe(cell) != 0) { - dlg_unlock( d_table, &entry); + dlg_lock(d_table, &entry); + if(update_dialog_dbinfo_unsafe(cell) != 0) { + dlg_unlock(d_table, &entry); return -1; - } - dlg_unlock( d_table, &entry); + } + dlg_unlock(d_table, &entry); return 0; } -void dialog_update_db(unsigned int ticks, void * param) +void dialog_update_db(unsigned int ticks, void *param) { int index; struct dlg_entry entry; - struct dlg_cell * cell; + struct dlg_cell *cell; LM_DBG("saving current_info \n"); - - for(index = 0; index< d_table->size; index++){ + + for(index = 0; index < d_table->size; index++) { /* lock the whole entry */ entry = (d_table->entries)[index]; - dlg_lock( d_table, &entry); + dlg_lock(d_table, &entry); - for(cell = entry.first; cell != NULL; cell = cell->next){ - if (update_dialog_dbinfo_unsafe(cell) != 0) { - dlg_unlock( d_table, &entry); + for(cell = entry.first; cell != NULL; cell = cell->next) { + if(update_dialog_dbinfo_unsafe(cell) != 0) { + dlg_unlock(d_table, &entry); goto error; } } - dlg_unlock( d_table, &entry); - + dlg_unlock(d_table, &entry); } return; error: - dlg_unlock( d_table, &entry); + dlg_unlock(d_table, &entry); } diff --git a/src/modules/ims_dialog/dlg_db_handler.h b/src/modules/ims_dialog/dlg_db_handler.h index fa4c1698951..94da57509b6 100644 --- a/src/modules/ims_dialog/dlg_db_handler.h +++ b/src/modules/ims_dialog/dlg_db_handler.h @@ -32,58 +32,58 @@ #include "../../core/str.h" #include "../../lib/srdb1/db.h" -#define ID_COL "id" -#define HASH_ENTRY_COL "hash_entry" -#define HASH_ID_COL "hash_id" -#define DID_COL "did" -#define CALL_ID_COL "callid" -#define FROM_URI_COL "from_uri" -#define FROM_TAG_COL "from_tag" +#define ID_COL "id" +#define HASH_ENTRY_COL "hash_entry" +#define HASH_ID_COL "hash_id" +#define DID_COL "did" +#define CALL_ID_COL "callid" +#define FROM_URI_COL "from_uri" +#define FROM_TAG_COL "from_tag" #define CALLER_ORIGINAL_CSEQ_COL "caller_original_cseq" -#define REQ_URI_COL "req_uri" -#define CALLER_ROUTESET_COL "caller_route_set" -#define CALLER_CONTACT_COL "caller_contact" -#define CALLER_SOCK "caller_sock" -#define STATE_COL "state" -#define START_TIME_COL "start_time" -#define TIMEOUT_COL "timeout" -#define SFLAGS_COL "sflags" -#define TOROUTE_NAME_COL "toroute_name" -#define TOROUTE_INDEX_COL "toroute_index" +#define REQ_URI_COL "req_uri" +#define CALLER_ROUTESET_COL "caller_route_set" +#define CALLER_CONTACT_COL "caller_contact" +#define CALLER_SOCK "caller_sock" +#define STATE_COL "state" +#define START_TIME_COL "start_time" +#define TIMEOUT_COL "timeout" +#define SFLAGS_COL "sflags" +#define TOROUTE_NAME_COL "toroute_name" +#define TOROUTE_INDEX_COL "toroute_index" // dialog_out exclusive columns -#define TO_URI_COL "to_uri" -#define TO_TAG_COL "to_tag" -#define CALLER_CSEQ_COL "caller_cseq" -#define CALLEE_CSEQ_COL "callee_cseq" -#define CALLEE_CONTACT_COL "callee_contact" -#define CALLEE_ROUTESET_COL "callee_route_set" -#define CALLEE_SOCK "callee_sock" +#define TO_URI_COL "to_uri" +#define TO_TAG_COL "to_tag" +#define CALLER_CSEQ_COL "caller_cseq" +#define CALLEE_CSEQ_COL "callee_cseq" +#define CALLEE_CONTACT_COL "callee_contact" +#define CALLEE_ROUTESET_COL "callee_route_set" +#define CALLEE_SOCK "callee_sock" //#define XDATA_COL "xdata" -#define DIALOG_IN_TABLE_NAME "dialog_in" -#define DIALOG_OUT_TABLE_NAME "dialog_out" -#define DLG_TABLE_VERSION 7 -#define DIALOG_IN_TABLE_COL_NO 18 +#define DIALOG_IN_TABLE_NAME "dialog_in" +#define DIALOG_OUT_TABLE_NAME "dialog_out" +#define DLG_TABLE_VERSION 7 +#define DIALOG_IN_TABLE_COL_NO 18 #define DIALOG_OUT_TABLE_COL_NO 11 -#define VARS_HASH_ID_COL "hash_id" -#define VARS_HASH_ENTRY_COL "hash_entry" -#define VARS_KEY_COL "dialog_key" -#define VARS_VALUE_COL "dialog_value" -#define DIALOG_VARS_TABLE_NAME "dialog_vars" -#define DLG_VARS_TABLE_VERSION 7 -#define DIALOG_VARS_TABLE_COL_NO 4 +#define VARS_HASH_ID_COL "hash_id" +#define VARS_HASH_ENTRY_COL "hash_entry" +#define VARS_KEY_COL "dialog_key" +#define VARS_VALUE_COL "dialog_value" +#define DIALOG_VARS_TABLE_NAME "dialog_vars" +#define DLG_VARS_TABLE_VERSION 7 +#define DIALOG_VARS_TABLE_COL_NO 4 /*every minute the dialogs' information will be refreshed*/ -#define DB_DEFAULT_UPDATE_PERIOD 60 -#define DB_MODE_NONE 0 -#define DB_MODE_REALTIME 1 -#define DB_MODE_DELAYED 2 -#define DB_MODE_SHUTDOWN 3 +#define DB_DEFAULT_UPDATE_PERIOD 60 +#define DB_MODE_NONE 0 +#define DB_MODE_REALTIME 1 +#define DB_MODE_DELAYED 2 +#define DB_MODE_SHUTDOWN 3 /* Dialog table */ -extern str call_id_column; +extern str call_id_column; extern str from_uri_column; extern str from_tag_column; extern str to_uri_column; @@ -114,12 +114,13 @@ extern str vars_value_column; extern str dialog_vars_table_name; -int init_dlg_db(const str *db_url, int dlg_hash_size, int db_update_period, int fetch_num_rows); +int init_dlg_db(const str *db_url, int dlg_hash_size, int db_update_period, + int fetch_num_rows); int dlg_connect_db(const str *db_url); void destroy_dlg_db(void); -int remove_dialog_in_from_db(struct dlg_cell * cell); -int update_dialog_dbinfo(struct dlg_cell * cell); -void dialog_update_db(unsigned int ticks, void * param); +int remove_dialog_in_from_db(struct dlg_cell *cell); +int update_dialog_dbinfo(struct dlg_cell *cell); +void dialog_update_db(unsigned int ticks, void *param); #endif diff --git a/src/modules/ims_dialog/dlg_handlers.c b/src/modules/ims_dialog/dlg_handlers.c index b5a036199f6..023c2019e3c 100644 --- a/src/modules/ims_dialog/dlg_handlers.c +++ b/src/modules/ims_dialog/dlg_handlers.c @@ -31,12 +31,12 @@ #include "dlg_db_handler.h" #include "dlg_ng_stats.h" -static str rr_param; /*!< record-route parameter for matching */ -static int dlg_flag; /*!< flag for dialog tracking */ +static str rr_param; /*!< record-route parameter for matching */ +static int dlg_flag; /*!< flag for dialog tracking */ static pv_spec_t *timeout_avp; /*!< AVP for timeout setting */ -static int default_timeout; /*!< default dialog timeout */ -static int seq_match_mode; /*!< dlg_match mode */ -static int shutdown_done = 0; /*!< 1 when destroy_dlg_handlers was called */ +static int default_timeout; /*!< default dialog timeout */ +static int seq_match_mode; /*!< dlg_match mode */ +static int shutdown_done = 0; /*!< 1 when destroy_dlg_handlers was called */ extern int detect_spirals; int spiral_detected = -1; @@ -47,15 +47,15 @@ time_t act_time; extern pv_elem_t *ruri_param_model; /*!< pv-string to get r-uri */ -static unsigned int CURR_DLG_LIFETIME = 0; /*!< current dialog lifetime */ -static unsigned int CURR_DLG_STATUS = 0; /*!< current dialog state */ +static unsigned int CURR_DLG_LIFETIME = 0; /*!< current dialog lifetime */ +static unsigned int CURR_DLG_STATUS = 0; /*!< current dialog state */ static unsigned int CURR_DLG_ID = 0xffffffff; /*!< current dialog id */ /*! size of the dialog record-route parameter */ -#define RR_DLG_PARAM_SIZE (2*2*sizeof(int)+3+MAX_DLG_RR_PARAM_NAME) +#define RR_DLG_PARAM_SIZE (2 * 2 * sizeof(int) + 3 + MAX_DLG_RR_PARAM_NAME) /*! separator inside the record-route paramter */ -#define DLG_SEPARATOR '.' +#define DLG_SEPARATOR '.' /*! * \brief Initialize the dialog handlers @@ -65,22 +65,25 @@ static unsigned int CURR_DLG_ID = 0xffffffff; /*!< current dialog id */ * \param default_timeout_p default timeout * \param seq_match_mode_p matching mode */ -void init_dlg_handlers(char *rr_param_p, int dlg_flag_p, pv_spec_t *timeout_avp_p, int default_timeout_p, int seq_match_mode_p) { - rr_param.s = rr_param_p; - rr_param.len = strlen(rr_param.s); +void init_dlg_handlers(char *rr_param_p, int dlg_flag_p, + pv_spec_t *timeout_avp_p, int default_timeout_p, int seq_match_mode_p) +{ + rr_param.s = rr_param_p; + rr_param.len = strlen(rr_param.s); - dlg_flag = 1 << dlg_flag_p; + dlg_flag = 1 << dlg_flag_p; - timeout_avp = timeout_avp_p; - default_timeout = default_timeout_p; - seq_match_mode = seq_match_mode_p; + timeout_avp = timeout_avp_p; + default_timeout = default_timeout_p; + seq_match_mode = seq_match_mode_p; } /*! * \brief Shutdown operation of the module */ -void destroy_dlg_handlers(void) { - shutdown_done = 1; +void destroy_dlg_handlers(void) +{ + shutdown_done = 1; } /*! @@ -90,37 +93,39 @@ void destroy_dlg_handlers(void) { * \param id dialog hash id * \return 0 on success, -1 on failure */ -static inline int add_dlg_rr_param(struct sip_msg *req, unsigned int entry, unsigned int id) { - static char buf[RR_DLG_PARAM_SIZE]; - str s; - int n; - char *p; +static inline int add_dlg_rr_param( + struct sip_msg *req, unsigned int entry, unsigned int id) +{ + static char buf[RR_DLG_PARAM_SIZE]; + str s; + int n; + char *p; - s.s = p = buf; + s.s = p = buf; - *(p++) = ';'; - memcpy(p, rr_param.s, rr_param.len); - p += rr_param.len; - *(p++) = '='; + *(p++) = ';'; + memcpy(p, rr_param.s, rr_param.len); + p += rr_param.len; + *(p++) = '='; - n = RR_DLG_PARAM_SIZE - (p - buf); - if (int2reverse_hex(&p, &n, entry) == -1) - return -1; + n = RR_DLG_PARAM_SIZE - (p - buf); + if(int2reverse_hex(&p, &n, entry) == -1) + return -1; - *(p++) = DLG_SEPARATOR; + *(p++) = DLG_SEPARATOR; - n = RR_DLG_PARAM_SIZE - (p - buf); - if (int2reverse_hex(&p, &n, id) == -1) - return -1; + n = RR_DLG_PARAM_SIZE - (p - buf); + if(int2reverse_hex(&p, &n, id) == -1) + return -1; - s.len = p - buf; + s.len = p - buf; - if (d_rrb.add_rr_param(req, &s) < 0) { - LM_ERR("failed to add rr param\n"); - return -1; - } + if(d_rrb.add_rr_param(req, &s) < 0) { + LM_ERR("failed to add rr param\n"); + return -1; + } - return 0; + return 0; } /*! @@ -129,20 +134,22 @@ static inline int add_dlg_rr_param(struct sip_msg *req, unsigned int entry, unsi * \param type type of the entered callback * \param param saved dialog structure in the callback */ -static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *param) { - dlg_cell_t *dlg = NULL; - dlg_iuid_t *iuid = NULL; - - LM_DBG("Unref dlg from callback called\n"); - iuid = (dlg_iuid_t*) (*param->param); - if (iuid == NULL) - return; - - dlg = dlg_get_by_iuid(iuid); - if (dlg == NULL) - return; - /* unref by 2: 1 set when adding in tm cb, 1 sent by dlg_get_by_iuid() */ - unref_dlg(dlg, 2); +static void unref_dlg_from_cb( + struct cell *t, int type, struct tmcb_params *param) +{ + dlg_cell_t *dlg = NULL; + dlg_iuid_t *iuid = NULL; + + LM_DBG("Unref dlg from callback called\n"); + iuid = (dlg_iuid_t *)(*param->param); + if(iuid == NULL) + return; + + dlg = dlg_get_by_iuid(iuid); + if(dlg == NULL) + return; + /* unref by 2: 1 set when adding in tm cb, 1 sent by dlg_get_by_iuid() */ + unref_dlg(dlg, 2); } /*! @@ -158,133 +165,149 @@ static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *para * \note for a request: get record route in normal order, for a reply get * in reverse order, skipping the ones from the request and the proxies' own */ -int populate_leg_info(struct dlg_cell *dlg, struct sip_msg *msg, - struct cell* t, unsigned int leg, str *tag) { - unsigned int skip_recs; - str cseq; - str contact; - str rr_set; - struct socket_info* callee_bind_address = NULL; - - if (leg == DLG_CALLER_LEG) - dlg->caller_bind_addr = msg->rcv.bind_address; - else - callee_bind_address = msg->rcv.bind_address; - - - - /* extract the cseq number as string from the request or response*/ - //TO DO - can pair the cseqs here to make sure that the response and request are in sync - - if ((!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) < 0 || !msg->cseq)) - || !msg->cseq->parsed) { - LM_ERR("bad sip message or missing CSeq hdr :-/\n"); - goto error0; - } - cseq = (get_cseq(msg))->number; - - - /* extract the contact address */ - if (!msg->contact && (parse_headers(msg, HDR_CONTACT_F, 0) < 0 || !msg->contact)) { - if (msg->first_line.type == SIP_REQUEST) - LM_ERR("bad sip message or missing Contact hdr for message [%.*s]\n", msg->first_line.u.request.method.len, msg->first_line.u.request.method.s); - else - LM_ERR("bad sip message or missing Contact hdr for message [%.*s]\n", msg->first_line.u.reply.status.len, msg->first_line.u.reply.status.s); - goto error0; - } - if (parse_contact(msg->contact) < 0 || - ((contact_body_t *) msg->contact->parsed)->contacts == NULL || - ((contact_body_t *) msg->contact->parsed)->contacts->next != NULL) { - LM_ERR("bad Contact HDR\n"); - goto error0; - } - contact = ((contact_body_t *) msg->contact->parsed)->contacts->uri; - - /* extract the RR parts */ - if (!msg->record_route && (parse_headers(msg, HDR_EOH_F, 0) < 0)) { - LM_ERR("failed to parse record route header\n"); - goto error0; - } - - if (leg == DLG_CALLER_LEG) { - skip_recs = 0; - } else { - skip_recs = 0; - /* was the 200 OK received or local generated */ - skip_recs = dlg->from_rr_nb + - ((t->relayed_reply_branch >= 0) ? - ((t->uac[t->relayed_reply_branch].flags & TM_UAC_FLAG_R2) ? 2 : - ((t->uac[t->relayed_reply_branch].flags & TM_UAC_FLAG_RR) ? 1 : 0)) - : 0); - } - - if (msg->record_route) { - if (print_rr_body(msg->record_route, &rr_set, leg, - &skip_recs) != 0) { - LM_ERR("failed to print route records \n"); - goto error0; - } - } else { - rr_set.s = 0; - rr_set.len = 0; - } - - if (leg == DLG_CALLER_LEG) - dlg->from_rr_nb = skip_recs; - - LM_DBG("route_set %.*s, contact %.*s, cseq %.*s and bind_addr %.*s [%p]\n", - rr_set.len, rr_set.s, contact.len, contact.s, - cseq.len, cseq.s, - msg->rcv.bind_address->sock_str.len, - msg->rcv.bind_address->sock_str.s, msg->rcv.bind_address); - - if (dlg_set_leg_info(dlg, tag, &rr_set, &contact, &cseq, callee_bind_address, leg) != 0) { - LM_ERR("dlg_set_leg_info failed\n"); - if (rr_set.s) pkg_free(rr_set.s); - goto error0; - } - - if (rr_set.s) pkg_free(rr_set.s); - - return 0; +int populate_leg_info(struct dlg_cell *dlg, struct sip_msg *msg, struct cell *t, + unsigned int leg, str *tag) +{ + unsigned int skip_recs; + str cseq; + str contact; + str rr_set; + struct socket_info *callee_bind_address = NULL; + + if(leg == DLG_CALLER_LEG) + dlg->caller_bind_addr = msg->rcv.bind_address; + else + callee_bind_address = msg->rcv.bind_address; + + + /* extract the cseq number as string from the request or response*/ + //TO DO - can pair the cseqs here to make sure that the response and request are in sync + + if((!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) < 0 || !msg->cseq)) + || !msg->cseq->parsed) { + LM_ERR("bad sip message or missing CSeq hdr :-/\n"); + goto error0; + } + cseq = (get_cseq(msg))->number; + + + /* extract the contact address */ + if(!msg->contact + && (parse_headers(msg, HDR_CONTACT_F, 0) < 0 || !msg->contact)) { + if(msg->first_line.type == SIP_REQUEST) + LM_ERR("bad sip message or missing Contact hdr for message " + "[%.*s]\n", + msg->first_line.u.request.method.len, + msg->first_line.u.request.method.s); + else + LM_ERR("bad sip message or missing Contact hdr for message " + "[%.*s]\n", + msg->first_line.u.reply.status.len, + msg->first_line.u.reply.status.s); + goto error0; + } + if(parse_contact(msg->contact) < 0 + || ((contact_body_t *)msg->contact->parsed)->contacts == NULL + || ((contact_body_t *)msg->contact->parsed)->contacts->next + != NULL) { + LM_ERR("bad Contact HDR\n"); + goto error0; + } + contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri; + + /* extract the RR parts */ + if(!msg->record_route && (parse_headers(msg, HDR_EOH_F, 0) < 0)) { + LM_ERR("failed to parse record route header\n"); + goto error0; + } + + if(leg == DLG_CALLER_LEG) { + skip_recs = 0; + } else { + skip_recs = 0; + /* was the 200 OK received or local generated */ + skip_recs = dlg->from_rr_nb + + ((t->relayed_reply_branch >= 0) ? ( + (t->uac[t->relayed_reply_branch].flags + & TM_UAC_FLAG_R2) + ? 2 + : ((t->uac[t->relayed_reply_branch].flags + & TM_UAC_FLAG_RR) + ? 1 + : 0)) + : 0); + } + + if(msg->record_route) { + if(print_rr_body(msg->record_route, &rr_set, leg, &skip_recs) != 0) { + LM_ERR("failed to print route records \n"); + goto error0; + } + } else { + rr_set.s = 0; + rr_set.len = 0; + } + + if(leg == DLG_CALLER_LEG) + dlg->from_rr_nb = skip_recs; + + LM_DBG("route_set %.*s, contact %.*s, cseq %.*s and bind_addr %.*s [%p]\n", + rr_set.len, rr_set.s, contact.len, contact.s, cseq.len, cseq.s, + msg->rcv.bind_address->sock_str.len, + msg->rcv.bind_address->sock_str.s, msg->rcv.bind_address); + + if(dlg_set_leg_info( + dlg, tag, &rr_set, &contact, &cseq, callee_bind_address, leg) + != 0) { + LM_ERR("dlg_set_leg_info failed\n"); + if(rr_set.s) + pkg_free(rr_set.s); + goto error0; + } + + if(rr_set.s) + pkg_free(rr_set.s); + + return 0; error0: - return -1; + return -1; } /*! * \brief Clone dialog internal unique id to shared memory * \param dlg dialog */ -dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg) { - dlg_iuid_t *iuid = NULL; +dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg) +{ + dlg_iuid_t *iuid = NULL; - if (dlg == NULL) - return NULL; + if(dlg == NULL) + return NULL; - iuid = (dlg_iuid_t*) shm_malloc(sizeof (dlg_iuid_t)); - if (iuid == NULL) { - LM_ERR("failed to clone dialog iuid\n"); - return NULL; - } + iuid = (dlg_iuid_t *)shm_malloc(sizeof(dlg_iuid_t)); + if(iuid == NULL) { + LM_ERR("failed to clone dialog iuid\n"); + return NULL; + } - memset(iuid, 0, sizeof (dlg_iuid_t)); - iuid->h_entry = dlg->h_entry; - iuid->h_id = dlg->h_id; + memset(iuid, 0, sizeof(dlg_iuid_t)); + iuid->h_entry = dlg->h_entry; + iuid->h_id = dlg->h_id; - return iuid; + return iuid; } /*! * \brief Free dialog internal unique id stored in shared memory * \param iuid dialog iuid */ -void dlg_iuid_sfree(void *iuid) { - if (iuid) { - LM_DBG("freeing dlg iuid [%u:%u] (%p)\n", - ((dlg_iuid_t*) iuid)->h_entry, - ((dlg_iuid_t*) iuid)->h_id, iuid); - shm_free(iuid); - } +void dlg_iuid_sfree(void *iuid) +{ + if(iuid) { + LM_DBG("freeing dlg iuid [%u:%u] (%p)\n", ((dlg_iuid_t *)iuid)->h_entry, + ((dlg_iuid_t *)iuid)->h_id, iuid); + shm_free(iuid); + } } ///*! @@ -316,27 +339,23 @@ void dlg_iuid_sfree(void *iuid) { // 0); //} -static void dlg_cancel_confirmed(struct cell* t, - int type, - struct tmcb_params* params) { - if (!params || !params->req || !params->param) { - LM_ERR("invalid parameters!\n"); - return; - } - - struct dlg_cell* dlg = (struct dlg_cell*) *params->param; - - if (!dlg) { - LM_ERR("failed to get dialog from params!\n"); - return; - } - /* dialog termination confirmed (BYE reply) */ - run_dlg_callbacks(DLGCB_TERMINATED_CONFIRMED, - dlg, - params->req, - params->rpl, - DLG_DIR_UPSTREAM, - 0); +static void dlg_cancel_confirmed( + struct cell *t, int type, struct tmcb_params *params) +{ + if(!params || !params->req || !params->param) { + LM_ERR("invalid parameters!\n"); + return; + } + + struct dlg_cell *dlg = (struct dlg_cell *)*params->param; + + if(!dlg) { + LM_ERR("failed to get dialog from params!\n"); + return; + } + /* dialog termination confirmed (BYE reply) */ + run_dlg_callbacks(DLGCB_TERMINATED_CONFIRMED, dlg, params->req, params->rpl, + DLG_DIR_UPSTREAM, 0); } /*! @@ -345,33 +364,33 @@ static void dlg_cancel_confirmed(struct cell* t, * \param dlg corresponding dialog * \param dir message direction */ -static void dlg_terminated(struct sip_msg* req, - struct dlg_cell* dlg, - unsigned int dir) { - if (!req) { - LM_ERR("request is empty!"); - return; - } - - if (!dlg) { - LM_ERR("dialog is empty!"); - return; - } - - /* dialog terminated (BYE) */ - run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0); - -// /* register callback for the corresponding reply */ -// LM_DBG("Registering tmcb1\n"); -// if (d_tmb.register_tmcb(req, -// 0, -// TMCB_RESPONSE_OUT, -// dlg_terminated_confirmed, -// (void*) dlg, -// 0) <= 0) { -// LM_ERR("cannot register response callback for BYE request\n"); -// return; -// } +static void dlg_terminated( + struct sip_msg *req, struct dlg_cell *dlg, unsigned int dir) +{ + if(!req) { + LM_ERR("request is empty!"); + return; + } + + if(!dlg) { + LM_ERR("dialog is empty!"); + return; + } + + /* dialog terminated (BYE) */ + run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0); + + // /* register callback for the corresponding reply */ + // LM_DBG("Registering tmcb1\n"); + // if (d_tmb.register_tmcb(req, + // 0, + // TMCB_RESPONSE_OUT, + // dlg_terminated_confirmed, + // (void*) dlg, + // 0) <= 0) { + // LM_ERR("cannot register response callback for BYE request\n"); + // return; + // } } /*! @@ -380,33 +399,30 @@ static void dlg_terminated(struct sip_msg* req, * \param dlg corresponding dialog * \param dir message direction */ -static void dlg_cancelled(struct sip_msg* req, - struct dlg_cell* dlg, - unsigned int dir) { - if (!req) { - LM_ERR("request is empty!"); - return; - } - - if (!dlg) { - LM_ERR("dialog is empty!"); - return; - } - - /* dialog terminated (BYE) */ - run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0); - - /* register callback for the corresponding reply */ - LM_DBG("Registering tmcb for CANCEL confirmed\n"); - if (d_tmb.register_tmcb(req, - 0, - TMCB_RESPONSE_OUT, - dlg_cancel_confirmed, - (void*) dlg, - 0) <= 0) { - LM_ERR("cannot register response callback for CANCEL request\n"); - return; - } +static void dlg_cancelled( + struct sip_msg *req, struct dlg_cell *dlg, unsigned int dir) +{ + if(!req) { + LM_ERR("request is empty!"); + return; + } + + if(!dlg) { + LM_ERR("dialog is empty!"); + return; + } + + /* dialog terminated (BYE) */ + run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0); + + /* register callback for the corresponding reply */ + LM_DBG("Registering tmcb for CANCEL confirmed\n"); + if(d_tmb.register_tmcb( + req, 0, TMCB_RESPONSE_OUT, dlg_cancel_confirmed, (void *)dlg, 0) + <= 0) { + LM_ERR("cannot register response callback for CANCEL request\n"); + return; + } } //static void unlink_dlgouts_from_cb(struct cell* t, int type, struct tmcb_params *param) { @@ -450,29 +466,26 @@ static void dlg_cancelled(struct sip_msg* req, * \param param saved dialog structure inside the callback * \param direction direction of the request */ -static void dlg_seq_onreply_helper(struct cell* t, int type, - struct tmcb_params *param, const int direction) { - dlg_cell_t *dlg = NULL; - dlg_iuid_t *iuid = NULL; - - if (shutdown_done) - return; - iuid = (dlg_iuid_t*) (*param->param); - dlg = dlg_get_by_iuid(iuid); - if (dlg == 0) - return; - - if (type == TMCB_RESPONSE_FWDED) { - run_dlg_callbacks(DLGCB_RESPONSE_WITHIN, - dlg, - param->req, - param->rpl, - direction, - 0); - } - dlg_release(dlg); - - return; +static void dlg_seq_onreply_helper(struct cell *t, int type, + struct tmcb_params *param, const int direction) +{ + dlg_cell_t *dlg = NULL; + dlg_iuid_t *iuid = NULL; + + if(shutdown_done) + return; + iuid = (dlg_iuid_t *)(*param->param); + dlg = dlg_get_by_iuid(iuid); + if(dlg == 0) + return; + + if(type == TMCB_RESPONSE_FWDED) { + run_dlg_callbacks(DLGCB_RESPONSE_WITHIN, dlg, param->req, param->rpl, + direction, 0); + } + dlg_release(dlg); + + return; } /*! @@ -482,8 +495,10 @@ static void dlg_seq_onreply_helper(struct cell* t, int type, * \param type type of the callback, should be TMCB_RESPONSE_FWDED * \param param saved dialog structure inside the callback */ -static void dlg_seq_up_onreply(struct cell* t, int type, struct tmcb_params *param) { - return dlg_seq_onreply_helper(t, type, param, DLG_DIR_UPSTREAM); +static void dlg_seq_up_onreply( + struct cell *t, int type, struct tmcb_params *param) +{ + return dlg_seq_onreply_helper(t, type, param, DLG_DIR_UPSTREAM); } /*! @@ -493,8 +508,10 @@ static void dlg_seq_up_onreply(struct cell* t, int type, struct tmcb_params *par * \param type type of the callback, should be TMCB_RESPONSE_FWDED * \param param saved dialog structure inside the callback */ -static void dlg_seq_down_onreply(struct cell* t, int type, struct tmcb_params *param) { - return dlg_seq_onreply_helper(t, type, param, DLG_DIR_DOWNSTREAM); +static void dlg_seq_down_onreply( + struct cell *t, int type, struct tmcb_params *param) +{ + return dlg_seq_onreply_helper(t, type, param, DLG_DIR_DOWNSTREAM); } /*! @@ -502,17 +519,18 @@ static void dlg_seq_down_onreply(struct cell* t, int type, struct tmcb_params *p * \param req SIP message * \return value from timeout AVP if present or default timeout */ -inline static int get_dlg_timeout(struct sip_msg *req) { - pv_value_t pv_val; - - if (timeout_avp) { - if (pv_get_spec_value(req, timeout_avp, &pv_val) == 0 && - pv_val.flags & PV_VAL_INT && pv_val.ri > 0) { - return pv_val.ri; - } - LM_DBG("invalid AVP value, using default timeout\n"); - } - return default_timeout; +inline static int get_dlg_timeout(struct sip_msg *req) +{ + pv_value_t pv_val; + + if(timeout_avp) { + if(pv_get_spec_value(req, timeout_avp, &pv_val) == 0 + && pv_val.flags & PV_VAL_INT && pv_val.ri > 0) { + return pv_val.ri; + } + LM_DBG("invalid AVP value, using default timeout\n"); + } + return default_timeout; } /*! @@ -524,98 +542,100 @@ inline static int get_dlg_timeout(struct sip_msg *req) { * \param with_ttag flag set if to tag must be found for success * \return 0 on success, -1 on failure */ -static inline int pre_match_parse(struct sip_msg *req, str *callid, - str *ftag, str *ttag, int with_ttag) { - if (parse_headers(req, HDR_CALLID_F | HDR_TO_F, 0) < 0 || !req->callid || - !req->to) { - LM_ERR("bad request or missing CALLID/TO hdr :-/\n"); - return -1; - } - - if (get_to(req)->tag_value.len == 0) { - if (with_ttag == 1) { - /* out of dialog request with preloaded Route headers; ignore. */ - return -1; - } else { - ttag->s = NULL; - ttag->len = 0; - } - } else { - *ttag = get_to(req)->tag_value; - } - - if (parse_from_header(req) < 0 || get_from(req)->tag_value.len == 0) { - LM_ERR("failed to get From header\n"); - return -1; - } - - /* callid */ - *callid = req->callid->body; - trim(callid); - /* from tag */ - *ftag = get_from(req)->tag_value; - return 0; +static inline int pre_match_parse( + struct sip_msg *req, str *callid, str *ftag, str *ttag, int with_ttag) +{ + if(parse_headers(req, HDR_CALLID_F | HDR_TO_F, 0) < 0 || !req->callid + || !req->to) { + LM_ERR("bad request or missing CALLID/TO hdr :-/\n"); + return -1; + } + + if(get_to(req)->tag_value.len == 0) { + if(with_ttag == 1) { + /* out of dialog request with preloaded Route headers; ignore. */ + return -1; + } else { + ttag->s = NULL; + ttag->len = 0; + } + } else { + *ttag = get_to(req)->tag_value; + } + + if(parse_from_header(req) < 0 || get_from(req)->tag_value.len == 0) { + LM_ERR("failed to get From header\n"); + return -1; + } + + /* callid */ + *callid = req->callid->body; + trim(callid); + /* from tag */ + *ftag = get_from(req)->tag_value; + return 0; } -static inline char* tm_type_to_string(int type) { - switch (type) { - case TMCB_REQUEST_IN: - return "TMCB_REQUEST_IN"; - case TMCB_RESPONSE_IN: - return "TMCB_RESPONSE_IN"; - case TMCB_E2EACK_IN: - return "TMCB_E2EACK_IN"; - case TMCB_REQUEST_PENDING: - return "TMCB_REQUEST_PENDING"; - case TMCB_REQUEST_FWDED: - return "TMCB_REQUEST_FWDED"; - case TMCB_RESPONSE_FWDED: - return "TMCB_RESPONSE_FWDED"; - case TMCB_ON_FAILURE_RO: - return "TMCB_ON_FAILURE_RO"; - case TMCB_ON_FAILURE: - return "TMCB_ON_FAILURE"; - case TMCB_REQUEST_OUT: - return "TMCB_REQUEST_OUT"; - case TMCB_RESPONSE_OUT: - return "TMCB_RESPONSE_OUT"; - case TMCB_LOCAL_COMPLETED: - return "TMCB_LOCAL_COMPLETED"; - case TMCB_LOCAL_RESPONSE_OUT: - return "TMCB_LOCAL_RESPONSE_OUT"; - case TMCB_ACK_NEG_IN: - return "TMCB_ACK_NEG_IN"; - case TMCB_REQ_RETR_IN: - return "TMCB_REQ_RETR_IN"; - case TMCB_LOCAL_RESPONSE_IN: - return "TMCB_LOCAL_RESPONSE_IN"; - case TMCB_LOCAL_REQUEST_IN: - return "TMCB_LOCAL_REQUEST_IN"; - case TMCB_DLG: - return "TMCB_DLG"; - case TMCB_DESTROY: - return "TMCB_DESTROY"; - case TMCB_E2ECANCEL_IN: - return "TMCB_E2ECANCEL_IN"; - case TMCB_E2EACK_RETR_IN: - return "TMCB_E2EACK_RETR_IN"; - case TMCB_RESPONSE_READY: - return "TMCB_RESPONSE_READY"; - case TMCB_DONT_ACK: - return "TMCB_DONT_ACK"; - case TMCB_REQUEST_SENT: - return "TMCB_REQUEST_SENT"; - case TMCB_RESPONSE_SENT: - return "TMCB_RESPONSE_SENT"; - case TMCB_ON_BRANCH_FAILURE: - return "TMCB_ON_BRANCH_FAILURE"; - case TMCB_ON_BRANCH_FAILURE_RO: - return "TMCB_ON_BRANCH_FAILURE_RO"; - case TMCB_MAX: - return "TMCB_MAX"; - } - - return "UNKNOWN"; +static inline char *tm_type_to_string(int type) +{ + switch(type) { + case TMCB_REQUEST_IN: + return "TMCB_REQUEST_IN"; + case TMCB_RESPONSE_IN: + return "TMCB_RESPONSE_IN"; + case TMCB_E2EACK_IN: + return "TMCB_E2EACK_IN"; + case TMCB_REQUEST_PENDING: + return "TMCB_REQUEST_PENDING"; + case TMCB_REQUEST_FWDED: + return "TMCB_REQUEST_FWDED"; + case TMCB_RESPONSE_FWDED: + return "TMCB_RESPONSE_FWDED"; + case TMCB_ON_FAILURE_RO: + return "TMCB_ON_FAILURE_RO"; + case TMCB_ON_FAILURE: + return "TMCB_ON_FAILURE"; + case TMCB_REQUEST_OUT: + return "TMCB_REQUEST_OUT"; + case TMCB_RESPONSE_OUT: + return "TMCB_RESPONSE_OUT"; + case TMCB_LOCAL_COMPLETED: + return "TMCB_LOCAL_COMPLETED"; + case TMCB_LOCAL_RESPONSE_OUT: + return "TMCB_LOCAL_RESPONSE_OUT"; + case TMCB_ACK_NEG_IN: + return "TMCB_ACK_NEG_IN"; + case TMCB_REQ_RETR_IN: + return "TMCB_REQ_RETR_IN"; + case TMCB_LOCAL_RESPONSE_IN: + return "TMCB_LOCAL_RESPONSE_IN"; + case TMCB_LOCAL_REQUEST_IN: + return "TMCB_LOCAL_REQUEST_IN"; + case TMCB_DLG: + return "TMCB_DLG"; + case TMCB_DESTROY: + return "TMCB_DESTROY"; + case TMCB_E2ECANCEL_IN: + return "TMCB_E2ECANCEL_IN"; + case TMCB_E2EACK_RETR_IN: + return "TMCB_E2EACK_RETR_IN"; + case TMCB_RESPONSE_READY: + return "TMCB_RESPONSE_READY"; + case TMCB_DONT_ACK: + return "TMCB_DONT_ACK"; + case TMCB_REQUEST_SENT: + return "TMCB_REQUEST_SENT"; + case TMCB_RESPONSE_SENT: + return "TMCB_RESPONSE_SENT"; + case TMCB_ON_BRANCH_FAILURE: + return "TMCB_ON_BRANCH_FAILURE"; + case TMCB_ON_BRANCH_FAILURE_RO: + return "TMCB_ON_BRANCH_FAILURE_RO"; + case TMCB_MAX: + return "TMCB_MAX"; + } + + return "UNKNOWN"; } /* @@ -639,26 +659,29 @@ static inline char* tm_type_to_string(int type) { * \param h_id found dialog hash id * \return 0 on success, -1 on failure */ -static inline int parse_dlg_rr_param(char *p, char *end, int *h_entry, int *h_id) { - char *s; - - for (s = p; p < end && *p != DLG_SEPARATOR; p++); - if (*p != DLG_SEPARATOR) { - LM_ERR("malformed rr param '%.*s'\n", (int) (long) (end - s), s); - return -1; - } - - if (reverse_hex2int(s, p - s, (unsigned int*) h_entry) < 0) { - LM_ERR("invalid hash entry '%.*s'\n", (int) (long) (p - s), s); - return -1; - } - - if (reverse_hex2int(p + 1, end - (p + 1), (unsigned int*) h_id) < 0) { - LM_ERR("invalid hash id '%.*s'\n", (int) (long) (end - (p + 1)), p + 1); - return -1; - } - - return 0; +static inline int parse_dlg_rr_param( + char *p, char *end, int *h_entry, int *h_id) +{ + char *s; + + for(s = p; p < end && *p != DLG_SEPARATOR; p++) + ; + if(*p != DLG_SEPARATOR) { + LM_ERR("malformed rr param '%.*s'\n", (int)(long)(end - s), s); + return -1; + } + + if(reverse_hex2int(s, p - s, (unsigned int *)h_entry) < 0) { + LM_ERR("invalid hash entry '%.*s'\n", (int)(long)(p - s), s); + return -1; + } + + if(reverse_hex2int(p + 1, end - (p + 1), (unsigned int *)h_id) < 0) { + LM_ERR("invalid hash id '%.*s'\n", (int)(long)(end - (p + 1)), p + 1); + return -1; + } + + return 0; } /*! @@ -725,21 +748,24 @@ static inline int parse_dlg_rr_param(char *p, char *end, int *h_entry, int *h_id * \return 0 on success, -1 on failure */ static inline int update_cseqs(struct dlg_cell *dlg, struct sip_msg *req, - unsigned int dir, str *to_tag) { - if ((!req->cseq && parse_headers(req, HDR_CSEQ_F, 0) < 0) || !req->cseq || - !req->cseq->parsed) { - LM_ERR("bad sip message or missing CSeq hdr :-/\n"); - return -1; - } - - if (dir == DLG_DIR_UPSTREAM) { - return dlg_update_cseq(dlg, DLG_CALLEE_LEG, &((get_cseq(req))->number), to_tag); - } else if (dir == DLG_DIR_DOWNSTREAM) { - return dlg_update_cseq(dlg, DLG_CALLER_LEG, &((get_cseq(req))->number), to_tag); - } else { - LM_CRIT("dir is not set!\n"); - return -1; - } + unsigned int dir, str *to_tag) +{ + if((!req->cseq && parse_headers(req, HDR_CSEQ_F, 0) < 0) || !req->cseq + || !req->cseq->parsed) { + LM_ERR("bad sip message or missing CSeq hdr :-/\n"); + return -1; + } + + if(dir == DLG_DIR_UPSTREAM) { + return dlg_update_cseq( + dlg, DLG_CALLEE_LEG, &((get_cseq(req))->number), to_tag); + } else if(dir == DLG_DIR_DOWNSTREAM) { + return dlg_update_cseq( + dlg, DLG_CALLER_LEG, &((get_cseq(req))->number), to_tag); + } else { + LM_CRIT("dir is not set!\n"); + return -1; + } } /*! @@ -749,49 +775,52 @@ static inline int update_cseqs(struct dlg_cell *dlg, struct sip_msg *req, * \param type type of the entered callback * \param param saved dialog structure in the callback */ -void dlg_onreq(struct cell* t, int type, struct tmcb_params *param) { - sip_msg_t *req = param->req; - dlg_cell_t *dlg = NULL; - - if (req->first_line.u.request.method_value == METHOD_BYE) { - _dlg_ctx.t = 1; - return; - } - - if (req->first_line.u.request.method_value != METHOD_INVITE/* && req->first_line.u.request.method_value != METHOD_CANCEL*/) { - return; - } - - dlg = dlg_get_ctx_dialog(); - - if (dlg != NULL) { - if (spiral_detected == 1) { - LM_DBG("Running DLGB_SPIRALED callback\n"); - run_dlg_callbacks(DLGCB_SPIRALED, dlg, - req, NULL, DLG_DIR_DOWNSTREAM, 0); - LM_DBG("This is a spiraled REQUEST\n"); - } else if (spiral_detected == 0) - run_create_callbacks(dlg, req); - } - if (dlg == NULL) { - if ((req->flags & dlg_flag) != dlg_flag) - return; - LM_DBG("dialog creation on config flag\n"); - dlg_new_dialog(req, t, 1); - dlg = dlg_get_ctx_dialog(); - } - if (dlg != NULL) { - if (dlg_set_tm_callbacks(t, req, dlg, spiral_detected) !=0) { - LM_ERR("Failed to register TM Callbacks for dialog... this is bad!\n"); - //the DLG_TM flag will not be set so at least we can clear the dialog later... - } else { - LM_DBG("dialog [%p] added to tm callbacks\n", dlg); - } - _dlg_ctx.t = 1; - dlg_release(dlg); - } else { - LM_ERR("Failed to create dialog.... this is bad\n"); - } +void dlg_onreq(struct cell *t, int type, struct tmcb_params *param) +{ + sip_msg_t *req = param->req; + dlg_cell_t *dlg = NULL; + + if(req->first_line.u.request.method_value == METHOD_BYE) { + _dlg_ctx.t = 1; + return; + } + + if(req->first_line.u.request.method_value + != METHOD_INVITE /* && req->first_line.u.request.method_value != METHOD_CANCEL*/) { + return; + } + + dlg = dlg_get_ctx_dialog(); + + if(dlg != NULL) { + if(spiral_detected == 1) { + LM_DBG("Running DLGB_SPIRALED callback\n"); + run_dlg_callbacks( + DLGCB_SPIRALED, dlg, req, NULL, DLG_DIR_DOWNSTREAM, 0); + LM_DBG("This is a spiraled REQUEST\n"); + } else if(spiral_detected == 0) + run_create_callbacks(dlg, req); + } + if(dlg == NULL) { + if((req->flags & dlg_flag) != dlg_flag) + return; + LM_DBG("dialog creation on config flag\n"); + dlg_new_dialog(req, t, 1); + dlg = dlg_get_ctx_dialog(); + } + if(dlg != NULL) { + if(dlg_set_tm_callbacks(t, req, dlg, spiral_detected) != 0) { + LM_ERR("Failed to register TM Callbacks for dialog... this is " + "bad!\n"); + //the DLG_TM flag will not be set so at least we can clear the dialog later... + } else { + LM_DBG("dialog [%p] added to tm callbacks\n", dlg); + } + _dlg_ctx.t = 1; + dlg_release(dlg); + } else { + LM_ERR("Failed to create dialog.... this is bad\n"); + } } /*! @@ -805,340 +834,348 @@ void dlg_onreq(struct cell* t, int type, struct tmcb_params *param) { * \param route_params record-route parameter * \param param unused */ -void dlg_onroute(struct sip_msg* req, str *route_params, void *param) { - dlg_cell_t *dlg; - dlg_iuid_t *iuid; - str val, callid, ftag, ttag; - int h_entry, h_id, new_state, old_state, unref, event, timeout; - unsigned int dir; - int ret = 0; - int reset = 1; - - dlg = dlg_get_ctx_dialog(); - if (dlg != NULL) { - dlg_release(dlg); - return; - } - - /* skip initial requests - they may end up here because of the +void dlg_onroute(struct sip_msg *req, str *route_params, void *param) +{ + dlg_cell_t *dlg; + dlg_iuid_t *iuid; + str val, callid, ftag, ttag; + int h_entry, h_id, new_state, old_state, unref, event, timeout; + unsigned int dir; + int ret = 0; + int reset = 1; + + dlg = dlg_get_ctx_dialog(); + if(dlg != NULL) { + dlg_release(dlg); + return; + } + + /* skip initial requests - they may end up here because of the * preloaded route */ - if ((!req->to && parse_headers(req, HDR_TO_F, 0) < 0) || !req->to) { - LM_ERR("bad request or missing TO hdr :-/\n"); - return; - } - if (get_to(req)->tag_value.len == 0) { - LM_DBG("No to tag header found --- ignoring... MESSAGE [%.*s\n", req->first_line.u.request.method.len, req->first_line.u.request.method.s); - return; - } - - dlg = 0; - dir = DLG_DIR_NONE; - - if (seq_match_mode != SEQ_MATCH_NO_ID) { - if (d_rrb.get_route_param(req, &rr_param, &val) != 0) { - LM_DBG("Route param '%.*s' not found\n", rr_param.len, rr_param.s); - if (seq_match_mode == SEQ_MATCH_STRICT_ID) - return; - } else { - LM_DBG("route param is '%.*s' (len=%d)\n", val.len, val.s, val.len); - - if (parse_dlg_rr_param(val.s, val.s + val.len, &h_entry, &h_id) < 0) - return; - - dlg = lookup_dlg(h_entry, h_id); - if (dlg == 0) { - LM_WARN("unable to find dialog for %.*s " - "with route param '%.*s' [%u:%u]\n", - req->first_line.u.request.method.len, - req->first_line.u.request.method.s, - val.len, val.s, h_entry, h_id); - if (seq_match_mode == SEQ_MATCH_STRICT_ID) - return; - } else { - if (pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0) { - // lookup_dlg has incremented the ref count by 1 - unref_dlg(dlg, 1); - return; - } - if (match_dialog(dlg, &callid, &ftag, &ttag, &dir) == 0) { - LM_WARN("tight matching failed for %.*s with callid='%.*s'/%d, " - "ftag='%.*s'/%d, ttag='%.*s'/%d and direction=%d\n", - req->first_line.u.request.method.len, - req->first_line.u.request.method.s, - callid.len, callid.s, callid.len, - ftag.len, ftag.s, ftag.len, - ttag.len, ttag.s, ttag.len, dir); - LM_WARN("dialog identification elements are callid='%.*s'/%d, " - "caller tag='%.*s'/%d\n", - dlg->callid.len, dlg->callid.s, dlg->callid.len, - dlg->from_tag.len, dlg->from_tag.s, - dlg->from_tag.len); - // lookup_dlg has incremented the ref count by 1 - dlg_release(dlg); - - // Reset variables in order to do a lookup based on SIP-Elements. - dlg = 0; - dir = DLG_DIR_NONE; - - if (seq_match_mode == SEQ_MATCH_STRICT_ID) - return; - } - } - } - } - - if (dlg == 0) { - if (pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0) - return; - /* TODO - try to use the RR dir detection to speed up here the + if((!req->to && parse_headers(req, HDR_TO_F, 0) < 0) || !req->to) { + LM_ERR("bad request or missing TO hdr :-/\n"); + return; + } + if(get_to(req)->tag_value.len == 0) { + LM_DBG("No to tag header found --- ignoring... MESSAGE [%.*s\n", + req->first_line.u.request.method.len, + req->first_line.u.request.method.s); + return; + } + + dlg = 0; + dir = DLG_DIR_NONE; + + if(seq_match_mode != SEQ_MATCH_NO_ID) { + if(d_rrb.get_route_param(req, &rr_param, &val) != 0) { + LM_DBG("Route param '%.*s' not found\n", rr_param.len, rr_param.s); + if(seq_match_mode == SEQ_MATCH_STRICT_ID) + return; + } else { + LM_DBG("route param is '%.*s' (len=%d)\n", val.len, val.s, val.len); + + if(parse_dlg_rr_param(val.s, val.s + val.len, &h_entry, &h_id) < 0) + return; + + dlg = lookup_dlg(h_entry, h_id); + if(dlg == 0) { + LM_WARN("unable to find dialog for %.*s " + "with route param '%.*s' [%u:%u]\n", + req->first_line.u.request.method.len, + req->first_line.u.request.method.s, val.len, val.s, + h_entry, h_id); + if(seq_match_mode == SEQ_MATCH_STRICT_ID) + return; + } else { + if(pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0) { + // lookup_dlg has incremented the ref count by 1 + unref_dlg(dlg, 1); + return; + } + if(match_dialog(dlg, &callid, &ftag, &ttag, &dir) == 0) { + LM_WARN("tight matching failed for %.*s with " + "callid='%.*s'/%d, " + "ftag='%.*s'/%d, ttag='%.*s'/%d and direction=%d\n", + req->first_line.u.request.method.len, + req->first_line.u.request.method.s, callid.len, + callid.s, callid.len, ftag.len, ftag.s, ftag.len, + ttag.len, ttag.s, ttag.len, dir); + LM_WARN("dialog identification elements are " + "callid='%.*s'/%d, " + "caller tag='%.*s'/%d\n", + dlg->callid.len, dlg->callid.s, dlg->callid.len, + dlg->from_tag.len, dlg->from_tag.s, + dlg->from_tag.len); + // lookup_dlg has incremented the ref count by 1 + dlg_release(dlg); + + // Reset variables in order to do a lookup based on SIP-Elements. + dlg = 0; + dir = DLG_DIR_NONE; + + if(seq_match_mode == SEQ_MATCH_STRICT_ID) + return; + } + } + } + } + + if(dlg == 0) { + if(pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0) + return; + /* TODO - try to use the RR dir detection to speed up here the * search -bogdan */ - dlg = get_dlg(&callid, &ftag, &ttag, &dir); - if (!dlg) { - LM_DBG("Callid '%.*s' not found\n", - req->callid->body.len, req->callid->body.s); - return; - } - } - - /* set current dialog - re-use ref increment from dlg_get() above */ - set_current_dialog(req, dlg); - _dlg_ctx.iuid.h_entry = dlg->h_entry; - _dlg_ctx.iuid.h_id = dlg->h_id; - - if (req->first_line.u.request.method_value != METHOD_ACK) { - iuid = dlg_get_iuid_shm_clone(dlg); - if (iuid != NULL) { - /* register callback for the replies of this request */ - if (d_tmb.register_tmcb(req, 0, TMCB_RESPONSE_IN | TMCB_ON_FAILURE, - dlg_onreply, (void*) iuid, dlg_iuid_sfree) < 0) { - LM_ERR("failed to register TMCB (3)\n"); - shm_free(iuid); - } - iuid = NULL; - } - } - // if (d_tmb.register_tmcb(req, NULL, TMCB_REQUEST_FWDED, - // store_dlg_in_tm_cb, (void*) dlg, NULL) < 0) { - // LM_ERR("failed to store dialog in transaction during dialog creation for later reference\n"); - // } - - /* run state machine */ - switch (req->first_line.u.request.method_value) { - case METHOD_PRACK: - event = DLG_EVENT_REQPRACK; - break; - case METHOD_ACK: - event = DLG_EVENT_REQACK; - break; - case METHOD_BYE: - event = DLG_EVENT_REQBYE; - break; -// case METHOD_CANCEL: -// event = DLG_EVENT_REQCANCEL; -// break; - default: - event = DLG_EVENT_REQ; - } - - next_state_dlg(dlg, event, &old_state, &new_state, &unref, 0); - LM_DBG("unref after next state is %i\n", unref); - CURR_DLG_ID = req->id; - CURR_DLG_LIFETIME = (unsigned int) (time(0)) - dlg->start_ts; - CURR_DLG_STATUS = new_state; - - // dlg_run_event_route(dlg, req, old_state, new_state); - - /* delay deletion of dialog until transaction has died off in order + dlg = get_dlg(&callid, &ftag, &ttag, &dir); + if(!dlg) { + LM_DBG("Callid '%.*s' not found\n", req->callid->body.len, + req->callid->body.s); + return; + } + } + + /* set current dialog - re-use ref increment from dlg_get() above */ + set_current_dialog(req, dlg); + _dlg_ctx.iuid.h_entry = dlg->h_entry; + _dlg_ctx.iuid.h_id = dlg->h_id; + + if(req->first_line.u.request.method_value != METHOD_ACK) { + iuid = dlg_get_iuid_shm_clone(dlg); + if(iuid != NULL) { + /* register callback for the replies of this request */ + if(d_tmb.register_tmcb(req, 0, TMCB_RESPONSE_IN | TMCB_ON_FAILURE, + dlg_onreply, (void *)iuid, dlg_iuid_sfree) + < 0) { + LM_ERR("failed to register TMCB (3)\n"); + shm_free(iuid); + } + iuid = NULL; + } + } + // if (d_tmb.register_tmcb(req, NULL, TMCB_REQUEST_FWDED, + // store_dlg_in_tm_cb, (void*) dlg, NULL) < 0) { + // LM_ERR("failed to store dialog in transaction during dialog creation for later reference\n"); + // } + + /* run state machine */ + switch(req->first_line.u.request.method_value) { + case METHOD_PRACK: + event = DLG_EVENT_REQPRACK; + break; + case METHOD_ACK: + event = DLG_EVENT_REQACK; + break; + case METHOD_BYE: + event = DLG_EVENT_REQBYE; + break; + // case METHOD_CANCEL: + // event = DLG_EVENT_REQCANCEL; + // break; + default: + event = DLG_EVENT_REQ; + } + + next_state_dlg(dlg, event, &old_state, &new_state, &unref, 0); + LM_DBG("unref after next state is %i\n", unref); + CURR_DLG_ID = req->id; + CURR_DLG_LIFETIME = (unsigned int)(time(0)) - dlg->start_ts; + CURR_DLG_STATUS = new_state; + + // dlg_run_event_route(dlg, req, old_state, new_state); + + /* delay deletion of dialog until transaction has died off in order * to absorb in-air messages */ - if ((new_state == DLG_STATE_DELETED) && (old_state != DLG_STATE_DELETED)) { - iuid = dlg_get_iuid_shm_clone(dlg); - if (iuid != NULL) { - if (d_tmb.register_tmcb(req, NULL, TMCB_DESTROY, - unref_dlg_from_cb, (void*) iuid, dlg_iuid_sfree) < 0) { - LM_ERR("failed to register deletion delay function\n"); - shm_free(iuid); - } else { - ref_dlg(dlg, 1); - } - } -// unref_dlg(dlg, unref); - } - - // if (new_state == DLG_STATE_CONFIRMED && old_state != DLG_STATE_CONFIRMED) - // dlg_ka_add(dlg); - - if (event == DLG_EVENT_REQCANCEL && new_state == DLG_STATE_DELETED && - old_state != DLG_STATE_DELETED) { - LM_DBG("CANCEL successfully processed and old state was [%d]\n", old_state); - - ret = remove_dialog_timer(&dlg->tl); - if (ret < 0) { - LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else if (ret > 0) { - LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s' \n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else { - unref++; - } - - dlg_terminated(req, dlg, dir); - unref_dlg(dlg, unref); - _dlg_ctx.cpid = my_pid(); - _dlg_ctx.expect_t = 1; - dlg_set_ctx_iuid(dlg); - - if (old_state == DLG_STATE_EARLY) { - counter_add(dialog_ng_cnts_h.early, -1); - } else if (old_state == DLG_STATE_CONFIRMED ||old_state == DLG_STATE_CONFIRMED_NA) { - counter_add(dialog_ng_cnts_h.active, -1); - } - - goto done; - } - - /* run actions for the transition */ - if (event == DLG_EVENT_REQBYE && new_state == DLG_STATE_DELETED && - old_state != DLG_STATE_DELETED) { - LM_DBG("BYE successfully processed\n"); - /* remove from timer */ - ret = remove_dialog_timer(&dlg->tl); - if (ret < 0) { - LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else if (ret > 0) { - LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s' \n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else { - unref++; - } - /* dialog terminated (BYE) */ - dlg_terminated(req, dlg, dir); - unref_dlg(dlg, unref); - _dlg_ctx.cpid = my_pid(); - _dlg_ctx.expect_t = 1; - dlg_set_ctx_iuid(dlg); - - if (old_state == DLG_STATE_CONFIRMED ||old_state == DLG_STATE_CONFIRMED_NA) { - counter_add(dialog_ng_cnts_h.active, -1); - } - - goto done; - } - - if (event == DLG_EVENT_REQCANCEL && new_state == DLG_STATE_DELETED && - old_state != DLG_STATE_DELETED) { - LM_DBG("CANCEL successfully processed\n"); - /* remove from timer */ - ret = remove_dialog_timer(&dlg->tl); - if (ret < 0) { - LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else if (ret > 0) { - LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s' \n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else { - unref++; - } - /* dialog terminated (CANCEL) */ - dlg_cancelled(req, dlg, dir); -// unref_dlg(dlg, unref); - _dlg_ctx.cpid = my_pid(); - _dlg_ctx.expect_t = 1; - dlg_set_ctx_iuid(dlg); - counter_add(dialog_ng_cnts_h.early, -1); - goto done; - } - - if ((event == DLG_EVENT_REQ || event == DLG_EVENT_REQACK) - && (new_state == DLG_STATE_CONFIRMED || new_state == DLG_STATE_EARLY)) { - - if (event != DLG_EVENT_REQACK) { - if (update_cseqs(dlg, req, dir, &ttag) != 0) { - LM_ERR("cseqs update failed\n"); - } else { - dlg->dflags |= DLG_FLAG_CHANGED; - } - } - if (dlg_db_mode == DB_MODE_REALTIME && (dlg->dflags & DLG_FLAG_CHANGED)) { - update_dialog_dbinfo(dlg); - } - - if (old_state == DLG_STATE_CONFIRMED_NA) { - LM_DBG("confirming ACK successfully processed\n"); - - /* confirming ACK request */ - run_dlg_callbacks(DLGCB_CONFIRMED, dlg, req, NULL, dir, 0); - } else { - LM_DBG("sequential request successfully processed\n"); - - /* within dialog request */ - run_dlg_callbacks(DLGCB_REQ_WITHIN, dlg, req, NULL, dir, 0); - - if ((event != DLG_EVENT_REQACK) && - (dlg->cbs.types) & DLGCB_RESPONSE_WITHIN) { - iuid = dlg_get_iuid_shm_clone(dlg); - if (iuid != NULL) { - /* register callback for the replies of this request */ - if (d_tmb.register_tmcb(req, 0, TMCB_RESPONSE_FWDED, - (dir == DLG_DIR_UPSTREAM) ? dlg_seq_down_onreply : - dlg_seq_up_onreply, - (void*) iuid, dlg_iuid_sfree) < 0) { - LM_ERR("failed to register TMCB (2)\n"); - shm_free(iuid); - } - } - } - } - - timeout = get_dlg_timeout(req); - if (timeout != default_timeout) { - dlg->lifetime = timeout; - } - // reset = !((dlg->iflags & DLG_IFLAG_TIMER_NORESET) || dlg_timeout_noreset); - - if ((new_state != DLG_STATE_EARLY) && (old_state != DLG_STATE_CONFIRMED || reset)) { - if (update_dlg_timer(&dlg->tl, dlg->lifetime) == -1) { - LM_ERR("failed to update dialog lifetime\n"); - } else { - dlg->dflags |= DLG_FLAG_CHANGED; - } - } - } - - if (new_state == DLG_STATE_CONFIRMED && old_state == DLG_STATE_CONFIRMED_NA) { - dlg->dflags |= DLG_FLAG_CHANGED; - if (dlg_db_mode == DB_MODE_REALTIME) - update_dialog_dbinfo(dlg); - } + if((new_state == DLG_STATE_DELETED) && (old_state != DLG_STATE_DELETED)) { + iuid = dlg_get_iuid_shm_clone(dlg); + if(iuid != NULL) { + if(d_tmb.register_tmcb(req, NULL, TMCB_DESTROY, unref_dlg_from_cb, + (void *)iuid, dlg_iuid_sfree) + < 0) { + LM_ERR("failed to register deletion delay function\n"); + shm_free(iuid); + } else { + ref_dlg(dlg, 1); + } + } + // unref_dlg(dlg, unref); + } + + // if (new_state == DLG_STATE_CONFIRMED && old_state != DLG_STATE_CONFIRMED) + // dlg_ka_add(dlg); + + if(event == DLG_EVENT_REQCANCEL && new_state == DLG_STATE_DELETED + && old_state != DLG_STATE_DELETED) { + LM_DBG("CANCEL successfully processed and old state was [%d]\n", + old_state); + + ret = remove_dialog_timer(&dlg->tl); + if(ret < 0) { + LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else if(ret > 0) { + LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s' \n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else { + unref++; + } + + dlg_terminated(req, dlg, dir); + unref_dlg(dlg, unref); + _dlg_ctx.cpid = my_pid(); + _dlg_ctx.expect_t = 1; + dlg_set_ctx_iuid(dlg); + + if(old_state == DLG_STATE_EARLY) { + counter_add(dialog_ng_cnts_h.early, -1); + } else if(old_state == DLG_STATE_CONFIRMED + || old_state == DLG_STATE_CONFIRMED_NA) { + counter_add(dialog_ng_cnts_h.active, -1); + } + + goto done; + } + + /* run actions for the transition */ + if(event == DLG_EVENT_REQBYE && new_state == DLG_STATE_DELETED + && old_state != DLG_STATE_DELETED) { + LM_DBG("BYE successfully processed\n"); + /* remove from timer */ + ret = remove_dialog_timer(&dlg->tl); + if(ret < 0) { + LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else if(ret > 0) { + LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s' \n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else { + unref++; + } + /* dialog terminated (BYE) */ + dlg_terminated(req, dlg, dir); + unref_dlg(dlg, unref); + _dlg_ctx.cpid = my_pid(); + _dlg_ctx.expect_t = 1; + dlg_set_ctx_iuid(dlg); + + if(old_state == DLG_STATE_CONFIRMED + || old_state == DLG_STATE_CONFIRMED_NA) { + counter_add(dialog_ng_cnts_h.active, -1); + } + + goto done; + } + + if(event == DLG_EVENT_REQCANCEL && new_state == DLG_STATE_DELETED + && old_state != DLG_STATE_DELETED) { + LM_DBG("CANCEL successfully processed\n"); + /* remove from timer */ + ret = remove_dialog_timer(&dlg->tl); + if(ret < 0) { + LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else if(ret > 0) { + LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s' \n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); + + } else { + unref++; + } + /* dialog terminated (CANCEL) */ + dlg_cancelled(req, dlg, dir); + // unref_dlg(dlg, unref); + _dlg_ctx.cpid = my_pid(); + _dlg_ctx.expect_t = 1; + dlg_set_ctx_iuid(dlg); + counter_add(dialog_ng_cnts_h.early, -1); + goto done; + } + + if((event == DLG_EVENT_REQ || event == DLG_EVENT_REQACK) + && (new_state == DLG_STATE_CONFIRMED + || new_state == DLG_STATE_EARLY)) { + + if(event != DLG_EVENT_REQACK) { + if(update_cseqs(dlg, req, dir, &ttag) != 0) { + LM_ERR("cseqs update failed\n"); + } else { + dlg->dflags |= DLG_FLAG_CHANGED; + } + } + if(dlg_db_mode == DB_MODE_REALTIME + && (dlg->dflags & DLG_FLAG_CHANGED)) { + update_dialog_dbinfo(dlg); + } + + if(old_state == DLG_STATE_CONFIRMED_NA) { + LM_DBG("confirming ACK successfully processed\n"); + + /* confirming ACK request */ + run_dlg_callbacks(DLGCB_CONFIRMED, dlg, req, NULL, dir, 0); + } else { + LM_DBG("sequential request successfully processed\n"); + + /* within dialog request */ + run_dlg_callbacks(DLGCB_REQ_WITHIN, dlg, req, NULL, dir, 0); + + if((event != DLG_EVENT_REQACK) + && (dlg->cbs.types) & DLGCB_RESPONSE_WITHIN) { + iuid = dlg_get_iuid_shm_clone(dlg); + if(iuid != NULL) { + /* register callback for the replies of this request */ + if(d_tmb.register_tmcb(req, 0, TMCB_RESPONSE_FWDED, + (dir == DLG_DIR_UPSTREAM) ? dlg_seq_down_onreply + : dlg_seq_up_onreply, + (void *)iuid, dlg_iuid_sfree) + < 0) { + LM_ERR("failed to register TMCB (2)\n"); + shm_free(iuid); + } + } + } + } + + timeout = get_dlg_timeout(req); + if(timeout != default_timeout) { + dlg->lifetime = timeout; + } + // reset = !((dlg->iflags & DLG_IFLAG_TIMER_NORESET) || dlg_timeout_noreset); + + if((new_state != DLG_STATE_EARLY) + && (old_state != DLG_STATE_CONFIRMED || reset)) { + if(update_dlg_timer(&dlg->tl, dlg->lifetime) == -1) { + LM_ERR("failed to update dialog lifetime\n"); + } else { + dlg->dflags |= DLG_FLAG_CHANGED; + } + } + } + + if(new_state == DLG_STATE_CONFIRMED + && old_state == DLG_STATE_CONFIRMED_NA) { + dlg->dflags |= DLG_FLAG_CHANGED; + if(dlg_db_mode == DB_MODE_REALTIME) + update_dialog_dbinfo(dlg); + } done: - dlg_release(dlg); - return; + dlg_release(dlg); + return; } /*! @@ -1153,356 +1190,390 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) { * \param type type of the entered callback * \param param saved dialog structure in the callback */ -void dlg_onreply(struct cell* t, int type, struct tmcb_params *param) { - dlg_cell_t *dlg = NULL; - dlg_iuid_t *iuid = NULL; - struct dlg_cell_out *dlg_out = 0; - char *event_s = 0; - - int new_state, old_state, unref, event; - str to_tag={0,0}, to_uri={0,0}, branch={0,0}; - struct sip_msg *req = param->req; - struct sip_msg *rpl = param->rpl; - struct dlg_entry_out* dlg_entry_out = 0; - - char* cb_type_s = tm_type_to_string(type); - - if (t && t->fwded_totags) +void dlg_onreply(struct cell *t, int type, struct tmcb_params *param) +{ + dlg_cell_t *dlg = NULL; + dlg_iuid_t *iuid = NULL; + struct dlg_cell_out *dlg_out = 0; + char *event_s = 0; + + int new_state, old_state, unref, event; + str to_tag = {0, 0}, to_uri = {0, 0}, branch = {0, 0}; + struct sip_msg *req = param->req; + struct sip_msg *rpl = param->rpl; + struct dlg_entry_out *dlg_entry_out = 0; + + char *cb_type_s = tm_type_to_string(type); + + if(t && t->fwded_totags) LM_DBG("ONREPLY CALL_BACK from TM received and type is [%i] = [%s]" - " and TO is [%.*s]\n", type, cb_type_s, t->fwded_totags->tag.len, + " and TO is [%.*s]\n", + type, cb_type_s, t->fwded_totags->tag.len, t->fwded_totags->tag.s); - else - LM_DBG("ONREPLY CALL_BACK from TM received and type is [%i] = [%s]\n", - type, cb_type_s); - - if (shutdown_done) - return; - - iuid = (dlg_iuid_t*) (*param->param); - dlg = dlg_get_by_iuid(iuid); - if (dlg == 0) - return; - - if (t) { - dlg->transaction = t; - } - - unref = 0; - - LM_DBG("DLG dialogid is entry:id [%i:%i]\n", dlg->h_entry, dlg->h_id); - - if (type & TMCB_E2ECANCEL_IN) { - LM_DBG("Received CANCEL...\n"); - goto done; - } - - if (type & TMCB_REQUEST_OUT) { - LM_DBG("Received Request out for request [%.*s]\n", param->send_buf.len, param->send_buf.s); - if (param->send_buf.s && (param->send_buf.len > 6) && !memcmp(param->send_buf.s, "CANCEL", 6)) { - LM_DBG("Request out sending CANCEL...\n"); - type = TMCB_E2ECANCEL_IN; - goto done; - } else { - LM_DBG("Ignoring request out as it's not a CANCEL\n"); - goto done; - } - } - - if (type & (TMCB_RESPONSE_IN | TMCB_ON_FAILURE)) { - /* Set the dialog context so it is available in onreply_route and failure_route*/ - set_current_dialog(req, dlg); - dlg_set_ctx_iuid(dlg); - goto done; - } - - if (type == TMCB_RESPONSE_FWDED) { - // The state does not change, but the msg is mutable in this callback - LM_DBG("TMCB_RESPONSE_FWDED from TM received"); - run_dlg_callbacks(DLGCB_RESPONSE_FWDED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - goto done; - } - - if (type == TMCB_RESPONSE_READY) { - if (rpl == FAKED_REPLY) { - LM_DBG("Faked reply\n"); - //TODO - maybe we should run the state machine especially for things like cancel (ie early dialog.....) - to_tag.s = 0; - to_tag.len = 0; -// goto done; - } else { - // get to tag - LM_DBG("Extracting to-tag from reply"); - if (!rpl->to && ((parse_headers(rpl, HDR_TO_F, 0) < 0) || !rpl->to)) { - LM_DBG("bad reply or missing TO hdr :-/\n"); - to_tag.s = 0; - to_tag.len = 0; - } else { - //populate to uri for this branch. - to_uri = get_to(rpl)->uri; - - to_tag = get_to(rpl)->tag_value; - if (to_tag.s == 0 || to_tag.len == 0) { - LM_DBG("missing TAG param in TO hdr :-/\n"); - to_tag.s = 0; - to_tag.len = 0; - //Here we assume that the transaction module timer will remove any early dialogs - //return; if we leave this then we have over-reffed dialogs - } - } - } - - LM_DBG("Got to-tag from response: %.*s \n", to_tag.len, to_tag.s); - } - - if (type == TMCB_DESTROY) { - event = DLG_EVENT_TDEL; - event_s = "DLG_EVENT_TDEL"; -// } else if (type == TMCB_E2ECANCEL_IN) { -// event = DLG_EVENT_REQCANCEL; -// event_s = "DLG_EVENT_REQCANCEL"; - } else if (param->code < 200) { - event = DLG_EVENT_RPL1xx; - event_s = "DLG_EVENT_RPL1xx"; - } else if (param->code < 300) { - event = DLG_EVENT_RPL2xx; - event_s = "DLG_EVENT_RPL2xx"; - } else { - event = DLG_EVENT_RPL3xx; - event_s = "DLG_EVENT_RPL3xx"; - } - - LM_DBG("Calling next_state_dlg and event is %i = %s\n", event, event_s); - next_state_dlg(dlg, event, &old_state, &new_state, &unref, &to_tag); - - if (type == TMCB_RESPONSE_READY) { - LM_DBG("Checking if there is an existing dialog_out entry with same to-tag"); - if (rpl == FAKED_REPLY) { - LM_DBG("Faked reply\n"); - - if (new_state == DLG_STATE_DELETED - && (old_state == DLG_STATE_UNCONFIRMED - || old_state == DLG_STATE_EARLY)) { - LM_DBG("dialog %p failed (negative reply)\n", dlg); - /* dialog setup not completed (3456XX) */ - run_dlg_callbacks(DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - /* do unref */ - if (unref) - unref_dlg(dlg, unref); - - if (old_state == DLG_STATE_EARLY) - counter_add(dialog_ng_cnts_h.early, -1); - } - goto done; - } - - // get to tag - LM_DBG("Extracting to-tag from reply"); - if (rpl == FAKED_REPLY || (!rpl->to && ((parse_headers(rpl, HDR_TO_F, 0) < 0) || !rpl->to))) { - LM_ERR("faked reply or bad reply or missing TO hdr :-/\n"); - to_tag.s = 0; - to_tag.len = 0; - } else { - //populate to uri for this branch. - to_uri = get_to(rpl)->uri; - - to_tag = get_to(rpl)->tag_value; - if (to_tag.s == 0 || to_tag.len == 0) { - LM_DBG("missing TAG param in TO hdr :-/ - probably a failure response\n"); - to_tag.s = 0; - to_tag.len = 0; - //Here we assume that the transaction module timer will remove any early dialogs - if (new_state == DLG_STATE_DELETED - && (old_state == DLG_STATE_UNCONFIRMED - || old_state == DLG_STATE_EARLY)) { - LM_DBG("dialog %p failed (negative reply)\n", dlg); - /* dialog setup not completed (3456XX) */ - run_dlg_callbacks(DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - /* do unref */ - if (unref) - unref_dlg(dlg, unref); - - if (old_state == DLG_STATE_EARLY) - counter_add(dialog_ng_cnts_h.early, -1); - } - goto done; - } - } - LM_DBG("Got to-tag from response: %.*s \n", to_tag.len, to_tag.s); - - dlg_entry_out = &dlg->dlg_entry_out; - - lock_get(dlg->dlg_out_entries_lock); - dlg_out = dlg_entry_out->first; - - LM_DBG("Scanning dlg_entry_out list for dlg_out"); - while (dlg_out) { - //Check if there is an already dialog_out entry with same To-tag - if (dlg_out->to_tag.len == to_tag.len && - memcmp(dlg_out->to_tag.s, to_tag.s, dlg_out->to_tag.len) == 0) { - //Found a dialog_out entry with same to_tag! - LM_DBG("Found dlg_out for to-tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s); - break; - } - dlg_out = dlg_out->next; - } - lock_release(dlg->dlg_out_entries_lock); - - if (!dlg_out) { - if (rpl->first_line.u.reply.statuscode < 299) { /*we don't care about failure responses to dialog - not necessary to create dialog out...*/ - if (rpl->via1->branch && (rpl->via1->branch->value.s) && (rpl->via1->branch->value.len > 0)) { - branch = rpl->via1->branch->value; - } - - LM_DBG("No dlg_out entry found - creating a new dialog_out entry on dialog [%p]\n", dlg); - dlg_out = build_new_dlg_out(dlg, &to_uri, &to_tag, &branch); - - link_dlg_out(dlg, dlg_out, 0); - - /* save callee's cseq, caller cseq, callee contact and callee record route*/ - if (populate_leg_info(dlg, rpl, t, DLG_CALLEE_LEG, &to_tag) != 0) { - LM_ERR("could not add further info to the dlg out\n"); - } - - if (!dlg_out) { - LM_ERR("failed to create new dialog out structure\n"); - goto done; - //TODO do something on this error! - - } - } - } else { - //This dlg_out already exists, update cseq and contact if present - - LM_DBG("dlg_out entry found - updating cseq's for dialog out [%p] for to-tag [%.*s] \n", dlg_out, dlg_out->to_tag.len, dlg_out->to_tag.s); - - if ((!rpl->cseq && parse_headers(rpl, HDR_CSEQ_F, 0) < 0) || !rpl->cseq || - !rpl->cseq->parsed) { - LM_ERR("bad sip message or missing CSeq hdr :-/\n"); - } - dlg_update_cseq(dlg, DLG_CALLEE_LEG, &((get_cseq(rpl))->number), &(dlg_out->to_tag)); - - - /* extract the contact address to update if present*/ - if (!rpl->contact && (parse_headers(rpl, HDR_CONTACT_F, 0) < 0 || !rpl->contact)) { - LM_DBG("Can not update callee contact: bad sip message or missing Contact hdr\n"); - } else if (parse_contact(rpl->contact) < 0 || - ((contact_body_t *) rpl->contact->parsed)->contacts == NULL || - ((contact_body_t *) rpl->contact->parsed)->contacts->next != NULL) { - LM_ERR("Can not update callee contact: bad Contact HDR\n"); - } else { - str contact; - contact = ((contact_body_t *) rpl->contact->parsed)->contacts->uri; - dlg_update_contact(dlg, DLG_CALLEE_LEG, &contact, &(dlg_out->to_tag)); - } - } - } - if (new_state == DLG_STATE_EARLY) { - if (dlg_db_mode == DB_MODE_REALTIME) - update_dialog_dbinfo(dlg); - run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - if (old_state != DLG_STATE_EARLY) - counter_inc(dialog_ng_cnts_h.early); - goto done; - } - - LM_DBG("new state is %i and old state is %i\n", new_state, old_state); - - if (new_state == DLG_STATE_CONFIRMED_NA && - old_state != DLG_STATE_CONFIRMED_NA && old_state != DLG_STATE_CONFIRMED) { - // if ((new_state == DLG_STATE_CONFIRMED) && (event == DLG_EVENT_RPL2xx)) { - LM_DBG("dialog %p confirmed (No Ack) \n", dlg); - - /* set start time */ - dlg->start_ts = (unsigned int) (time(0)); - - /* save the settings to the database, + else + LM_DBG("ONREPLY CALL_BACK from TM received and type is [%i] = [%s]\n", + type, cb_type_s); + + if(shutdown_done) + return; + + iuid = (dlg_iuid_t *)(*param->param); + dlg = dlg_get_by_iuid(iuid); + if(dlg == 0) + return; + + if(t) { + dlg->transaction = t; + } + + unref = 0; + + LM_DBG("DLG dialogid is entry:id [%i:%i]\n", dlg->h_entry, dlg->h_id); + + if(type & TMCB_E2ECANCEL_IN) { + LM_DBG("Received CANCEL...\n"); + goto done; + } + + if(type & TMCB_REQUEST_OUT) { + LM_DBG("Received Request out for request [%.*s]\n", param->send_buf.len, + param->send_buf.s); + if(param->send_buf.s && (param->send_buf.len > 6) + && !memcmp(param->send_buf.s, "CANCEL", 6)) { + LM_DBG("Request out sending CANCEL...\n"); + type = TMCB_E2ECANCEL_IN; + goto done; + } else { + LM_DBG("Ignoring request out as it's not a CANCEL\n"); + goto done; + } + } + + if(type & (TMCB_RESPONSE_IN | TMCB_ON_FAILURE)) { + /* Set the dialog context so it is available in onreply_route and failure_route*/ + set_current_dialog(req, dlg); + dlg_set_ctx_iuid(dlg); + goto done; + } + + if(type == TMCB_RESPONSE_FWDED) { + // The state does not change, but the msg is mutable in this callback + LM_DBG("TMCB_RESPONSE_FWDED from TM received"); + run_dlg_callbacks( + DLGCB_RESPONSE_FWDED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + goto done; + } + + if(type == TMCB_RESPONSE_READY) { + if(rpl == FAKED_REPLY) { + LM_DBG("Faked reply\n"); + //TODO - maybe we should run the state machine especially for things like cancel (ie early dialog.....) + to_tag.s = 0; + to_tag.len = 0; + // goto done; + } else { + // get to tag + LM_DBG("Extracting to-tag from reply"); + if(!rpl->to + && ((parse_headers(rpl, HDR_TO_F, 0) < 0) || !rpl->to)) { + LM_DBG("bad reply or missing TO hdr :-/\n"); + to_tag.s = 0; + to_tag.len = 0; + } else { + //populate to uri for this branch. + to_uri = get_to(rpl)->uri; + + to_tag = get_to(rpl)->tag_value; + if(to_tag.s == 0 || to_tag.len == 0) { + LM_DBG("missing TAG param in TO hdr :-/\n"); + to_tag.s = 0; + to_tag.len = 0; + //Here we assume that the transaction module timer will remove any early dialogs + //return; if we leave this then we have over-reffed dialogs + } + } + } + + LM_DBG("Got to-tag from response: %.*s \n", to_tag.len, to_tag.s); + } + + if(type == TMCB_DESTROY) { + event = DLG_EVENT_TDEL; + event_s = "DLG_EVENT_TDEL"; + // } else if (type == TMCB_E2ECANCEL_IN) { + // event = DLG_EVENT_REQCANCEL; + // event_s = "DLG_EVENT_REQCANCEL"; + } else if(param->code < 200) { + event = DLG_EVENT_RPL1xx; + event_s = "DLG_EVENT_RPL1xx"; + } else if(param->code < 300) { + event = DLG_EVENT_RPL2xx; + event_s = "DLG_EVENT_RPL2xx"; + } else { + event = DLG_EVENT_RPL3xx; + event_s = "DLG_EVENT_RPL3xx"; + } + + LM_DBG("Calling next_state_dlg and event is %i = %s\n", event, event_s); + next_state_dlg(dlg, event, &old_state, &new_state, &unref, &to_tag); + + if(type == TMCB_RESPONSE_READY) { + LM_DBG("Checking if there is an existing dialog_out entry with same " + "to-tag"); + if(rpl == FAKED_REPLY) { + LM_DBG("Faked reply\n"); + + if(new_state == DLG_STATE_DELETED + && (old_state == DLG_STATE_UNCONFIRMED + || old_state == DLG_STATE_EARLY)) { + LM_DBG("dialog %p failed (negative reply)\n", dlg); + /* dialog setup not completed (3456XX) */ + run_dlg_callbacks( + DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + /* do unref */ + if(unref) + unref_dlg(dlg, unref); + + if(old_state == DLG_STATE_EARLY) + counter_add(dialog_ng_cnts_h.early, -1); + } + goto done; + } + + // get to tag + LM_DBG("Extracting to-tag from reply"); + if(rpl == FAKED_REPLY + || (!rpl->to + && ((parse_headers(rpl, HDR_TO_F, 0) < 0) + || !rpl->to))) { + LM_ERR("faked reply or bad reply or missing TO hdr :-/\n"); + to_tag.s = 0; + to_tag.len = 0; + } else { + //populate to uri for this branch. + to_uri = get_to(rpl)->uri; + + to_tag = get_to(rpl)->tag_value; + if(to_tag.s == 0 || to_tag.len == 0) { + LM_DBG("missing TAG param in TO hdr :-/ - probably a failure " + "response\n"); + to_tag.s = 0; + to_tag.len = 0; + //Here we assume that the transaction module timer will remove any early dialogs + if(new_state == DLG_STATE_DELETED + && (old_state == DLG_STATE_UNCONFIRMED + || old_state == DLG_STATE_EARLY)) { + LM_DBG("dialog %p failed (negative reply)\n", dlg); + /* dialog setup not completed (3456XX) */ + run_dlg_callbacks( + DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + /* do unref */ + if(unref) + unref_dlg(dlg, unref); + + if(old_state == DLG_STATE_EARLY) + counter_add(dialog_ng_cnts_h.early, -1); + } + goto done; + } + } + LM_DBG("Got to-tag from response: %.*s \n", to_tag.len, to_tag.s); + + dlg_entry_out = &dlg->dlg_entry_out; + + lock_get(dlg->dlg_out_entries_lock); + dlg_out = dlg_entry_out->first; + + LM_DBG("Scanning dlg_entry_out list for dlg_out"); + while(dlg_out) { + //Check if there is an already dialog_out entry with same To-tag + if(dlg_out->to_tag.len == to_tag.len + && memcmp(dlg_out->to_tag.s, to_tag.s, dlg_out->to_tag.len) + == 0) { + //Found a dialog_out entry with same to_tag! + LM_DBG("Found dlg_out for to-tag: %.*s\n", dlg_out->to_tag.len, + dlg_out->to_tag.s); + break; + } + dlg_out = dlg_out->next; + } + lock_release(dlg->dlg_out_entries_lock); + + if(!dlg_out) { + if(rpl->first_line.u.reply.statuscode + < 299) { /*we don't care about failure responses to dialog - not necessary to create dialog out...*/ + if(rpl->via1->branch && (rpl->via1->branch->value.s) + && (rpl->via1->branch->value.len > 0)) { + branch = rpl->via1->branch->value; + } + + LM_DBG("No dlg_out entry found - creating a new dialog_out " + "entry on dialog [%p]\n", + dlg); + dlg_out = build_new_dlg_out(dlg, &to_uri, &to_tag, &branch); + + link_dlg_out(dlg, dlg_out, 0); + + /* save callee's cseq, caller cseq, callee contact and callee record route*/ + if(populate_leg_info(dlg, rpl, t, DLG_CALLEE_LEG, &to_tag) + != 0) { + LM_ERR("could not add further info to the dlg out\n"); + } + + if(!dlg_out) { + LM_ERR("failed to create new dialog out structure\n"); + goto done; + //TODO do something on this error! + } + } + } else { + //This dlg_out already exists, update cseq and contact if present + + LM_DBG("dlg_out entry found - updating cseq's for dialog out [%p] " + "for to-tag [%.*s] \n", + dlg_out, dlg_out->to_tag.len, dlg_out->to_tag.s); + + if((!rpl->cseq && parse_headers(rpl, HDR_CSEQ_F, 0) < 0) + || !rpl->cseq || !rpl->cseq->parsed) { + LM_ERR("bad sip message or missing CSeq hdr :-/\n"); + } + dlg_update_cseq(dlg, DLG_CALLEE_LEG, &((get_cseq(rpl))->number), + &(dlg_out->to_tag)); + + + /* extract the contact address to update if present*/ + if(!rpl->contact + && (parse_headers(rpl, HDR_CONTACT_F, 0) < 0 + || !rpl->contact)) { + LM_DBG("Can not update callee contact: bad sip message or " + "missing Contact hdr\n"); + } else if(parse_contact(rpl->contact) < 0 + || ((contact_body_t *)rpl->contact->parsed)->contacts + == NULL + || ((contact_body_t *)rpl->contact->parsed) + ->contacts->next + != NULL) { + LM_ERR("Can not update callee contact: bad Contact HDR\n"); + } else { + str contact; + contact = + ((contact_body_t *)rpl->contact->parsed)->contacts->uri; + dlg_update_contact( + dlg, DLG_CALLEE_LEG, &contact, &(dlg_out->to_tag)); + } + } + } + if(new_state == DLG_STATE_EARLY) { + if(dlg_db_mode == DB_MODE_REALTIME) + update_dialog_dbinfo(dlg); + run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + if(old_state != DLG_STATE_EARLY) + counter_inc(dialog_ng_cnts_h.early); + goto done; + } + + LM_DBG("new state is %i and old state is %i\n", new_state, old_state); + + if(new_state == DLG_STATE_CONFIRMED_NA + && old_state != DLG_STATE_CONFIRMED_NA + && old_state != DLG_STATE_CONFIRMED) { + // if ((new_state == DLG_STATE_CONFIRMED) && (event == DLG_EVENT_RPL2xx)) { + LM_DBG("dialog %p confirmed (No Ack) \n", dlg); + + /* set start time */ + dlg->start_ts = (unsigned int)(time(0)); + + /* save the settings to the database, * if realtime saving mode configured- save dialog now * else: the next time the timer will fire the update*/ - if ((dlg->dflags & DLG_FLAG_INSERTED) == 0) { - dlg->dflags |= DLG_FLAG_NEW; - } else { - dlg->dflags |= DLG_FLAG_CHANGED; - } - if (dlg_db_mode == DB_MODE_REALTIME) - update_dialog_dbinfo(dlg); - - if (0 != insert_dlg_timer(&dlg->tl, dlg->lifetime)) { - LM_CRIT("Unable to insert dlg %p [%u:%u] on event %d [%d->%d] " - "with clid '%.*s' and tags '%.*s' \n", - dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - } else { - ref_dlg(dlg, 1); - } - - /* dialog confirmed (ACK pending) */ - run_dlg_callbacks(DLGCB_CONFIRMED_NA, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - - if (old_state == DLG_STATE_EARLY) - counter_add(dialog_ng_cnts_h.early, -1); - - if (unref) unref_dlg(dlg, unref); - - counter_inc(dialog_ng_cnts_h.active); - - goto done; - } - - if (new_state == DLG_STATE_CONCURRENTLY_CONFIRMED && (old_state == DLG_STATE_CONFIRMED || old_state == DLG_STATE_CONCURRENTLY_CONFIRMED)) { - //This is a concurrently confirmed call - LM_DBG("This is a concurrently confirmed call."); - //Create a new Dialog ID token “X” - //Not sure how to do this so just going to use existing Did and add an X character to it - str new_did; - create_concurrent_did(dlg, &new_did); - - //assign new did to the created or updated dialog_out entry. - update_dlg_out_did(dlg_out, &new_did); - - //Then, duplicate the dialog_in entry and set its Dialog ID value to new_did - //for now rather just create new dlg structure with the correct params - this should be fixed if future use requires - - struct dlg_cell *new_dlg = 0; - new_dlg = build_new_dlg(&(dlg->callid) /*callid*/, - &(dlg->from_uri) /*from uri*/, - &(dlg->from_tag)/*from_tag*/, - &(dlg->req_uri) /*r-uri*/); - - //assign new did to dlg_in - update_dlg_did(new_dlg, &new_did); - - if (new_dlg == 0) { - LM_ERR("failed to create new dialog\n"); - goto done; - } - - //link the new_dlg with dlg_out object - link_dlg_out(new_dlg, dlg_out, 0); - - } - - if (new_state == DLG_STATE_DELETED - && (old_state == DLG_STATE_UNCONFIRMED - || old_state == DLG_STATE_EARLY)) { - LM_DBG("dialog %p failed (negative reply)\n", dlg); - /* dialog setup not completed (3456XX) */ - run_dlg_callbacks(DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); - /* do unref */ - if (unref) - unref_dlg(dlg, unref); - - if (old_state == DLG_STATE_EARLY) - counter_add(dialog_ng_cnts_h.early, -1); - goto done; - } - - if (unref) unref_dlg(dlg, unref); + if((dlg->dflags & DLG_FLAG_INSERTED) == 0) { + dlg->dflags |= DLG_FLAG_NEW; + } else { + dlg->dflags |= DLG_FLAG_CHANGED; + } + if(dlg_db_mode == DB_MODE_REALTIME) + update_dialog_dbinfo(dlg); + + if(0 != insert_dlg_timer(&dlg->tl, dlg->lifetime)) { + LM_CRIT("Unable to insert dlg %p [%u:%u] on event %d [%d->%d] " + "with clid '%.*s' and tags '%.*s' \n", + dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state, + dlg->callid.len, dlg->callid.s, dlg->from_tag.len, + dlg->from_tag.s); + } else { + ref_dlg(dlg, 1); + } + + /* dialog confirmed (ACK pending) */ + run_dlg_callbacks( + DLGCB_CONFIRMED_NA, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + + if(old_state == DLG_STATE_EARLY) + counter_add(dialog_ng_cnts_h.early, -1); + + if(unref) + unref_dlg(dlg, unref); + + counter_inc(dialog_ng_cnts_h.active); + + goto done; + } + + if(new_state == DLG_STATE_CONCURRENTLY_CONFIRMED + && (old_state == DLG_STATE_CONFIRMED + || old_state == DLG_STATE_CONCURRENTLY_CONFIRMED)) { + //This is a concurrently confirmed call + LM_DBG("This is a concurrently confirmed call."); + //Create a new Dialog ID token “X” + //Not sure how to do this so just going to use existing Did and add an X character to it + str new_did; + create_concurrent_did(dlg, &new_did); + + //assign new did to the created or updated dialog_out entry. + update_dlg_out_did(dlg_out, &new_did); + + //Then, duplicate the dialog_in entry and set its Dialog ID value to new_did + //for now rather just create new dlg structure with the correct params - this should be fixed if future use requires + + struct dlg_cell *new_dlg = 0; + new_dlg = build_new_dlg(&(dlg->callid) /*callid*/, + &(dlg->from_uri) /*from uri*/, &(dlg->from_tag) /*from_tag*/, + &(dlg->req_uri) /*r-uri*/); + + //assign new did to dlg_in + update_dlg_did(new_dlg, &new_did); + + if(new_dlg == 0) { + LM_ERR("failed to create new dialog\n"); + goto done; + } + + //link the new_dlg with dlg_out object + link_dlg_out(new_dlg, dlg_out, 0); + } + + if(new_state == DLG_STATE_DELETED + && (old_state == DLG_STATE_UNCONFIRMED + || old_state == DLG_STATE_EARLY)) { + LM_DBG("dialog %p failed (negative reply)\n", dlg); + /* dialog setup not completed (3456XX) */ + run_dlg_callbacks(DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0); + /* do unref */ + if(unref) + unref_dlg(dlg, unref); + + if(old_state == DLG_STATE_EARLY) + counter_add(dialog_ng_cnts_h.early, -1); + goto done; + } + + if(unref) + unref_dlg(dlg, unref); done: - /* unref due to dlg_get_by_iuid() */ - dlg_release(dlg); - return; + /* unref due to dlg_get_by_iuid() */ + dlg_release(dlg); + return; } /*! @@ -1524,8 +1595,9 @@ void dlg_onreply(struct cell* t, int type, struct tmcb_params *param) { * \param type unused * \param param unused */ -void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param) { - return; +void dlg_tmcb_dummy(struct cell *t, int type, struct tmcb_params *param) +{ + return; } /*! @@ -1542,146 +1614,154 @@ void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param) { * \param run_initial_cbs if set zero, initial callbacks are not executed * \return 0 on success, -1 on failure */ -int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs) { - struct dlg_cell *dlg; - str s; - str callid; - str ftag; - str ttag; - str req_uri; - unsigned int dir; - int mlock; - - if (req->first_line.u.request.method_value != METHOD_INVITE) - return -1; - - LM_DBG("starting dlg_new_dialog and method is [%.*s]\n", req->first_line.u.request.method.len, req->first_line.u.request.method.s); - - if (pre_match_parse(req, &callid, &ftag, &ttag, 0) < 0) { - LM_WARN("pre-matching failed\n"); - return -1; - } - - if (ttag.s != 0 && ttag.len != 0) - return -1; - - if (pv_printf_s(req, ruri_param_model, &req_uri) < 0) { - LM_ERR("error - cannot print the r-uri format\n"); - return -1; - } - trim(&req_uri); - - mlock = 1; - dlg = search_dlg(&callid, &ftag, &ttag, &dir); - if (detect_spirals) { - if (spiral_detected == 1) { - LM_DBG("spiral detected - returning 0\n"); - return 0; - } - dir = DLG_DIR_NONE; - if (dlg) { - mlock = 0; - if (dlg->state != DLG_STATE_DELETED) { - LM_DBG("Callid '%.*s' found, must be a spiraled request\n", - callid.len, callid.s); - spiral_detected = 1; - - if (run_initial_cbs) - run_dlg_callbacks(DLGCB_SPIRALED, dlg, req, NULL, DLG_DIR_DOWNSTREAM, 0); - - //Add did to rr header for all spiralled requested INVITEs - if (req->first_line.u.request.method_value == METHOD_INVITE) { - if (add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { - LM_ERR("failed to add RR param\n"); - } - } -// dlg_release(dlg); //this is a fix so that we register for terminating callbacks too (caters for spiralled invites on same P/S-CSCF) - _dlg_ctx.cpid = my_pid(); - _dlg_ctx.iuid.h_entry = dlg->h_entry; - _dlg_ctx.iuid.h_id = dlg->h_id; - set_current_dialog(req, dlg); - dlg_release(dlg); - return 0; - } else { - LM_DBG("spiral deteced and current state is [%d]\n", dlg->start_ts); - } - // get_dlg has incremented the ref count by 1 - dlg_release(dlg); - } - } else { - // get_dlg has incremented the ref count by 1 - if (dlg) - dlg_release(dlg); - } - spiral_detected = 0; - - - LM_DBG("Building new Dialog for call-id %.*s\n", callid.len, callid.s); - LM_DBG("SIP Method: %.*s \n", req->first_line.u.request.method.len, req->first_line.u.request.method.s); - dlg = build_new_dlg(&callid /*callid*/, - &(get_from(req)->uri) /*from uri*/, - &ftag/*from_tag*/, - &req_uri /*r-uri*/); - - if (dlg == 0) { - if (likely(mlock == 1)) dlg_hash_release(&callid); - LM_ERR("failed to create new dialog\n"); - return -1; - } - - /* save caller's tag, cseq, contact and record route*/ - if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG, - &(get_from(req)->tag_value)) != 0) { - LM_ERR("could not add further info to the dialog\n"); - lock_destroy(dlg->dlg_out_entries_lock); - lock_dealloc(dlg->dlg_out_entries_lock); - shm_free(dlg); - return -1; - } - - /* Populate initial varlist: */ - dlg->vars = get_local_varlist_pointer(req, 1); - - /* if search_dlg() returned NULL, slot was kept locked */ - link_dlg(dlg, 0, mlock); - if (likely(mlock == 1)) dlg_hash_release(&callid); - - s.s = _dlg_ctx.to_route_name; - s.len = strlen(s.s); - dlg_set_toroute(dlg, &s); - dlg->sflags |= _dlg_ctx.flags; - // dlg->iflags |= _dlg_ctx.iflags; - - // if (dlg_send_bye != 0 || _dlg_ctx.to_bye != 0) - // dlg->iflags |= DLG_IFLAG_TIMEOUTBYE; - - if (run_initial_cbs) run_create_callbacks(dlg, req); - - dlg->lifetime = get_dlg_timeout(req); - - /* first INVITE seen (dialog created, unconfirmed) */ - if (seq_match_mode != SEQ_MATCH_NO_ID && - add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { - LM_ERR("failed to add RR param\n"); - goto error; - } - - counter_inc(dialog_ng_cnts_h.processed); - - _dlg_ctx.cpid = my_pid(); - _dlg_ctx.iuid.h_entry = dlg->h_entry; - _dlg_ctx.iuid.h_id = dlg->h_id; - set_current_dialog(req, dlg); - - LM_DBG("New dialog created\n"); - - return 0; +int dlg_new_dialog( + struct sip_msg *req, struct cell *t, const int run_initial_cbs) +{ + struct dlg_cell *dlg; + str s; + str callid; + str ftag; + str ttag; + str req_uri; + unsigned int dir; + int mlock; + + if(req->first_line.u.request.method_value != METHOD_INVITE) + return -1; + + LM_DBG("starting dlg_new_dialog and method is [%.*s]\n", + req->first_line.u.request.method.len, + req->first_line.u.request.method.s); + + if(pre_match_parse(req, &callid, &ftag, &ttag, 0) < 0) { + LM_WARN("pre-matching failed\n"); + return -1; + } + + if(ttag.s != 0 && ttag.len != 0) + return -1; + + if(pv_printf_s(req, ruri_param_model, &req_uri) < 0) { + LM_ERR("error - cannot print the r-uri format\n"); + return -1; + } + trim(&req_uri); + + mlock = 1; + dlg = search_dlg(&callid, &ftag, &ttag, &dir); + if(detect_spirals) { + if(spiral_detected == 1) { + LM_DBG("spiral detected - returning 0\n"); + return 0; + } + dir = DLG_DIR_NONE; + if(dlg) { + mlock = 0; + if(dlg->state != DLG_STATE_DELETED) { + LM_DBG("Callid '%.*s' found, must be a spiraled request\n", + callid.len, callid.s); + spiral_detected = 1; + + if(run_initial_cbs) + run_dlg_callbacks(DLGCB_SPIRALED, dlg, req, NULL, + DLG_DIR_DOWNSTREAM, 0); + + //Add did to rr header for all spiralled requested INVITEs + if(req->first_line.u.request.method_value == METHOD_INVITE) { + if(add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { + LM_ERR("failed to add RR param\n"); + } + } + // dlg_release(dlg); //this is a fix so that we register for terminating callbacks too (caters for spiralled invites on same P/S-CSCF) + _dlg_ctx.cpid = my_pid(); + _dlg_ctx.iuid.h_entry = dlg->h_entry; + _dlg_ctx.iuid.h_id = dlg->h_id; + set_current_dialog(req, dlg); + dlg_release(dlg); + return 0; + } else { + LM_DBG("spiral deteced and current state is [%d]\n", + dlg->start_ts); + } + // get_dlg has incremented the ref count by 1 + dlg_release(dlg); + } + } else { + // get_dlg has incremented the ref count by 1 + if(dlg) + dlg_release(dlg); + } + spiral_detected = 0; + + + LM_DBG("Building new Dialog for call-id %.*s\n", callid.len, callid.s); + LM_DBG("SIP Method: %.*s \n", req->first_line.u.request.method.len, + req->first_line.u.request.method.s); + dlg = build_new_dlg(&callid /*callid*/, &(get_from(req)->uri) /*from uri*/, + &ftag /*from_tag*/, &req_uri /*r-uri*/); + + if(dlg == 0) { + if(likely(mlock == 1)) + dlg_hash_release(&callid); + LM_ERR("failed to create new dialog\n"); + return -1; + } + + /* save caller's tag, cseq, contact and record route*/ + if(populate_leg_info( + dlg, req, t, DLG_CALLER_LEG, &(get_from(req)->tag_value)) + != 0) { + LM_ERR("could not add further info to the dialog\n"); + lock_destroy(dlg->dlg_out_entries_lock); + lock_dealloc(dlg->dlg_out_entries_lock); + shm_free(dlg); + return -1; + } + + /* Populate initial varlist: */ + dlg->vars = get_local_varlist_pointer(req, 1); + + /* if search_dlg() returned NULL, slot was kept locked */ + link_dlg(dlg, 0, mlock); + if(likely(mlock == 1)) + dlg_hash_release(&callid); + + s.s = _dlg_ctx.to_route_name; + s.len = strlen(s.s); + dlg_set_toroute(dlg, &s); + dlg->sflags |= _dlg_ctx.flags; + // dlg->iflags |= _dlg_ctx.iflags; + + // if (dlg_send_bye != 0 || _dlg_ctx.to_bye != 0) + // dlg->iflags |= DLG_IFLAG_TIMEOUTBYE; + + if(run_initial_cbs) + run_create_callbacks(dlg, req); + + dlg->lifetime = get_dlg_timeout(req); + + /* first INVITE seen (dialog created, unconfirmed) */ + if(seq_match_mode != SEQ_MATCH_NO_ID + && add_dlg_rr_param(req, dlg->h_entry, dlg->h_id) < 0) { + LM_ERR("failed to add RR param\n"); + goto error; + } + + counter_inc(dialog_ng_cnts_h.processed); + + _dlg_ctx.cpid = my_pid(); + _dlg_ctx.iuid.h_entry = dlg->h_entry; + _dlg_ctx.iuid.h_id = dlg->h_id; + set_current_dialog(req, dlg); + + LM_DBG("New dialog created\n"); + + return 0; error: - if (!spiral_detected) - unref_dlg(dlg, 1); // undo ref regarding linking - return -1; - + if(!spiral_detected) + unref_dlg(dlg, 1); // undo ref regarding linking + return -1; } /*! @@ -1692,37 +1772,43 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb * \param smode if the sip request was spiraled * \return 0 on success, -1 on failure */ -int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg, - int smode) { - dlg_iuid_t *iuid = NULL; - if (t == NULL) - return -1; - - if (smode == 0) { -// if (smode == 1) { -// LM_DBG("Setting up TM callbacks for spiralled request on T (%p)\n", t); -// } - iuid = dlg_get_iuid_shm_clone(dlg); - if (iuid == NULL) { - LM_ERR("failed to create dialog unique id clone\n"); - goto error; - } - if (d_tmb.register_tmcb(req, t, - TMCB_RESPONSE_IN | TMCB_RESPONSE_READY | TMCB_RESPONSE_FWDED | TMCB_ON_FAILURE | TMCB_E2ECANCEL_IN | TMCB_REQUEST_OUT, - dlg_onreply, (void*) iuid, dlg_iuid_sfree) < 0) { - LM_ERR("failed to register TMCB\n"); - goto error; - } - } else { - LM_DBG("Not registering for TM callbacks because this is a spiraled request and we should have already registered callbacks on this transaction....\n"); - } - - dlg->dflags |= DLG_FLAG_TM; - - return 0; +int dlg_set_tm_callbacks( + tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg, int smode) +{ + dlg_iuid_t *iuid = NULL; + if(t == NULL) + return -1; + + if(smode == 0) { + // if (smode == 1) { + // LM_DBG("Setting up TM callbacks for spiralled request on T (%p)\n", t); + // } + iuid = dlg_get_iuid_shm_clone(dlg); + if(iuid == NULL) { + LM_ERR("failed to create dialog unique id clone\n"); + goto error; + } + if(d_tmb.register_tmcb(req, t, + TMCB_RESPONSE_IN | TMCB_RESPONSE_READY | TMCB_RESPONSE_FWDED + | TMCB_ON_FAILURE | TMCB_E2ECANCEL_IN + | TMCB_REQUEST_OUT, + dlg_onreply, (void *)iuid, dlg_iuid_sfree) + < 0) { + LM_ERR("failed to register TMCB\n"); + goto error; + } + } else { + LM_DBG("Not registering for TM callbacks because this is a spiraled " + "request and we should have already registered callbacks on " + "this transaction....\n"); + } + + dlg->dflags |= DLG_FLAG_TM; + + return 0; error: - dlg_iuid_sfree(iuid); - return -1; + dlg_iuid_sfree(iuid); + return -1; } static str reason_hdr_s = {"Reason: dialog_timeout\r\n", 24}; @@ -1731,67 +1817,69 @@ static str reason_hdr_s = {"Reason: dialog_timeout\r\n", 24}; * \brief Timer function that removes expired dialogs, run timeout route * \param tl dialog timer list */ -void dlg_ontimeout(struct dlg_tl *tl) { - dlg_cell_t *dlg; - int new_state, old_state, unref; - sip_msg_t *fmsg; - - - /* get the dialog tl payload */ - dlg = ((struct dlg_cell*) ((char *) (tl) - - (unsigned long) (&((struct dlg_cell*) 0)->tl))); - - /* mark dialog as expired */ - dlg->dflags |= DLG_FLAG_EXPIRED; - - if (dlg->state == DLG_STATE_CONFIRMED_NA - || dlg->state == DLG_STATE_CONFIRMED) { - if (dlg->toroute > 0 && dlg->toroute < main_rt.entries - && main_rt.rlist[dlg->toroute] != NULL) { - fmsg = faked_msg_next(); - if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE) > 0) { - ref_dlg(dlg, 1); - dlg_set_ctx_iuid(dlg); - LM_DBG("executing route %d on timeout\n", dlg->toroute); - set_route_type(REQUEST_ROUTE); - run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0); - dlg_reset_ctx_iuid(); - exec_post_script_cb(fmsg, REQUEST_CB_TYPE); - unref_dlg(dlg, 1); - } - } - - // if (dlg->iflags & DLG_IFLAG_TIMEOUTBYE) { //TODO return therse flags - if (dlg->state == DLG_STATE_CONFIRMED) { - if (dlg_bye_all(dlg, &reason_hdr_s) < 0 ) /* function only supports DLG_STATE_CONFIRMED*/ - LM_DBG("Failed to do dlg_bye_all.!!"); -// unref_dlg(dlg, 1); - } -// else if (dlg->state == DLG_STATE_CONFIRMED_NA) -// unref_dlg(dlg, 1); -// counter_inc(dialog_ng_cnts_h.expired); -// return; - } - - next_state_dlg(dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref, 0); - // dlg_run_event_route(dlg, NULL, old_state, new_state); //TODO replace - - if (new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) { - LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s'\n", - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - /* dialog timeout */ - run_dlg_callbacks(DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, 0); - - unref_dlg(dlg, unref + 1); - counter_add(dialog_ng_cnts_h.active, -1); - counter_inc(dialog_ng_cnts_h.expired); - } else { - unref_dlg(dlg, 1); - } - - return; +void dlg_ontimeout(struct dlg_tl *tl) +{ + dlg_cell_t *dlg; + int new_state, old_state, unref; + sip_msg_t *fmsg; + + + /* get the dialog tl payload */ + dlg = ((struct dlg_cell *)((char *)(tl) + - (unsigned long)(&((struct dlg_cell *)0)->tl))); + + /* mark dialog as expired */ + dlg->dflags |= DLG_FLAG_EXPIRED; + + if(dlg->state == DLG_STATE_CONFIRMED_NA + || dlg->state == DLG_STATE_CONFIRMED) { + if(dlg->toroute > 0 && dlg->toroute < main_rt.entries + && main_rt.rlist[dlg->toroute] != NULL) { + fmsg = faked_msg_next(); + if(exec_pre_script_cb(fmsg, REQUEST_CB_TYPE) > 0) { + ref_dlg(dlg, 1); + dlg_set_ctx_iuid(dlg); + LM_DBG("executing route %d on timeout\n", dlg->toroute); + set_route_type(REQUEST_ROUTE); + run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0); + dlg_reset_ctx_iuid(); + exec_post_script_cb(fmsg, REQUEST_CB_TYPE); + unref_dlg(dlg, 1); + } + } + + // if (dlg->iflags & DLG_IFLAG_TIMEOUTBYE) { //TODO return therse flags + if(dlg->state == DLG_STATE_CONFIRMED) { + if(dlg_bye_all(dlg, &reason_hdr_s) + < 0) /* function only supports DLG_STATE_CONFIRMED*/ + LM_DBG("Failed to do dlg_bye_all.!!"); + // unref_dlg(dlg, 1); + } + // else if (dlg->state == DLG_STATE_CONFIRMED_NA) + // unref_dlg(dlg, 1); + // counter_inc(dialog_ng_cnts_h.expired); + // return; + } + + next_state_dlg(dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref, 0); + // dlg_run_event_route(dlg, NULL, old_state, new_state); //TODO replace + + if(new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) { + LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s'\n", + dlg->callid.len, dlg->callid.s, dlg->from_tag.len, + dlg->from_tag.s); + + /* dialog timeout */ + run_dlg_callbacks(DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, 0); + + unref_dlg(dlg, unref + 1); + counter_add(dialog_ng_cnts_h.active, -1); + counter_inc(dialog_ng_cnts_h.expired); + } else { + unref_dlg(dlg, 1); + } + + return; } /*! @@ -1801,25 +1889,26 @@ void dlg_ontimeout(struct dlg_tl *tl) { * \param res pseudo-variable result * \return 0 on success, -1 on failure */ -int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - int l = 0; - char *ch = NULL; +int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) +{ + int l = 0; + char *ch = NULL; - if (msg == NULL || res == NULL) - return -1; + if(msg == NULL || res == NULL) + return -1; - if (CURR_DLG_ID != msg->id) - return pv_get_null(msg, param, res); + if(CURR_DLG_ID != msg->id) + return pv_get_null(msg, param, res); - res->ri = CURR_DLG_LIFETIME; - ch = int2str((unsigned long) res->ri, &l); + res->ri = CURR_DLG_LIFETIME; + ch = int2str((unsigned long)res->ri, &l); - res->rs.s = ch; - res->rs.len = l; + res->rs.s = ch; + res->rs.len = l; - res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT; + res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT; - return 0; + return 0; } /*! @@ -1829,25 +1918,26 @@ int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) * \param res pseudo-variable result * \return 0 on success, -1 on failure */ -int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - int l = 0; - char *ch = NULL; +int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) +{ + int l = 0; + char *ch = NULL; - if (msg == NULL || res == NULL) - return -1; + if(msg == NULL || res == NULL) + return -1; - if (CURR_DLG_ID != msg->id) - return pv_get_null(msg, param, res); + if(CURR_DLG_ID != msg->id) + return pv_get_null(msg, param, res); - res->ri = CURR_DLG_STATUS; - ch = int2str((unsigned long) res->ri, &l); + res->ri = CURR_DLG_STATUS; + ch = int2str((unsigned long)res->ri, &l); - res->rs.s = ch; - res->rs.len = l; + res->rs.s = ch; + res->rs.len = l; - res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT; + res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT; - return 0; + return 0; } /*! @@ -1856,54 +1946,67 @@ int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { * \return void */ -void internal_print_all_dlg(struct dlg_cell *dlg) { - - LM_DBG("Trying to get lock for printing\n"); - lock_get(dlg->dlg_out_entries_lock); - - struct dlg_cell_out *dlg_out; - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - - LM_DBG("----------------------------"); - LM_DBG("Dialog h_entry:h_id = [%u : %u]\n", dlg->h_entry, dlg->h_id); - LM_DBG("Dialog age: %" TIME_T_FMT "\n", TIME_T_CAST(act_time - dlg->init_ts)); - LM_DBG("Dialog call-id: %.*s\n", dlg->callid.len, dlg->callid.s); - LM_DBG("Dialog state: %d\n", dlg->state); - LM_DBG("Dialog ref counter: %d\n", dlg->ref); - LM_DBG("Dialog did: %.*s\n", dlg->did.len, dlg->did.s); - LM_DBG("Dialog from_tag: %.*s\n", dlg->from_tag.len, dlg->from_tag.s); - LM_DBG("Dialog from_uri: %.*s\n", dlg->from_uri.len, dlg->from_uri.s); - LM_DBG("Dialog caller contact: %.*s\n", dlg->caller_contact.len, dlg->caller_contact.s); - LM_DBG("Dialog first request cseq: %.*s\n", dlg->first_req_cseq.len, dlg->first_req_cseq.s); - LM_DBG("Dialog caller route set: %.*s\n", dlg->caller_route_set.len, dlg->caller_route_set.s); - LM_DBG("Dialog lifetime: %d\n", dlg->lifetime); - LM_DBG("Dialog bind_address: %.*s\n", dlg->caller_bind_addr ? dlg->caller_bind_addr->sock_str.len : 0, dlg->caller_bind_addr ? dlg->caller_bind_addr->sock_str.s : 0); - LM_DBG("Dialog-creating transaction pointer [%p]\n", dlg->transaction); - - dlg_out = d_entry_out->first; - - while (dlg_out) { - - LM_DBG("----------"); - LM_DBG("Dialog out h_entry:h_id = [%u : %u]\n", dlg_out->h_entry, dlg_out->h_id); - LM_DBG("Dialog out did: %.*s\n", dlg_out->did.len, dlg_out->did.s); - LM_DBG("Dialog out to_tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s); - LM_DBG("Dialog out caller cseq: %.*s\n", dlg_out->caller_cseq.len, dlg_out->caller_cseq.s); - LM_DBG("Dialog out callee cseq: %.*s\n", dlg_out->callee_cseq.len, dlg_out->callee_cseq.s); - LM_DBG("Dialog out callee contact: %.*s\n", dlg_out->callee_contact.len, dlg_out->callee_contact.s); - LM_DBG("Dialog out callee route set: %.*s\n", dlg_out->callee_route_set.len, dlg_out->callee_route_set.s); - LM_DBG("Dialog out branch: %.*s\n", dlg_out->branch.len, dlg_out->branch.s); - LM_DBG("Dialog out state (deleted): %i\n", dlg_out->deleted); - - LM_DBG("----------"); - dlg_out = dlg_out->next; - } - - LM_DBG("Releasing lock for dlgout\n"); - lock_release(dlg->dlg_out_entries_lock); - - LM_DBG("----------------------------"); - +void internal_print_all_dlg(struct dlg_cell *dlg) +{ + + LM_DBG("Trying to get lock for printing\n"); + lock_get(dlg->dlg_out_entries_lock); + + struct dlg_cell_out *dlg_out; + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + + LM_DBG("----------------------------"); + LM_DBG("Dialog h_entry:h_id = [%u : %u]\n", dlg->h_entry, dlg->h_id); + LM_DBG("Dialog age: %" TIME_T_FMT "\n", + TIME_T_CAST(act_time - dlg->init_ts)); + LM_DBG("Dialog call-id: %.*s\n", dlg->callid.len, dlg->callid.s); + LM_DBG("Dialog state: %d\n", dlg->state); + LM_DBG("Dialog ref counter: %d\n", dlg->ref); + LM_DBG("Dialog did: %.*s\n", dlg->did.len, dlg->did.s); + LM_DBG("Dialog from_tag: %.*s\n", dlg->from_tag.len, dlg->from_tag.s); + LM_DBG("Dialog from_uri: %.*s\n", dlg->from_uri.len, dlg->from_uri.s); + LM_DBG("Dialog caller contact: %.*s\n", dlg->caller_contact.len, + dlg->caller_contact.s); + LM_DBG("Dialog first request cseq: %.*s\n", dlg->first_req_cseq.len, + dlg->first_req_cseq.s); + LM_DBG("Dialog caller route set: %.*s\n", dlg->caller_route_set.len, + dlg->caller_route_set.s); + LM_DBG("Dialog lifetime: %d\n", dlg->lifetime); + LM_DBG("Dialog bind_address: %.*s\n", + dlg->caller_bind_addr ? dlg->caller_bind_addr->sock_str.len : 0, + dlg->caller_bind_addr ? dlg->caller_bind_addr->sock_str.s : 0); + LM_DBG("Dialog-creating transaction pointer [%p]\n", dlg->transaction); + + dlg_out = d_entry_out->first; + + while(dlg_out) { + + LM_DBG("----------"); + LM_DBG("Dialog out h_entry:h_id = [%u : %u]\n", dlg_out->h_entry, + dlg_out->h_id); + LM_DBG("Dialog out did: %.*s\n", dlg_out->did.len, dlg_out->did.s); + LM_DBG("Dialog out to_tag: %.*s\n", dlg_out->to_tag.len, + dlg_out->to_tag.s); + LM_DBG("Dialog out caller cseq: %.*s\n", dlg_out->caller_cseq.len, + dlg_out->caller_cseq.s); + LM_DBG("Dialog out callee cseq: %.*s\n", dlg_out->callee_cseq.len, + dlg_out->callee_cseq.s); + LM_DBG("Dialog out callee contact: %.*s\n", dlg_out->callee_contact.len, + dlg_out->callee_contact.s); + LM_DBG("Dialog out callee route set: %.*s\n", + dlg_out->callee_route_set.len, dlg_out->callee_route_set.s); + LM_DBG("Dialog out branch: %.*s\n", dlg_out->branch.len, + dlg_out->branch.s); + LM_DBG("Dialog out state (deleted): %i\n", dlg_out->deleted); + + LM_DBG("----------"); + dlg_out = dlg_out->next; + } + + LM_DBG("Releasing lock for dlgout\n"); + lock_release(dlg->dlg_out_entries_lock); + + LM_DBG("----------------------------"); } /*! @@ -1911,27 +2014,27 @@ void internal_print_all_dlg(struct dlg_cell *dlg) { * \return void */ -void print_all_dlgs() { - //print all dialog information - this is just for testing and is set to happen every 10 seconds +void print_all_dlgs() +{ + //print all dialog information - this is just for testing and is set to happen every 10 seconds - struct dlg_cell *dlg; - unsigned int i; + struct dlg_cell *dlg; + unsigned int i; act_time = time(0); - LM_DBG("********************"); - LM_DBG("printing %i dialogs\n", d_table->size); + LM_DBG("********************"); + LM_DBG("printing %i dialogs\n", d_table->size); - for (i = 0; i < d_table->size; i++) { - dlg_lock(d_table, &(d_table->entries[i])); - - for (dlg = d_table->entries[i].first; dlg; dlg = dlg->next) { - internal_print_all_dlg(dlg); - } - dlg_unlock(d_table, &(d_table->entries[i])); - } - LM_DBG("********************"); + for(i = 0; i < d_table->size; i++) { + dlg_lock(d_table, &(d_table->entries[i])); + for(dlg = d_table->entries[i].first; dlg; dlg = dlg->next) { + internal_print_all_dlg(dlg); + } + dlg_unlock(d_table, &(d_table->entries[i])); + } + LM_DBG("********************"); } /*! @@ -1940,27 +2043,27 @@ void print_all_dlgs() { * \return current dialog, null if none. */ -struct dlg_cell *dlg_get_msg_dialog(sip_msg_t *msg) { - struct dlg_cell *dlg = NULL; - str callid; - str ftag; - str ttag; - unsigned int dir; - - /* Retrieve the current dialog */ - dlg = dlg_get_ctx_dialog(); - if (dlg != NULL) - return dlg; - - if (pre_match_parse(msg, &callid, &ftag, &ttag, 0) < 0) - return NULL; - dir = DLG_DIR_NONE; - dlg = get_dlg(&callid, &ftag, &ttag, &dir); - if (dlg == NULL) { - LM_DBG("dlg with callid '%.*s' not found\n", - msg->callid->body.len, msg->callid->body.s); - return NULL; - } - return dlg; +struct dlg_cell *dlg_get_msg_dialog(sip_msg_t *msg) +{ + struct dlg_cell *dlg = NULL; + str callid; + str ftag; + str ttag; + unsigned int dir; + + /* Retrieve the current dialog */ + dlg = dlg_get_ctx_dialog(); + if(dlg != NULL) + return dlg; + + if(pre_match_parse(msg, &callid, &ftag, &ttag, 0) < 0) + return NULL; + dir = DLG_DIR_NONE; + dlg = get_dlg(&callid, &ftag, &ttag, &dir); + if(dlg == NULL) { + LM_DBG("dlg with callid '%.*s' not found\n", msg->callid->body.len, + msg->callid->body.s); + return NULL; + } + return dlg; } - diff --git a/src/modules/ims_dialog/dlg_handlers.h b/src/modules/ims_dialog/dlg_handlers.h index 3c3dfd5c5bc..0e61d5dc825 100644 --- a/src/modules/ims_dialog/dlg_handlers.h +++ b/src/modules/ims_dialog/dlg_handlers.h @@ -42,17 +42,17 @@ #include "../../modules/tm/t_hooks.h" #include "dlg_timer.h" -#define MI_DIALOG_NOT_FOUND "Requested Dialog not found" -#define MI_DIALOG_NOT_FOUND_LEN (sizeof(MI_DIALOG_NOT_FOUND)-1) -#define MI_DLG_OPERATION_ERR "Operation failed" -#define MI_DLG_OPERATION_ERR_LEN (sizeof(MI_DLG_OPERATION_ERR)-1) +#define MI_DIALOG_NOT_FOUND "Requested Dialog not found" +#define MI_DIALOG_NOT_FOUND_LEN (sizeof(MI_DIALOG_NOT_FOUND) - 1) +#define MI_DLG_OPERATION_ERR "Operation failed" +#define MI_DLG_OPERATION_ERR_LEN (sizeof(MI_DLG_OPERATION_ERR) - 1) #define MAX_DLG_RR_PARAM_NAME 32 /* values for the sequential match mode */ -#define SEQ_MATCH_STRICT_ID 0 -#define SEQ_MATCH_FALLBACK 1 -#define SEQ_MATCH_NO_ID 2 +#define SEQ_MATCH_STRICT_ID 0 +#define SEQ_MATCH_FALLBACK 1 +#define SEQ_MATCH_NO_ID 2 /*! @@ -63,9 +63,8 @@ * \param default_timeout_p default timeout * \param seq_match_mode_p matching mode */ -void init_dlg_handlers(char *rr_param, int dlg_flag, - pv_spec_t *timeout_avp, int default_timeout, - int seq_match_mode); +void init_dlg_handlers(char *rr_param, int dlg_flag, pv_spec_t *timeout_avp, + int default_timeout, int seq_match_mode); /*! @@ -87,8 +86,8 @@ void destroy_dlg_handlers(void); * \note for a request: get record route in normal order, for a reply get * in reverse order, skipping the ones from the request and the proxies' own */ -int populate_leg_info( struct dlg_cell *dlg, struct sip_msg *msg, - struct cell* t, unsigned int leg, str *tag); +int populate_leg_info(struct dlg_cell *dlg, struct sip_msg *msg, struct cell *t, + unsigned int leg, str *tag); /*! * \brief Clone dialog internal unique id to shared memory @@ -108,9 +107,9 @@ void dlg_iuid_sfree(void *iuid); * \param type type of the entered callback * \param param saved dialog structure in the callback */ -void dlg_onreq(struct cell* t, int type, struct tmcb_params *param); +void dlg_onreq(struct cell *t, int type, struct tmcb_params *param); -void dlg_onreply(struct cell* t, int type, struct tmcb_params *param); +void dlg_onreply(struct cell *t, int type, struct tmcb_params *param); /*! * \brief Function that is registered as RR callback for dialog tracking @@ -123,14 +122,14 @@ void dlg_onreply(struct cell* t, int type, struct tmcb_params *param); * \param route_params record-route parameter * \param param unused */ -void dlg_onroute(struct sip_msg* req, str *rr_param, void *param); +void dlg_onroute(struct sip_msg *req, str *rr_param, void *param); /*! * \brief Timer function that removes expired dialogs, run timeout route * \param tl dialog timer list */ -void dlg_ontimeout( struct dlg_tl *tl); +void dlg_ontimeout(struct dlg_tl *tl); /*! @@ -146,8 +145,9 @@ void dlg_ontimeout( struct dlg_tl *tl); * \param t transaction * \param run_initial_cbs if set zero, initial callbacks are not executed * \return 0 on success, -1 on failure - */ -int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs); + */ +int dlg_new_dialog( + struct sip_msg *req, struct cell *t, const int run_initial_cbs); /*! * \brief add dlg structure to tm callbacks @@ -157,8 +157,8 @@ int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cb * \param smode if the sip request was spiraled * \return 0 on success, -1 on failure */ -int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg, - int smode); +int dlg_set_tm_callbacks( + tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg, int smode); /*! * \brief Function that returns the dialog lifetime as pseudo-variable @@ -167,8 +167,8 @@ int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg, * \param res pseudo-variable result * \return 0 on success, -1 on failure */ -int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); +int pv_get_dlg_lifetime( + struct sip_msg *msg, pv_param_t *param, pv_value_t *res); /*! @@ -178,8 +178,7 @@ int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, * \param res pseudo-variable result * \return 0 on success, -1 on failure */ -int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); +int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); /*! @@ -188,7 +187,7 @@ int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, * \param type unused * \param param unused */ -void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param); +void dlg_tmcb_dummy(struct cell *t, int type, struct tmcb_params *param); /*! * \brief Helper function that prints information for all dialogs diff --git a/src/modules/ims_dialog/dlg_hash.c b/src/modules/ims_dialog/dlg_hash.c index 780ae918fda..386c3ab2620 100644 --- a/src/modules/ims_dialog/dlg_hash.c +++ b/src/modules/ims_dialog/dlg_hash.c @@ -19,8 +19,8 @@ #include "dlg_db_handler.h" //#include -#define MAX_LDG_LOCKS 2048 -#define MIN_LDG_LOCKS 2 +#define MAX_LDG_LOCKS 2048 +#define MIN_LDG_LOCKS 2 extern int dlg_db_mode; @@ -35,12 +35,11 @@ static int dlg_hash_size_out = 4096; * \param _dlg dialog * \param _cnt increment for the reference counter */ -#define ref_dlg_unsafe(_dlg,_cnt) \ - do { \ - (_dlg)->ref += (_cnt); \ - LM_DBG("ref dlg %p with %d -> %d\n", \ - (_dlg),(_cnt),(_dlg)->ref); \ - }while(0) +#define ref_dlg_unsafe(_dlg, _cnt) \ + do { \ + (_dlg)->ref += (_cnt); \ + LM_DBG("ref dlg %p with %d -> %d\n", (_dlg), (_cnt), (_dlg)->ref); \ + } while(0) /*! @@ -49,26 +48,23 @@ static int dlg_hash_size_out = 4096; * \param _cnt decrement for the reference counter * \param _d_entry dialog entry */ -#define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \ - do { \ - (_dlg)->ref -= (_cnt); \ - LM_DBG("unref dlg %p with %d -> %d\n",\ - (_dlg),(_cnt),(_dlg)->ref);\ - if ((_dlg)->ref<0) {\ - LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\ - "with clid '%.*s' and tags '%.*s'\n",\ - (_dlg)->ref, _cnt, _dlg,\ - (_dlg)->h_entry, (_dlg)->h_id,\ - (_dlg)->callid.len, (_dlg)->callid.s,\ - (_dlg)->from_tag.len,\ - (_dlg)->from_tag.s);\ - }\ - if ((_dlg)->ref<=0) { \ - unlink_unsafe_dlg( _d_entry, _dlg);\ - LM_DBG("ref <=0 for dialog %p\n",_dlg);\ - destroy_dlg(_dlg);\ - }\ - }while(0) +#define unref_dlg_unsafe(_dlg, _cnt, _d_entry) \ + do { \ + (_dlg)->ref -= (_cnt); \ + LM_DBG("unref dlg %p with %d -> %d\n", (_dlg), (_cnt), (_dlg)->ref); \ + if((_dlg)->ref < 0) { \ + LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] " \ + "with clid '%.*s' and tags '%.*s'\n", \ + (_dlg)->ref, _cnt, _dlg, (_dlg)->h_entry, (_dlg)->h_id, \ + (_dlg)->callid.len, (_dlg)->callid.s, \ + (_dlg)->from_tag.len, (_dlg)->from_tag.s); \ + } \ + if((_dlg)->ref <= 0) { \ + unlink_unsafe_dlg(_d_entry, _dlg); \ + LM_DBG("ref <=0 for dialog %p\n", _dlg); \ + destroy_dlg(_dlg); \ + } \ + } while(0) #if 0 inline static int backtrace2str(char* buf, int size) @@ -95,52 +91,53 @@ inline static int backtrace2str(char* buf, int size) * \param size size of the table * \return 0 on success, -1 on failure */ -int init_dlg_table(unsigned int size) { - unsigned int n; - unsigned int i; - - d_table = (struct dlg_table*) shm_malloc - (sizeof (struct dlg_table) +size * sizeof (struct dlg_entry)); - if (d_table == 0) { - LM_ERR("no more shm mem (1)\n"); - goto error0; - } - - memset(d_table, 0, sizeof (struct dlg_table)); - d_table->size = size; - d_table->entries = (struct dlg_entry*) (d_table + 1); - - n = (size < MAX_LDG_LOCKS) ? size : MAX_LDG_LOCKS; - for (; n >= MIN_LDG_LOCKS; n--) { - d_table->locks = lock_set_alloc(n); - if (d_table->locks == 0) - continue; - if (lock_set_init(d_table->locks) == 0) { - lock_set_dealloc(d_table->locks); - d_table->locks = 0; - continue; - } - d_table->locks_no = n; - break; - } - - if (d_table->locks == 0) { - LM_ERR("unable to allocted at least %d locks for the hash table\n", - MIN_LDG_LOCKS); - goto error1; - } - - for (i = 0; i < size; i++) { - memset(&(d_table->entries[i]), 0, sizeof (struct dlg_entry)); - d_table->entries[i].next_id = kam_rand() % (3*size); - d_table->entries[i].lock_idx = i % d_table->locks_no; - } - - return 0; +int init_dlg_table(unsigned int size) +{ + unsigned int n; + unsigned int i; + + d_table = (struct dlg_table *)shm_malloc( + sizeof(struct dlg_table) + size * sizeof(struct dlg_entry)); + if(d_table == 0) { + LM_ERR("no more shm mem (1)\n"); + goto error0; + } + + memset(d_table, 0, sizeof(struct dlg_table)); + d_table->size = size; + d_table->entries = (struct dlg_entry *)(d_table + 1); + + n = (size < MAX_LDG_LOCKS) ? size : MAX_LDG_LOCKS; + for(; n >= MIN_LDG_LOCKS; n--) { + d_table->locks = lock_set_alloc(n); + if(d_table->locks == 0) + continue; + if(lock_set_init(d_table->locks) == 0) { + lock_set_dealloc(d_table->locks); + d_table->locks = 0; + continue; + } + d_table->locks_no = n; + break; + } + + if(d_table->locks == 0) { + LM_ERR("unable to allocted at least %d locks for the hash table\n", + MIN_LDG_LOCKS); + goto error1; + } + + for(i = 0; i < size; i++) { + memset(&(d_table->entries[i]), 0, sizeof(struct dlg_entry)); + d_table->entries[i].next_id = kam_rand() % (3 * size); + d_table->entries[i].lock_idx = i % d_table->locks_no; + } + + return 0; error1: - shm_free(d_table); + shm_free(d_table); error0: - return -1; + return -1; } /*! @@ -148,155 +145,156 @@ int init_dlg_table(unsigned int size) { * \param d_entry_out structure * \return void */ -static void destroy_entry_out(struct dlg_entry_out *d_entry_out) { - struct dlg_cell_out *dlg_out; - struct dlg_cell_out *dlg_out_tmp; - dlg_out = d_entry_out->first; - - LM_DBG("Destroy dialog entry out\n"); - while (dlg_out) { - //clear all dlg_out memory space - if (dlg_out->caller_cseq.s) { - LM_DBG("content before freeing caller cseq is [%.*s]\n", dlg_out->caller_cseq.len, dlg_out->caller_cseq.s); - shm_free(dlg_out->caller_cseq.s); - } +static void destroy_entry_out(struct dlg_entry_out *d_entry_out) +{ + struct dlg_cell_out *dlg_out; + struct dlg_cell_out *dlg_out_tmp; + dlg_out = d_entry_out->first; + + LM_DBG("Destroy dialog entry out\n"); + while(dlg_out) { + //clear all dlg_out memory space + if(dlg_out->caller_cseq.s) { + LM_DBG("content before freeing caller cseq is [%.*s]\n", + dlg_out->caller_cseq.len, dlg_out->caller_cseq.s); + shm_free(dlg_out->caller_cseq.s); + } - if (dlg_out->callee_cseq.s) { - LM_DBG("content before freeing callee cseq is [%.*s]\n", dlg_out->callee_cseq.len, dlg_out->callee_cseq.s); - shm_free(dlg_out->callee_cseq.s); - } + if(dlg_out->callee_cseq.s) { + LM_DBG("content before freeing callee cseq is [%.*s]\n", + dlg_out->callee_cseq.len, dlg_out->callee_cseq.s); + shm_free(dlg_out->callee_cseq.s); + } - if (dlg_out->callee_contact.s) { - LM_DBG("content before freeing callee contact is [%.*s]\n", dlg_out->callee_contact.len, dlg_out->callee_contact.s); - shm_free(dlg_out->callee_contact.s); - } + if(dlg_out->callee_contact.s) { + LM_DBG("content before freeing callee contact is [%.*s]\n", + dlg_out->callee_contact.len, dlg_out->callee_contact.s); + shm_free(dlg_out->callee_contact.s); + } - if (dlg_out->callee_route_set.s) { - shm_free(dlg_out->callee_route_set.s); - } - if (dlg_out->did.s) { - shm_free(dlg_out->did.s); - } + if(dlg_out->callee_route_set.s) { + shm_free(dlg_out->callee_route_set.s); + } + if(dlg_out->did.s) { + shm_free(dlg_out->did.s); + } - dlg_out_tmp = dlg_out->next; - shm_free(dlg_out); + dlg_out_tmp = dlg_out->next; + shm_free(dlg_out); - dlg_out = dlg_out_tmp; - } + dlg_out = dlg_out_tmp; + } } /*! * \brief Destroy a dialog, run callbacks and free memory * \param dlg destroyed dialog */ -void destroy_dlg(struct dlg_cell *dlg) { - int ret = 0; - struct dlg_var *var; - - LM_DBG("destroying dialog %p\n", dlg); - - ret = remove_dialog_timer(&dlg->tl); - if (ret < 0) { - LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } else if (ret > 0) { - LM_DBG("removed timer for dlg %p [%u:%u] " - "with clid '%.*s' and tags '%.*s' \n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - - } +void destroy_dlg(struct dlg_cell *dlg) +{ + int ret = 0; + struct dlg_var *var; + + LM_DBG("destroying dialog %p\n", dlg); + + ret = remove_dialog_timer(&dlg->tl); + if(ret < 0) { + LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, + dlg->from_tag.len, dlg->from_tag.s); + + } else if(ret > 0) { + LM_DBG("removed timer for dlg %p [%u:%u] " + "with clid '%.*s' and tags '%.*s' \n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, + dlg->from_tag.len, dlg->from_tag.s); + } - if (dlg_db_mode) - remove_dialog_in_from_db(dlg); + if(dlg_db_mode) + remove_dialog_in_from_db(dlg); - LM_DBG("About to run dlg callback for destroy\n"); - run_dlg_callbacks(DLGCB_DESTROY, dlg, NULL, NULL, DLG_DIR_NONE, 0); - LM_DBG("DONE: About to run dlg callback for destroy\n"); - - if (dlg->cbs.first) - destroy_dlg_callbacks_list(dlg->cbs.first); + LM_DBG("About to run dlg callback for destroy\n"); + run_dlg_callbacks(DLGCB_DESTROY, dlg, NULL, NULL, DLG_DIR_NONE, 0); + LM_DBG("DONE: About to run dlg callback for destroy\n"); - if (dlg->profile_links) - destroy_linkers(dlg->profile_links); + if(dlg->cbs.first) + destroy_dlg_callbacks_list(dlg->cbs.first); + if(dlg->profile_links) + destroy_linkers(dlg->profile_links); - if (dlg->from_tag.s) - shm_free(dlg->from_tag.s); - if (dlg->first_req_cseq.s) - shm_free(dlg->first_req_cseq.s); + if(dlg->from_tag.s) + shm_free(dlg->from_tag.s); - if (dlg->toroute_name.s) - shm_free(dlg->toroute_name.s); + if(dlg->first_req_cseq.s) + shm_free(dlg->first_req_cseq.s); - if (dlg->did.s) - shm_free(dlg->did.s); + if(dlg->toroute_name.s) + shm_free(dlg->toroute_name.s); - if (dlg->caller_route_set.s) - shm_free(dlg->caller_route_set.s); + if(dlg->did.s) + shm_free(dlg->did.s); - if (dlg->caller_contact.s) - shm_free(dlg->caller_contact.s); + if(dlg->caller_route_set.s) + shm_free(dlg->caller_route_set.s); - while (dlg->vars) { + if(dlg->caller_contact.s) + shm_free(dlg->caller_contact.s); - var = dlg->vars; - dlg->vars = dlg->vars->next; - shm_free(var->key.s); - shm_free(var->value.s); - shm_free(var); - } + while(dlg->vars) { - if (dlg->dlg_entry_out.first) { - lock_get(dlg->dlg_out_entries_lock); - destroy_entry_out(&(dlg->dlg_entry_out)); - lock_release(dlg->dlg_out_entries_lock); - } + var = dlg->vars; + dlg->vars = dlg->vars->next; + shm_free(var->key.s); + shm_free(var->value.s); + shm_free(var); + } - lock_destroy(dlg->dlg_out_entries_lock); - lock_dealloc(dlg->dlg_out_entries_lock); + if(dlg->dlg_entry_out.first) { + lock_get(dlg->dlg_out_entries_lock); + destroy_entry_out(&(dlg->dlg_entry_out)); + lock_release(dlg->dlg_out_entries_lock); + } - shm_free(dlg); + lock_destroy(dlg->dlg_out_entries_lock); + lock_dealloc(dlg->dlg_out_entries_lock); - dlg = 0; + shm_free(dlg); + dlg = 0; } /*! * \brief Destroy the global dialog table */ -void destroy_dlg_table(void) { - struct dlg_cell *dlg, *l_dlg; - unsigned int i; - - if (d_table == 0) - return; - - if (d_table->locks) { - lock_set_destroy(d_table->locks); - lock_set_dealloc(d_table->locks); - } - - for (i = 0; i < d_table->size; i++) { - dlg = d_table->entries[i].first; - while (dlg) { - l_dlg = dlg; - dlg = dlg->next; - destroy_dlg(l_dlg); - } +void destroy_dlg_table(void) +{ + struct dlg_cell *dlg, *l_dlg; + unsigned int i; + + if(d_table == 0) + return; - } + if(d_table->locks) { + lock_set_destroy(d_table->locks); + lock_set_dealloc(d_table->locks); + } + + for(i = 0; i < d_table->size; i++) { + dlg = d_table->entries[i].first; + while(dlg) { + l_dlg = dlg; + dlg = dlg->next; + destroy_dlg(l_dlg); + } + } - shm_free(d_table); - d_table = 0; + shm_free(d_table); + d_table = 0; - return; + return; } /*! @@ -307,65 +305,67 @@ void destroy_dlg_table(void) { * \param req_uri dialog r-uri * \return created dialog structure on success, NULL otherwise */ -struct dlg_cell* build_new_dlg(str *callid, str *from_uri, str *from_tag, str *req_uri) { - struct dlg_cell *dlg; - int len; - char *p; - - len = sizeof (struct dlg_cell) +callid->len + from_uri->len + req_uri->len; - dlg = (struct dlg_cell*) shm_malloc(len); - if (dlg == 0) { - LM_ERR("no more shm mem (%d)\n", len); - return 0; - } +struct dlg_cell *build_new_dlg( + str *callid, str *from_uri, str *from_tag, str *req_uri) +{ + struct dlg_cell *dlg; + int len; + char *p; - memset(dlg, 0, len); + len = sizeof(struct dlg_cell) + callid->len + from_uri->len + req_uri->len; + dlg = (struct dlg_cell *)shm_malloc(len); + if(dlg == 0) { + LM_ERR("no more shm mem (%d)\n", len); + return 0; + } - dlg->dlg_out_entries_lock = lock_alloc(); - if (dlg->dlg_out_entries_lock == NULL) { - LM_ERR("Cannot allocate lock for dlg out entries. Aborting...\n"); - shm_free(dlg); - return 0; - } else { - if (lock_init(dlg->dlg_out_entries_lock) == NULL) { - LM_ERR("Cannot init the lock for dlg out entries. Aborting...\n"); - lock_destroy(dlg->dlg_out_entries_lock); - lock_dealloc(dlg->dlg_out_entries_lock); - shm_free(dlg); - return 0; - } - } + memset(dlg, 0, len); - dlg->state = DLG_STATE_UNCONFIRMED; + dlg->dlg_out_entries_lock = lock_alloc(); + if(dlg->dlg_out_entries_lock == NULL) { + LM_ERR("Cannot allocate lock for dlg out entries. Aborting...\n"); + shm_free(dlg); + return 0; + } else { + if(lock_init(dlg->dlg_out_entries_lock) == NULL) { + LM_ERR("Cannot init the lock for dlg out entries. Aborting...\n"); + lock_destroy(dlg->dlg_out_entries_lock); + lock_dealloc(dlg->dlg_out_entries_lock); + shm_free(dlg); + return 0; + } + } + + dlg->state = DLG_STATE_UNCONFIRMED; dlg->init_ts = (unsigned int)time(NULL); - dlg->h_entry = core_hash(callid, 0, d_table->size); - LM_DBG("new dialog on hash %u\n", dlg->h_entry); + dlg->h_entry = core_hash(callid, 0, d_table->size); + LM_DBG("new dialog on hash %u\n", dlg->h_entry); - p = (char*) (dlg + 1); + p = (char *)(dlg + 1); - dlg->callid.s = p; - dlg->callid.len = callid->len; - memcpy(p, callid->s, callid->len); - p += callid->len; + dlg->callid.s = p; + dlg->callid.len = callid->len; + memcpy(p, callid->s, callid->len); + p += callid->len; - dlg->from_uri.s = p; - dlg->from_uri.len = from_uri->len; - memcpy(p, from_uri->s, from_uri->len); - p += from_uri->len; + dlg->from_uri.s = p; + dlg->from_uri.len = from_uri->len; + memcpy(p, from_uri->s, from_uri->len); + p += from_uri->len; - dlg->req_uri.s = p; - dlg->req_uri.len = req_uri->len; - memcpy(p, req_uri->s, req_uri->len); - p += req_uri->len; + dlg->req_uri.s = p; + dlg->req_uri.len = req_uri->len; + memcpy(p, req_uri->s, req_uri->len); + p += req_uri->len; - if (p != (((char*) dlg) + len)) { - LM_CRIT("buffer overflow\n"); - shm_free(dlg); - return 0; - } + if(p != (((char *)dlg) + len)) { + LM_CRIT("buffer overflow\n"); + shm_free(dlg); + return 0; + } - return dlg; + return dlg; } /*! @@ -379,111 +379,122 @@ struct dlg_cell* build_new_dlg(str *callid, str *from_uri, str *from_tag, str *r * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG * \return 0 on success, -1 on failure */ -int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact, - str *cseq, struct socket_info *bind_addr, unsigned int leg) { - - if (!dlg) { - return -1; - } - - //create new dlg_out entry - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - - if (leg == DLG_CALLER_LEG) { - if (tag->len > 0) { - dlg->from_tag.s = (char*) shm_malloc(tag->len); - if (!dlg->from_tag.s) { - LM_ERR("no more shm_mem\n"); - return -1; - } - memcpy(dlg->from_tag.s, tag->s, tag->len); - dlg->from_tag.len = tag->len; - } - if (contact->len > 0) { - dlg->caller_contact.s = (char*) shm_malloc(contact->len); - if (!dlg->caller_contact.s) { - LM_ERR("no more shm_mem\n"); - return -1; - } - memcpy(dlg->caller_contact.s, contact->s, contact->len); - dlg->caller_contact.len = contact->len; - } - if (rr->len > 0) { - dlg->caller_route_set.s = (char*) shm_malloc(rr->len); - if (!dlg->caller_route_set.s) { - LM_ERR("no more shm_mem\n"); - return -1; - } - memcpy(dlg->caller_route_set.s, rr->s, rr->len); - dlg->caller_route_set.len = rr->len; - } - if (cseq->len > 0) { - dlg->first_req_cseq.s = (char*) shm_malloc(cseq->len); - if (!dlg->first_req_cseq.s) { - LM_ERR("no more shm_mem\n"); - return -1; - } - memcpy(dlg->first_req_cseq.s, cseq->s, cseq->len); - dlg->first_req_cseq.len = cseq->len; - } - } else { - /* this is the callee side so we need to find the dialog_out entry with the correct to_tag +int dlg_set_leg_info(struct dlg_cell *dlg, str *tag, str *rr, str *contact, + str *cseq, struct socket_info *bind_addr, unsigned int leg) +{ + + if(!dlg) { + return -1; + } + + //create new dlg_out entry + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + + if(leg == DLG_CALLER_LEG) { + if(tag->len > 0) { + dlg->from_tag.s = (char *)shm_malloc(tag->len); + if(!dlg->from_tag.s) { + LM_ERR("no more shm_mem\n"); + return -1; + } + memcpy(dlg->from_tag.s, tag->s, tag->len); + dlg->from_tag.len = tag->len; + } + if(contact->len > 0) { + dlg->caller_contact.s = (char *)shm_malloc(contact->len); + if(!dlg->caller_contact.s) { + LM_ERR("no more shm_mem\n"); + return -1; + } + memcpy(dlg->caller_contact.s, contact->s, contact->len); + dlg->caller_contact.len = contact->len; + } + if(rr->len > 0) { + dlg->caller_route_set.s = (char *)shm_malloc(rr->len); + if(!dlg->caller_route_set.s) { + LM_ERR("no more shm_mem\n"); + return -1; + } + memcpy(dlg->caller_route_set.s, rr->s, rr->len); + dlg->caller_route_set.len = rr->len; + } + if(cseq->len > 0) { + dlg->first_req_cseq.s = (char *)shm_malloc(cseq->len); + if(!dlg->first_req_cseq.s) { + LM_ERR("no more shm_mem\n"); + return -1; + } + memcpy(dlg->first_req_cseq.s, cseq->s, cseq->len); + dlg->first_req_cseq.len = cseq->len; + } + } else { + /* this is the callee side so we need to find the dialog_out entry with the correct to_tag and assign caller and callee cseq, callee contact, callee route_set */ - if (d_entry_out) { - lock_get(dlg->dlg_out_entries_lock); - dlg_out = d_entry_out->first; - while (dlg_out) { - LM_DBG("Searching out dialog with to_tag '%.*s' (looking for %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s, tag->len, tag->s); - - if (dlg_out->to_tag.len == tag->len && memcmp(dlg_out->to_tag.s, tag->s, dlg_out->to_tag.len) == 0) { - LM_DBG("Found dialog_out entry with correct to_tag - updating leg info\n"); - - if (contact->len > 0) { - dlg_out->callee_contact.s = (char*) shm_malloc(contact->len); - if (!dlg_out->callee_contact.s) { - LM_ERR("no more shm mem\n"); + if(d_entry_out) { + lock_get(dlg->dlg_out_entries_lock); + dlg_out = d_entry_out->first; + while(dlg_out) { + LM_DBG("Searching out dialog with to_tag '%.*s' (looking for " + "%.*s\n", + dlg_out->to_tag.len, dlg_out->to_tag.s, tag->len, + tag->s); + + if(dlg_out->to_tag.len == tag->len + && memcmp(dlg_out->to_tag.s, tag->s, + dlg_out->to_tag.len) + == 0) { + LM_DBG("Found dialog_out entry with correct to_tag - " + "updating leg info\n"); + + if(contact->len > 0) { + dlg_out->callee_contact.s = + (char *)shm_malloc(contact->len); + if(!dlg_out->callee_contact.s) { + LM_ERR("no more shm mem\n"); lock_release(dlg->dlg_out_entries_lock); - return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway - } - dlg_out->callee_contact.len = contact->len; - memcpy(dlg_out->callee_contact.s, contact->s, contact->len); - } - if (rr->len > 0) { - dlg_out->callee_route_set.s = (char*) shm_malloc(rr->len); - if (!dlg_out->callee_route_set.s) { - LM_ERR("no more shm mem\n"); + return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway + } + dlg_out->callee_contact.len = contact->len; + memcpy(dlg_out->callee_contact.s, contact->s, + contact->len); + } + if(rr->len > 0) { + dlg_out->callee_route_set.s = + (char *)shm_malloc(rr->len); + if(!dlg_out->callee_route_set.s) { + LM_ERR("no more shm mem\n"); lock_release(dlg->dlg_out_entries_lock); - return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway - } - dlg_out->callee_route_set.len = rr->len; - memcpy(dlg_out->callee_route_set.s, rr->s, rr->len); - } - if (cseq->len > 0) { - dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len); - dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len); - if (!dlg_out->callee_cseq.s || !dlg_out->caller_cseq.s) { - LM_ERR("no more shm mem\n"); + return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway + } + dlg_out->callee_route_set.len = rr->len; + memcpy(dlg_out->callee_route_set.s, rr->s, rr->len); + } + if(cseq->len > 0) { + dlg_out->callee_cseq.s = (char *)shm_malloc(cseq->len); + dlg_out->caller_cseq.s = (char *)shm_malloc(cseq->len); + if(!dlg_out->callee_cseq.s || !dlg_out->caller_cseq.s) { + LM_ERR("no more shm mem\n"); lock_release(dlg->dlg_out_entries_lock); - return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway - } - dlg_out->caller_cseq.len = cseq->len; - memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); - dlg_out->callee_cseq.len = cseq->len; - memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); - } - dlg_out->callee_bind_addr = bind_addr; - } - dlg_out = dlg_out->next; - } - lock_release(dlg->dlg_out_entries_lock); - } else { - LM_ERR("This dialog has no dialog out entries\n"); - return -1; - } - } - return 0; + return -1; //if we're out of mem we don't really care about cleaning up - prob going to crash anyway + } + dlg_out->caller_cseq.len = cseq->len; + memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); + dlg_out->callee_cseq.len = cseq->len; + memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); + } + dlg_out->callee_bind_addr = bind_addr; + } + dlg_out = dlg_out->next; + } + lock_release(dlg->dlg_out_entries_lock); + } else { + LM_ERR("This dialog has no dialog out entries\n"); + return -1; + } + } + return 0; } /*! @@ -494,67 +505,67 @@ int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact, * \param branch dialog branch * \return created dlg_out structure on success, NULL otherwise */ -struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str* to_uri, str* to_tag, str* branch) { - - struct dlg_cell_out *dlg_out; - int len; - char *p; +struct dlg_cell_out *build_new_dlg_out( + struct dlg_cell *dlg, str *to_uri, str *to_tag, str *branch) +{ - //len = sizeof (struct dlg_cell_out) +dlg->did.len + to_tag->len + to_uri->len; - len = sizeof (struct dlg_cell_out) +to_tag->len + to_uri->len + branch->len; + struct dlg_cell_out *dlg_out; + int len; + char *p; - dlg_out = (struct dlg_cell_out*) shm_malloc(len); - if (dlg_out == 0) { - LM_ERR("no more shm mem (%d)\n", len); - return 0; - } - memset(dlg_out, 0, len); + //len = sizeof (struct dlg_cell_out) +dlg->did.len + to_tag->len + to_uri->len; + len = sizeof(struct dlg_cell_out) + to_tag->len + to_uri->len + branch->len; - dlg_out->h_entry = core_hash(to_tag, 0, dlg_hash_size_out); - LM_DBG("new dialog_out on hash %u\n", dlg_out->h_entry); + dlg_out = (struct dlg_cell_out *)shm_malloc(len); + if(dlg_out == 0) { + LM_ERR("no more shm mem (%d)\n", len); + return 0; + } + memset(dlg_out, 0, len); - p = (char*) (dlg_out + 1); + dlg_out->h_entry = core_hash(to_tag, 0, dlg_hash_size_out); + LM_DBG("new dialog_out on hash %u\n", dlg_out->h_entry); - if (branch && branch->len > 0) { - dlg_out->branch.s = p; - dlg_out->branch.len = branch->len; - memcpy(p, branch->s, branch->len); - p += branch->len; - } + p = (char *)(dlg_out + 1); - dlg_out->to_uri.s = p; - dlg_out->to_uri.len = to_uri->len; - memcpy(p, to_uri->s, to_uri->len); - p += to_uri->len; + if(branch && branch->len > 0) { + dlg_out->branch.s = p; + dlg_out->branch.len = branch->len; + memcpy(p, branch->s, branch->len); + p += branch->len; + } - dlg_out->to_tag.s = p; - dlg_out->to_tag.len = to_tag->len; - memcpy(p, to_tag->s, to_tag->len); - p += to_tag->len; + dlg_out->to_uri.s = p; + dlg_out->to_uri.len = to_uri->len; + memcpy(p, to_uri->s, to_uri->len); + p += to_uri->len; - if (p != (((char*) dlg_out) + len)) { - LM_CRIT("buffer overflow\n"); - shm_free(dlg_out); + dlg_out->to_tag.s = p; + dlg_out->to_tag.len = to_tag->len; + memcpy(p, to_tag->s, to_tag->len); + p += to_tag->len; - return 0; - } - - //did might be updated (check update_did_dlg_out) if there is a concurrent call -therefore this should not be done as single block of memory - //so Richard editted this to not have did in the single block of memory - if (dlg->did.len > 0) { - dlg_out->did.s = (char*) shm_malloc(dlg->did.len); - if (!dlg_out->did.s) { - LM_ERR("no more shm_mem\n"); - return 0; - } - memcpy(dlg_out->did.s, dlg->did.s, dlg->did.len); - dlg_out->did.len = dlg->did.len; - } + if(p != (((char *)dlg_out) + len)) { + LM_CRIT("buffer overflow\n"); + shm_free(dlg_out); + return 0; + } + //did might be updated (check update_did_dlg_out) if there is a concurrent call -therefore this should not be done as single block of memory + //so Richard editted this to not have did in the single block of memory + if(dlg->did.len > 0) { + dlg_out->did.s = (char *)shm_malloc(dlg->did.len); + if(!dlg_out->did.s) { + LM_ERR("no more shm_mem\n"); + return 0; + } + memcpy(dlg_out->did.s, dlg->did.s, dlg->did.len); + dlg_out->did.len = dlg->did.len; + } - return dlg_out; + return dlg_out; } /*! @@ -562,26 +573,27 @@ struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str* to_uri, str* t * \param dlg_out structure * \return void */ -void free_dlg_out_cell(struct dlg_cell_out *dlg_out) { - if (dlg_out->callee_contact.s) - shm_free(dlg_out->callee_contact.s); - if (dlg_out->callee_cseq.s) - shm_free(dlg_out->callee_cseq.s); - if (dlg_out->callee_route_set.s) - shm_free(dlg_out->callee_route_set.s); - if (dlg_out->caller_cseq.s) - shm_free(dlg_out->caller_cseq.s); - - //Richard removed this - it is free-ed two lines above!!??! - //if (dlg_out->callee_route_set.s) - // shm_free(dlg_out->callee_route_set.s); - - //Richard added this as the did is now malloc-ed separately and not as a single concurrent block (as the totag etc. are) - if (dlg_out->did.s) - shm_free(dlg_out->did.s); - - - shm_free(dlg_out); +void free_dlg_out_cell(struct dlg_cell_out *dlg_out) +{ + if(dlg_out->callee_contact.s) + shm_free(dlg_out->callee_contact.s); + if(dlg_out->callee_cseq.s) + shm_free(dlg_out->callee_cseq.s); + if(dlg_out->callee_route_set.s) + shm_free(dlg_out->callee_route_set.s); + if(dlg_out->caller_cseq.s) + shm_free(dlg_out->caller_cseq.s); + + //Richard removed this - it is free-ed two lines above!!??! + //if (dlg_out->callee_route_set.s) + // shm_free(dlg_out->callee_route_set.s); + + //Richard added this as the did is now malloc-ed separately and not as a single concurrent block (as the totag etc. are) + if(dlg_out->did.s) + shm_free(dlg_out->did.s); + + + shm_free(dlg_out); } /*! @@ -590,58 +602,58 @@ void free_dlg_out_cell(struct dlg_cell_out *dlg_out) { * \param to_tag dialog to tag * \return void */ -void dlg_remove_dlg_out_tag(struct dlg_cell *dlg, str *to_tag) { - - lock_get(dlg->dlg_out_entries_lock); - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *pdlg_out = d_entry_out->first; - struct dlg_cell_out *tmpdlg = 0; - - int only = 0; - - while (pdlg_out) { - if (pdlg_out->deleted) { - LM_DBG("Found dlg_out to remove\n"); - if (pdlg_out->prev) { - pdlg_out->prev->next = pdlg_out->next; - } else { - //assume that we are first - if (pdlg_out->next) { - d_entry_out->first = pdlg_out->next; - pdlg_out->next->prev = 0; - } else { - LM_ERR("dlg out entry has prev set to null and next set to null too\n"); - only = 1; - } - } - if (pdlg_out->next) { - pdlg_out->next->prev = pdlg_out->prev; - } else { - //we are likely the last - if (pdlg_out->prev) { - d_entry_out->last = pdlg_out->prev; - } else { - LM_ERR("dlg out next is NULL and so is prev"); - only = 1; - } - } - tmpdlg = pdlg_out->next; - free_dlg_out_cell(pdlg_out); - pdlg_out = tmpdlg; - - if (only) { - d_entry_out->last = 0; - d_entry_out->first = 0; - } - - } else { - LM_DBG("Not deleting dlg_out as it is not set to deleted\n"); - pdlg_out = pdlg_out->next; - } - - } - lock_release(dlg->dlg_out_entries_lock); +void dlg_remove_dlg_out_tag(struct dlg_cell *dlg, str *to_tag) +{ + lock_get(dlg->dlg_out_entries_lock); + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *pdlg_out = d_entry_out->first; + struct dlg_cell_out *tmpdlg = 0; + + int only = 0; + + while(pdlg_out) { + if(pdlg_out->deleted) { + LM_DBG("Found dlg_out to remove\n"); + if(pdlg_out->prev) { + pdlg_out->prev->next = pdlg_out->next; + } else { + //assume that we are first + if(pdlg_out->next) { + d_entry_out->first = pdlg_out->next; + pdlg_out->next->prev = 0; + } else { + LM_ERR("dlg out entry has prev set to null and next set to " + "null too\n"); + only = 1; + } + } + if(pdlg_out->next) { + pdlg_out->next->prev = pdlg_out->prev; + } else { + //we are likely the last + if(pdlg_out->prev) { + d_entry_out->last = pdlg_out->prev; + } else { + LM_ERR("dlg out next is NULL and so is prev"); + only = 1; + } + } + tmpdlg = pdlg_out->next; + free_dlg_out_cell(pdlg_out); + pdlg_out = tmpdlg; + + if(only) { + d_entry_out->last = 0; + d_entry_out->first = 0; + } + + } else { + LM_DBG("Not deleting dlg_out as it is not set to deleted\n"); + pdlg_out = pdlg_out->next; + } + } + lock_release(dlg->dlg_out_entries_lock); } /*! @@ -652,59 +664,67 @@ void dlg_remove_dlg_out_tag(struct dlg_cell *dlg, str *to_tag) { * \return void */ -void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, struct dlg_cell *dlg, int only_mark) { - - lock_get(dlg->dlg_out_entries_lock); - //get dlg_out_entry list from dlg - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - - //check if list is empty - if ((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) { - LM_DBG("There are no dlg_out entries\n"); - lock_release(dlg->dlg_out_entries_lock); - return; - } - - dlg_out = d_entry_out->first; - LM_DBG("Scanning dlg_entry_out list for dlg_out entry with did: [%s]", dlg->did.s); - //run through the list and for each dlg_out_entry: - while (dlg_out) { - - //check if it is the dlg_out that we don't want to remove (compare the to-tags) - if (dlg_out->to_tag.len == dlg_out_do_not_remove->to_tag.len && - memcmp(dlg_out->to_tag.s, dlg_out_do_not_remove->to_tag.s, dlg_out->to_tag.len) == 0) { - LM_DBG("This is the dlg_out not to be removed!\n"); - } else { - //check if this the last entry in the entry_table - if (d_entry_out->first == d_entry_out->last) { - //we shouldnt ever get here - LM_DBG("This is the last dlg_out_entry in the dlg_entries_out\n"); - //this is the last then set entry_out-> first and entry_out->last to zero - dlg->dlg_entry_out.first = dlg->dlg_entry_out.last = 0; - } else { - if (!only_mark) { - LM_DBG("Deleting dlg out structure\n"); - if (dlg_out->prev) { - dlg_out->prev->next = dlg_out->next; - } - - //make the next->previous dlg_out point to the previous of this dlg_out - //do not do this if this is the last entry in the list as the next struct is null - if (dlg_out->next) { - dlg_out->next->prev = dlg_out->prev; - } - - free_dlg_out_cell(dlg_out); - } else { - LM_DBG("Marking dlg_out structure for deletion - it should be deleted by tm callback instead to_tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s); - dlg_out->deleted = 1; - } - } - } - dlg_out = dlg_out->next; - } - lock_release(dlg->dlg_out_entries_lock); +void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, + struct dlg_cell *dlg, int only_mark) +{ + + lock_get(dlg->dlg_out_entries_lock); + //get dlg_out_entry list from dlg + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + + //check if list is empty + if((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) { + LM_DBG("There are no dlg_out entries\n"); + lock_release(dlg->dlg_out_entries_lock); + return; + } + + dlg_out = d_entry_out->first; + LM_DBG("Scanning dlg_entry_out list for dlg_out entry with did: [%s]", + dlg->did.s); + //run through the list and for each dlg_out_entry: + while(dlg_out) { + + //check if it is the dlg_out that we don't want to remove (compare the to-tags) + if(dlg_out->to_tag.len == dlg_out_do_not_remove->to_tag.len + && memcmp(dlg_out->to_tag.s, dlg_out_do_not_remove->to_tag.s, + dlg_out->to_tag.len) + == 0) { + LM_DBG("This is the dlg_out not to be removed!\n"); + } else { + //check if this the last entry in the entry_table + if(d_entry_out->first == d_entry_out->last) { + //we shouldnt ever get here + LM_DBG("This is the last dlg_out_entry in the " + "dlg_entries_out\n"); + //this is the last then set entry_out-> first and entry_out->last to zero + dlg->dlg_entry_out.first = dlg->dlg_entry_out.last = 0; + } else { + if(!only_mark) { + LM_DBG("Deleting dlg out structure\n"); + if(dlg_out->prev) { + dlg_out->prev->next = dlg_out->next; + } + + //make the next->previous dlg_out point to the previous of this dlg_out + //do not do this if this is the last entry in the list as the next struct is null + if(dlg_out->next) { + dlg_out->next->prev = dlg_out->prev; + } + + free_dlg_out_cell(dlg_out); + } else { + LM_DBG("Marking dlg_out structure for deletion - it should " + "be deleted by tm callback instead to_tag: %.*s\n", + dlg_out->to_tag.len, dlg_out->to_tag.s); + dlg_out->deleted = 1; + } + } + } + dlg_out = dlg_out->next; + } + lock_release(dlg->dlg_out_entries_lock); } /*! @@ -715,73 +735,77 @@ void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, struct dlg_c * \param to_tag dialog to tag * \return 0 on success, -1 on failure */ -int dlg_update_cseq(struct dlg_cell * dlg, unsigned int leg, str *cseq, str *to_tag) { - LM_DBG("trying to update cseq with seq [%.*s]\n", cseq->len, cseq->s); - - - //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller cseq accordingly - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - dlg_out = d_entry_out->first; - if (to_tag) { - - //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) - while (dlg_out) { - - if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) { - //this parameter matches we have found the dlg_out to update the cseq - - if (leg == DLG_CALLER_LEG) { - //update caller cseq - if (dlg_out->caller_cseq.s) { - if (dlg_out->caller_cseq.len < cseq->len) { - shm_free(dlg_out->caller_cseq.s); - dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len); - if (dlg_out->caller_cseq.s == NULL) - goto error; - dlg_out->caller_cseq.len = cseq->len; - memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); - } - } else { - dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len); - if (dlg_out->caller_cseq.s == NULL) - goto error; - - dlg_out->caller_cseq.len = cseq->len; - memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); - } - - } else if (leg == DLG_CALLEE_LEG) { - //update callee cseq - if (dlg_out->callee_cseq.s) { - if (dlg_out->callee_cseq.len < cseq->len) { - shm_free(dlg_out->callee_cseq.s); - dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len); - if (dlg_out->callee_cseq.s == NULL) - goto error; - - dlg_out->callee_cseq.len = cseq->len; - memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); - } - } else { - dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len); - if (dlg_out->callee_cseq.s == NULL) - goto error; - - dlg_out->callee_cseq.len = cseq->len; - memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); - } - - } - } - dlg_out = dlg_out->next; - } - - } - return 0; +int dlg_update_cseq( + struct dlg_cell *dlg, unsigned int leg, str *cseq, str *to_tag) +{ + LM_DBG("trying to update cseq with seq [%.*s]\n", cseq->len, cseq->s); + + + //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller cseq accordingly + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + dlg_out = d_entry_out->first; + if(to_tag) { + + //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) + while(dlg_out) { + + if(dlg_out->to_tag.len == to_tag->len + && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) + == 0) { + //this parameter matches we have found the dlg_out to update the cseq + + if(leg == DLG_CALLER_LEG) { + //update caller cseq + if(dlg_out->caller_cseq.s) { + if(dlg_out->caller_cseq.len < cseq->len) { + shm_free(dlg_out->caller_cseq.s); + dlg_out->caller_cseq.s = + (char *)shm_malloc(cseq->len); + if(dlg_out->caller_cseq.s == NULL) + goto error; + dlg_out->caller_cseq.len = cseq->len; + memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); + } + } else { + dlg_out->caller_cseq.s = (char *)shm_malloc(cseq->len); + if(dlg_out->caller_cseq.s == NULL) + goto error; + + dlg_out->caller_cseq.len = cseq->len; + memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len); + } + + } else if(leg == DLG_CALLEE_LEG) { + //update callee cseq + if(dlg_out->callee_cseq.s) { + if(dlg_out->callee_cseq.len < cseq->len) { + shm_free(dlg_out->callee_cseq.s); + dlg_out->callee_cseq.s = + (char *)shm_malloc(cseq->len); + if(dlg_out->callee_cseq.s == NULL) + goto error; + + dlg_out->callee_cseq.len = cseq->len; + memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); + } + } else { + dlg_out->callee_cseq.s = (char *)shm_malloc(cseq->len); + if(dlg_out->callee_cseq.s == NULL) + goto error; + + dlg_out->callee_cseq.len = cseq->len; + memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len); + } + } + } + dlg_out = dlg_out->next; + } + } + return 0; error: - LM_ERR("not more shm mem\n"); - return -1; + LM_ERR("not more shm mem\n"); + return -1; } /*! @@ -792,73 +816,81 @@ int dlg_update_cseq(struct dlg_cell * dlg, unsigned int leg, str *cseq, str *to_ * \param to_tag dialog to tag * \return 0 on success, -1 on failure */ -int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *contact, str *to_tag) { - LM_DBG("trying to update contact with contact [%.*s]\n", contact->len, contact->s); - - //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller contact accordingly - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - dlg_out = d_entry_out->first; - - if (leg == DLG_CALLER_LEG) { - //update caller contact - if (dlg->caller_contact.s) { - if (dlg->caller_contact.len < contact->len) { - shm_free(dlg->caller_contact.s); - dlg->caller_contact.s = (char*) shm_malloc(contact->len); - if (dlg->caller_contact.s == NULL) - goto error; - dlg->caller_contact.len = contact->len; - memcpy(dlg->caller_contact.s, contact->s, contact->len); - } - } else { - dlg->caller_contact.s = (char*) shm_malloc(contact->len); - if (dlg->caller_contact.s == NULL) - goto error; - - dlg->caller_contact.len = contact->len; - memcpy(dlg->caller_contact.s, contact->s, contact->len); - } - } - if (leg == DLG_CALLEE_LEG) { - //update callee contact - if (!to_tag) { - LM_ERR("No to tag to identify dlg_out\n"); - return -1; - } - //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) - while (dlg_out) { - - if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) { - //this parameter matches we have found the dlg_out to update the callee contact - - //update callee contact - if (dlg_out->callee_contact.s) { - if (dlg_out->callee_contact.len < contact->len) { - shm_free(dlg_out->callee_contact.s); - dlg_out->callee_contact.s = (char*) shm_malloc(contact->len); - if (dlg_out->callee_contact.s == NULL) - goto error; - - dlg_out->callee_contact.len = contact->len; - memcpy(dlg_out->callee_contact.s, contact->s, contact->len); - } - } else { - dlg_out->callee_contact.s = (char*) shm_malloc(contact->len); - if (dlg_out->callee_contact.s == NULL) - goto error; - - dlg_out->callee_contact.len = contact->len; - memcpy(dlg_out->callee_contact.s, contact->s, contact->len); - } - } - dlg_out = dlg_out->next; - } - } - return 0; +int dlg_update_contact( + struct dlg_cell *dlg, unsigned int leg, str *contact, str *to_tag) +{ + LM_DBG("trying to update contact with contact [%.*s]\n", contact->len, + contact->s); + + //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller contact accordingly + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + dlg_out = d_entry_out->first; + + if(leg == DLG_CALLER_LEG) { + //update caller contact + if(dlg->caller_contact.s) { + if(dlg->caller_contact.len < contact->len) { + shm_free(dlg->caller_contact.s); + dlg->caller_contact.s = (char *)shm_malloc(contact->len); + if(dlg->caller_contact.s == NULL) + goto error; + dlg->caller_contact.len = contact->len; + memcpy(dlg->caller_contact.s, contact->s, contact->len); + } + } else { + dlg->caller_contact.s = (char *)shm_malloc(contact->len); + if(dlg->caller_contact.s == NULL) + goto error; + + dlg->caller_contact.len = contact->len; + memcpy(dlg->caller_contact.s, contact->s, contact->len); + } + } + if(leg == DLG_CALLEE_LEG) { + //update callee contact + if(!to_tag) { + LM_ERR("No to tag to identify dlg_out\n"); + return -1; + } + //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) + while(dlg_out) { + + if(dlg_out->to_tag.len == to_tag->len + && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) + == 0) { + //this parameter matches we have found the dlg_out to update the callee contact + + //update callee contact + if(dlg_out->callee_contact.s) { + if(dlg_out->callee_contact.len < contact->len) { + shm_free(dlg_out->callee_contact.s); + dlg_out->callee_contact.s = + (char *)shm_malloc(contact->len); + if(dlg_out->callee_contact.s == NULL) + goto error; + + dlg_out->callee_contact.len = contact->len; + memcpy(dlg_out->callee_contact.s, contact->s, + contact->len); + } + } else { + dlg_out->callee_contact.s = + (char *)shm_malloc(contact->len); + if(dlg_out->callee_contact.s == NULL) + goto error; + + dlg_out->callee_contact.len = contact->len; + memcpy(dlg_out->callee_contact.s, contact->s, contact->len); + } + } + dlg_out = dlg_out->next; + } + } + return 0; error: - LM_ERR("not more shm mem\n"); - return -1; + LM_ERR("not more shm mem\n"); + return -1; } /*! @@ -870,32 +902,33 @@ int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *contact, st * \param h_id id of the hash table entry * \return dialog structure on success, NULL on failure */ -struct dlg_cell * lookup_dlg(unsigned int h_entry, unsigned int h_id) { - struct dlg_cell *dlg; - struct dlg_entry *d_entry; +struct dlg_cell *lookup_dlg(unsigned int h_entry, unsigned int h_id) +{ + struct dlg_cell *dlg; + struct dlg_entry *d_entry; - if (h_entry >= d_table->size) - goto not_found; + if(h_entry >= d_table->size) + goto not_found; - d_entry = &(d_table->entries[h_entry]); + d_entry = &(d_table->entries[h_entry]); - dlg_lock(d_table, d_entry); + dlg_lock(d_table, d_entry); - for (dlg = d_entry->first; dlg; dlg = dlg->next) { - if (dlg->h_id == h_id) { -// backtrace2str(0,0); - ref_dlg_unsafe(dlg, 1); - dlg_unlock(d_table, d_entry); - LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry); - return dlg; - } - } + for(dlg = d_entry->first; dlg; dlg = dlg->next) { + if(dlg->h_id == h_id) { + // backtrace2str(0,0); + ref_dlg_unsafe(dlg, 1); + dlg_unlock(d_table, d_entry); + LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry); + return dlg; + } + } - dlg_unlock(d_table, d_entry); + dlg_unlock(d_table, d_entry); not_found: - LM_DBG("no dialog id=%u found on entry %u\n", h_id, h_entry); + LM_DBG("no dialog id=%u found on entry %u\n", h_id, h_entry); - return 0; + return 0; } /*! @@ -909,31 +942,33 @@ struct dlg_cell * lookup_dlg(unsigned int h_entry, unsigned int h_id) { * \param mode let hash table slot locked if dialog is not found * \return dialog structure on success, NULL on failure */ -static inline struct dlg_cell * internal_get_dlg(unsigned int h_entry, - str *callid, str *ftag, str *ttag, unsigned int *dir, unsigned int mode) { - struct dlg_cell *dlg; +static inline struct dlg_cell *internal_get_dlg(unsigned int h_entry, + str *callid, str *ftag, str *ttag, unsigned int *dir, unsigned int mode) +{ + struct dlg_cell *dlg; struct dlg_entry *d_entry; d_entry = &(d_table->entries[h_entry]); - dlg_lock( d_table, d_entry); - - for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) { + dlg_lock(d_table, d_entry); + + for(dlg = d_entry->first; dlg; dlg = dlg->next) { /* Check callid / fromtag / totag */ - if (match_dialog( dlg, callid, ftag, ttag, dir)==1) { + if(match_dialog(dlg, callid, ftag, ttag, dir) == 1) { ref_dlg_unsafe(dlg, 1); - dlg_unlock( d_table, d_entry); + dlg_unlock(d_table, d_entry); LM_DBG("dialog callid='%.*s' found on entry %u, dir=%d\n", - callid->len, callid->s,h_entry,*dir); + callid->len, callid->s, h_entry, *dir); return dlg; } } - if(likely(mode==0)) dlg_unlock( d_table, d_entry); + if(likely(mode == 0)) + dlg_unlock(d_table, d_entry); LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s); return 0; - return 0; + return 0; } /*! @@ -952,18 +987,19 @@ static inline struct dlg_cell * internal_get_dlg(unsigned int h_entry, * \param dir direction * \return dialog structure on success, NULL on failure */ -struct dlg_cell * get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir) { - struct dlg_cell *dlg; - unsigned int he; +struct dlg_cell *get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir) +{ + struct dlg_cell *dlg; + unsigned int he; - he = core_hash(callid, 0, d_table->size); - dlg = internal_get_dlg(he, callid, ftag, ttag, dir, 0); + he = core_hash(callid, 0, d_table->size); + dlg = internal_get_dlg(he, callid, ftag, ttag, dir, 0); - if (dlg == 0) { - LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s); - return 0; - } - return dlg; + if(dlg == 0) { + LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s); + return 0; + } + return dlg; } /*! @@ -972,30 +1008,31 @@ struct dlg_cell * get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir) * \param dlg_out dialog out * \param n extra increments for the reference counter */ -void link_dlg_out(struct dlg_cell *dlg, struct dlg_cell_out *dlg_out, int n) { - LM_DBG("Start: link_dlg_out\n"); - - lock_get(dlg->dlg_out_entries_lock); - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - - if ((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) { - //adding first out dialog - LM_DBG("Adding first dlg_out structure\n"); - d_entry_out->first = dlg_out; - d_entry_out->last = dlg_out; - } else { - LM_DBG("Adding new dlg_out structure\n"); - dlg_out->prev = d_entry_out->last; - dlg_out->next = 0; - - d_entry_out->last->next = dlg_out; - d_entry_out->last = dlg_out; - } - - lock_release(dlg->dlg_out_entries_lock); - - LM_DBG("Done: link_dlg_out\n"); - return; +void link_dlg_out(struct dlg_cell *dlg, struct dlg_cell_out *dlg_out, int n) +{ + LM_DBG("Start: link_dlg_out\n"); + + lock_get(dlg->dlg_out_entries_lock); + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + + if((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) { + //adding first out dialog + LM_DBG("Adding first dlg_out structure\n"); + d_entry_out->first = dlg_out; + d_entry_out->last = dlg_out; + } else { + LM_DBG("Adding new dlg_out structure\n"); + dlg_out->prev = d_entry_out->last; + dlg_out->next = 0; + + d_entry_out->last->next = dlg_out; + d_entry_out->last = dlg_out; + } + + lock_release(dlg->dlg_out_entries_lock); + + LM_DBG("Done: link_dlg_out\n"); + return; } /*! * \brief Link a dialog structure @@ -1003,49 +1040,53 @@ void link_dlg_out(struct dlg_cell *dlg, struct dlg_cell_out *dlg_out, int n) { * \param n extra increments for the reference counter * \param mode link in safe mode (0 - lock slot; 1 - don't) */ -void link_dlg(struct dlg_cell *dlg, int n, int mode) { - struct dlg_entry *d_entry; - - d_entry = &(d_table->entries[dlg->h_entry]); - - if (unlikely(mode == 0)) dlg_lock(d_table, d_entry); +void link_dlg(struct dlg_cell *dlg, int n, int mode) +{ + struct dlg_entry *d_entry; - /* keep id 0 for special cases */ - dlg->h_id = 1 + d_entry->next_id++; - if (dlg->h_id == 0) dlg->h_id = 1; - LM_DBG("linking dialog [%u:%u]\n", dlg->h_entry, dlg->h_id); - if (d_entry->first == 0) { - d_entry->first = d_entry->last = dlg; - } else { - d_entry->last->next = dlg; - dlg->prev = d_entry->last; - d_entry->last = dlg; - } + d_entry = &(d_table->entries[dlg->h_entry]); + + if(unlikely(mode == 0)) + dlg_lock(d_table, d_entry); + + /* keep id 0 for special cases */ + dlg->h_id = 1 + d_entry->next_id++; + if(dlg->h_id == 0) + dlg->h_id = 1; + LM_DBG("linking dialog [%u:%u]\n", dlg->h_entry, dlg->h_id); + if(d_entry->first == 0) { + d_entry->first = d_entry->last = dlg; + } else { + d_entry->last->next = dlg; + dlg->prev = d_entry->last; + d_entry->last = dlg; + } - ref_dlg_unsafe(dlg, 1 + n); + ref_dlg_unsafe(dlg, 1 + n); - if (unlikely(mode == 0)) dlg_unlock(d_table, d_entry); - return; + if(unlikely(mode == 0)) + dlg_unlock(d_table, d_entry); + return; } - /*! * \brief Refefence a dialog with locking * \see ref_dlg_unsafe * \param dlg dialog * \param cnt increment for the reference counter */ -void ref_dlg(struct dlg_cell *dlg, unsigned int cnt) { +void ref_dlg(struct dlg_cell *dlg, unsigned int cnt) +{ - struct dlg_entry *d_entry; + struct dlg_entry *d_entry; - d_entry = &(d_table->entries[dlg->h_entry]); + d_entry = &(d_table->entries[dlg->h_entry]); - dlg_lock(d_table, d_entry); -// backtrace2str(0, 0); - ref_dlg_unsafe(dlg, cnt); - dlg_unlock(d_table, d_entry); + dlg_lock(d_table, d_entry); + // backtrace2str(0, 0); + ref_dlg_unsafe(dlg, cnt); + dlg_unlock(d_table, d_entry); } @@ -1055,16 +1096,17 @@ void ref_dlg(struct dlg_cell *dlg, unsigned int cnt) { * \param dlg dialog * \param cnt decrement for the reference counter */ -void unref_dlg(struct dlg_cell *dlg, unsigned int cnt) { +void unref_dlg(struct dlg_cell *dlg, unsigned int cnt) +{ - struct dlg_entry *d_entry; + struct dlg_entry *d_entry; - d_entry = &(d_table->entries[dlg->h_entry]); + d_entry = &(d_table->entries[dlg->h_entry]); - dlg_lock(d_table, d_entry); -// backtrace2str(0, 0); - unref_dlg_unsafe(dlg, cnt, d_entry); - dlg_unlock(d_table, d_entry); + dlg_lock(d_table, d_entry); + // backtrace2str(0, 0); + unref_dlg_unsafe(dlg, cnt, d_entry); + dlg_unlock(d_table, d_entry); } /*! @@ -1073,12 +1115,15 @@ void unref_dlg(struct dlg_cell *dlg, unsigned int cnt) { * \param dlg dialog data * \see next_state_dlg */ -static inline void log_next_state_dlg(const int event, const struct dlg_cell * dlg) { +static inline void log_next_state_dlg( + const int event, const struct dlg_cell *dlg) +{ - LM_CRIT("bogus event %d in state %d for dlg %p [%u:%u] with clid '%.*s' and tags " - "'%.*s'\n", event, dlg->state, dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); + LM_CRIT("bogus event %d in state %d for dlg %p [%u:%u] with clid '%.*s' " + "and tags " + "'%.*s'\n", + event, dlg->state, dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s, dlg->from_tag.len, dlg->from_tag.s); } /*! @@ -1095,203 +1140,221 @@ static inline void log_next_state_dlg(const int event, const struct dlg_cell * d * \param unref set to 1 when the dialog was deleted, 0 otherwise * \param to_tag dialog to tag */ -void next_state_dlg(struct dlg_cell *dlg, int event, - int *old_state, int *new_state, int *unref, str * to_tag) { - struct dlg_entry *d_entry; +void next_state_dlg(struct dlg_cell *dlg, int event, int *old_state, + int *new_state, int *unref, str *to_tag) +{ + struct dlg_entry *d_entry; - d_entry = &(d_table->entries[dlg->h_entry]); + d_entry = &(d_table->entries[dlg->h_entry]); - *unref = 0; + *unref = 0; - dlg_lock(d_table, d_entry); + dlg_lock(d_table, d_entry); - *old_state = dlg->state; + *old_state = dlg->state; - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - dlg_out = d_entry_out->first; - int found = -1; - int delete = 1; + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + dlg_out = d_entry_out->first; + int found = -1; + int delete = 1; - switch (event) { - case DLG_EVENT_TDEL: - switch (dlg->state) { - case DLG_STATE_UNCONFIRMED: - case DLG_STATE_EARLY: + switch(event) { + case DLG_EVENT_TDEL: + switch(dlg->state) { + case DLG_STATE_UNCONFIRMED: + case DLG_STATE_EARLY: // dlg->state = DLG_STATE_DELETED; unref_dlg_unsafe(dlg, 1, d_entry); // *unref = 1; - break; - case DLG_STATE_CONFIRMED: - case DLG_STATE_CONFIRMED_NA: - unref_dlg_unsafe(dlg, 1, d_entry); - break; - case DLG_STATE_DELETED: - *unref = 1; - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_RPL1xx: - switch (dlg->state) { - case DLG_STATE_UNCONFIRMED: - case DLG_STATE_EARLY: - dlg->state = DLG_STATE_EARLY; - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_RPL3xx: - switch (dlg->state) { - case DLG_STATE_UNCONFIRMED: - case DLG_STATE_EARLY: - if(delete) { - dlg->state = DLG_STATE_DELETED; - *unref = 1; - } - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_RPL2xx: - switch (dlg->state) { - case DLG_STATE_DELETED: - if (dlg->dflags & DLG_FLAG_HASBYE) { - LM_CRIT("bogus event %d in state %d (with BYE) " - "for dlg %p [%u:%u] with clid '%.*s' and tags '%.*s' \n", - event, dlg->state, dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - break; - } - ref_dlg_unsafe(dlg, 1); - case DLG_STATE_UNCONFIRMED: - case DLG_STATE_EARLY: - dlg->state = DLG_STATE_CONFIRMED_NA; - break; - case DLG_STATE_CONFIRMED_NA: - case DLG_STATE_CONFIRMED: - if (to_tag) { - //compare the to_tag passed parameter to the dlg_out to_tag entry of the dlg parameter (There should be only 1 dlg_out entry) - - if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) { - //this parameter matches the existing dlg_out and is therefore a retransmission, so break - break; - } else { - - LM_ERR("It looks like this is a concurrently confirmed call!!\n"); - LM_ERR("Error checking now so not putting into DLG_STATE_CONCURRENTLY_CONFIRMED\n"); - - LM_ERR("This is event DLG_EVENT_RPL2XX and the current dlg state is DLG_STATE_CONFIRMED\n"); - LM_ERR("There should only be one dlg out here as the state is CONFIRMED but we are checking anyway!\n"); - LM_ERR("To tag passed in the 2XX: [%.*s]", to_tag->len, to_tag->s); - LM_ERR("Now printing dlgouts totags - there should be only one!\n"); - while (dlg_out) { - LM_ERR("dlg_out to_tag: [%.*s]\n", dlg_out->to_tag.len, dlg_out->to_tag.s); - dlg_out = dlg_out->next; - } - - //The parameter does not match so this is a concurrently confirmed call - //dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED; - } - } - break; - case DLG_STATE_CONCURRENTLY_CONFIRMED: - //check the to_tag passed parameter exists - if (to_tag) { - //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) - while (dlg_out) { - if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) { - //this parameter matches the existing dlg_out and is therefore a retransmission - found = 1; - } - dlg_out = dlg_out->next; - } - if (found == -1) { - //The parameter does not match so this is another concurrently confirmed call (we would have breaked by now if it matched) - dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED; - } - } else { - //to_tag parameter does not exist so break - break; - } - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_REQACK: - switch (dlg->state) { - case DLG_STATE_CONFIRMED_NA: - dlg->state = DLG_STATE_CONFIRMED; - break; - case DLG_STATE_CONFIRMED: - break; - case DLG_STATE_DELETED: - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_REQBYE: - switch (dlg->state) { - case DLG_STATE_CONFIRMED: - case DLG_STATE_CONFIRMED_NA: /* we weight towards tearing the dialog down if we get a bye - perhaps bye can beat ack*/ - dlg->dflags |= DLG_FLAG_HASBYE; - dlg->state = DLG_STATE_DELETED; - *unref = 1; - break; - case DLG_STATE_EARLY: - case DLG_STATE_DELETED: - break; - default: - log_next_state_dlg(event, dlg); - } - break; - - break; - case DLG_EVENT_REQPRACK: - switch (dlg->state) { - case DLG_STATE_EARLY: - //Richard added this - think it is necessary as can received PRACK in early state! - break; - default: - log_next_state_dlg(event, dlg); - } - break; - case DLG_EVENT_REQ: - switch (dlg->state) { - - case DLG_STATE_EARLY: - case DLG_STATE_CONFIRMED: - break; - default: - log_next_state_dlg(event, dlg); - } - break; - default: - LM_CRIT("unknown event %d in state %d " - "for dlg %p [%u:%u] with clid '%.*s' and tags '%.*s'\n", - event, dlg->state, dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s, - dlg->from_tag.len, dlg->from_tag.s); - } - *new_state = dlg->state; - - /* remove the dialog from profiles when is not no longer active */ - if (*new_state == DLG_STATE_DELETED && dlg->profile_links != NULL - && *old_state != *new_state) { - destroy_linkers(dlg->profile_links); - dlg->profile_links = NULL; - } - - dlg_unlock(d_table, d_entry); - - LM_DBG("dialog %p changed from state %d to " - "state %d, due event %d\n", dlg, *old_state, *new_state, event); + break; + case DLG_STATE_CONFIRMED: + case DLG_STATE_CONFIRMED_NA: + unref_dlg_unsafe(dlg, 1, d_entry); + break; + case DLG_STATE_DELETED: + *unref = 1; + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_RPL1xx: + switch(dlg->state) { + case DLG_STATE_UNCONFIRMED: + case DLG_STATE_EARLY: + dlg->state = DLG_STATE_EARLY; + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_RPL3xx: + switch(dlg->state) { + case DLG_STATE_UNCONFIRMED: + case DLG_STATE_EARLY: + if(delete) { + dlg->state = DLG_STATE_DELETED; + *unref = 1; + } + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_RPL2xx: + switch(dlg->state) { + case DLG_STATE_DELETED: + if(dlg->dflags & DLG_FLAG_HASBYE) { + LM_CRIT("bogus event %d in state %d (with BYE) " + "for dlg %p [%u:%u] with clid '%.*s' and tags " + "'%.*s' \n", + event, dlg->state, dlg, dlg->h_entry, dlg->h_id, + dlg->callid.len, dlg->callid.s, + dlg->from_tag.len, dlg->from_tag.s); + break; + } + ref_dlg_unsafe(dlg, 1); + case DLG_STATE_UNCONFIRMED: + case DLG_STATE_EARLY: + dlg->state = DLG_STATE_CONFIRMED_NA; + break; + case DLG_STATE_CONFIRMED_NA: + case DLG_STATE_CONFIRMED: + if(to_tag) { + //compare the to_tag passed parameter to the dlg_out to_tag entry of the dlg parameter (There should be only 1 dlg_out entry) + + if(dlg_out->to_tag.len == to_tag->len + && memcmp(dlg_out->to_tag.s, to_tag->s, + dlg_out->to_tag.len) + == 0) { + //this parameter matches the existing dlg_out and is therefore a retransmission, so break + break; + } else { + + LM_ERR("It looks like this is a concurrently " + "confirmed call!!\n"); + LM_ERR("Error checking now so not putting into " + "DLG_STATE_CONCURRENTLY_CONFIRMED\n"); + + LM_ERR("This is event DLG_EVENT_RPL2XX and the " + "current dlg state is " + "DLG_STATE_CONFIRMED\n"); + LM_ERR("There should only be one dlg out here as " + "the state is CONFIRMED but we are checking " + "anyway!\n"); + LM_ERR("To tag passed in the 2XX: [%.*s]", + to_tag->len, to_tag->s); + LM_ERR("Now printing dlgouts totags - there should " + "be only one!\n"); + while(dlg_out) { + LM_ERR("dlg_out to_tag: [%.*s]\n", + dlg_out->to_tag.len, dlg_out->to_tag.s); + dlg_out = dlg_out->next; + } + + //The parameter does not match so this is a concurrently confirmed call + //dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED; + } + } + break; + case DLG_STATE_CONCURRENTLY_CONFIRMED: + //check the to_tag passed parameter exists + if(to_tag) { + //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple) + while(dlg_out) { + if(dlg_out->to_tag.len == to_tag->len + && memcmp(dlg_out->to_tag.s, to_tag->s, + dlg_out->to_tag.len) + == 0) { + //this parameter matches the existing dlg_out and is therefore a retransmission + found = 1; + } + dlg_out = dlg_out->next; + } + if(found == -1) { + //The parameter does not match so this is another concurrently confirmed call (we would have breaked by now if it matched) + dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED; + } + } else { + //to_tag parameter does not exist so break + break; + } + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_REQACK: + switch(dlg->state) { + case DLG_STATE_CONFIRMED_NA: + dlg->state = DLG_STATE_CONFIRMED; + break; + case DLG_STATE_CONFIRMED: + break; + case DLG_STATE_DELETED: + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_REQBYE: + switch(dlg->state) { + case DLG_STATE_CONFIRMED: + case DLG_STATE_CONFIRMED_NA: /* we weight towards tearing the dialog down if we get a bye - perhaps bye can beat ack*/ + dlg->dflags |= DLG_FLAG_HASBYE; + dlg->state = DLG_STATE_DELETED; + *unref = 1; + break; + case DLG_STATE_EARLY: + case DLG_STATE_DELETED: + break; + default: + log_next_state_dlg(event, dlg); + } + break; + + break; + case DLG_EVENT_REQPRACK: + switch(dlg->state) { + case DLG_STATE_EARLY: + //Richard added this - think it is necessary as can received PRACK in early state! + break; + default: + log_next_state_dlg(event, dlg); + } + break; + case DLG_EVENT_REQ: + switch(dlg->state) { + + case DLG_STATE_EARLY: + case DLG_STATE_CONFIRMED: + break; + default: + log_next_state_dlg(event, dlg); + } + break; + default: + LM_CRIT("unknown event %d in state %d " + "for dlg %p [%u:%u] with clid '%.*s' and tags '%.*s'\n", + event, dlg->state, dlg, dlg->h_entry, dlg->h_id, + dlg->callid.len, dlg->callid.s, dlg->from_tag.len, + dlg->from_tag.s); + } + *new_state = dlg->state; + + /* remove the dialog from profiles when is not no longer active */ + if(*new_state == DLG_STATE_DELETED && dlg->profile_links != NULL + && *old_state != *new_state) { + destroy_linkers(dlg->profile_links); + dlg->profile_links = NULL; + } + + dlg_unlock(d_table, d_entry); + + LM_DBG("dialog %p changed from state %d to " + "state %d, due event %d\n", + dlg, *old_state, *new_state, event); } /*! @@ -1300,25 +1363,26 @@ void next_state_dlg(struct dlg_cell *dlg, int event, * \param route name of route * \return 0 on success, -1 on failure */ -int dlg_set_toroute(struct dlg_cell *dlg, str * route) { - if (dlg == NULL || route == NULL || route->len <= 0) - return 0; - if (dlg->toroute_name.s != NULL) { - shm_free(dlg->toroute_name.s); - dlg->toroute_name.s = NULL; - dlg->toroute_name.len = 0; - } - dlg->toroute_name.s = (char*) shm_malloc((route->len + 1) * sizeof (char)); - if (dlg->toroute_name.s == NULL) { - LM_ERR("no more shared memory\n"); - return -1; - } - memcpy(dlg->toroute_name.s, route->s, route->len); - dlg->toroute_name.len = route->len; - dlg->toroute_name.s[dlg->toroute_name.len] = '\0'; - dlg->toroute = route_lookup(&main_rt, dlg->toroute_name.s); - - return 0; +int dlg_set_toroute(struct dlg_cell *dlg, str *route) +{ + if(dlg == NULL || route == NULL || route->len <= 0) + return 0; + if(dlg->toroute_name.s != NULL) { + shm_free(dlg->toroute_name.s); + dlg->toroute_name.s = NULL; + dlg->toroute_name.len = 0; + } + dlg->toroute_name.s = (char *)shm_malloc((route->len + 1) * sizeof(char)); + if(dlg->toroute_name.s == NULL) { + LM_ERR("no more shared memory\n"); + return -1; + } + memcpy(dlg->toroute_name.s, route->s, route->len); + dlg->toroute_name.len = route->len; + dlg->toroute_name.s[dlg->toroute_name.len] = '\0'; + dlg->toroute = route_lookup(&main_rt, dlg->toroute_name.s); + + return 0; } /*! @@ -1327,17 +1391,18 @@ int dlg_set_toroute(struct dlg_cell *dlg, str * route) { * \param new_did empty container for new_did * \return void */ -void create_concurrent_did(struct dlg_cell *dlg, str * new_did) { - int len = dlg->did.len + 1 + 1; - new_did->s = shm_malloc(len); - if (new_did->s == 0) { - LM_ERR("no more shm mem (%d)\n", len); - return; - } - memset(new_did->s, 0, len); - memcpy(new_did->s, dlg->did.s, dlg->did.len); - new_did->s[dlg->did.len] = 'x'; - new_did->len = dlg->did.len + 1; +void create_concurrent_did(struct dlg_cell *dlg, str *new_did) +{ + int len = dlg->did.len + 1 + 1; + new_did->s = shm_malloc(len); + if(new_did->s == 0) { + LM_ERR("no more shm mem (%d)\n", len); + return; + } + memset(new_did->s, 0, len); + memcpy(new_did->s, dlg->did.s, dlg->did.len); + new_did->s[dlg->did.len] = 'x'; + new_did->len = dlg->did.len + 1; } /*! @@ -1346,27 +1411,28 @@ void create_concurrent_did(struct dlg_cell *dlg, str * new_did) { * \param new_did new did to use * \return 1 success, 0 failure */ -int update_dlg_out_did(struct dlg_cell_out *dlg_out, str * new_did) { - //update the did of the dlg_out - if (dlg_out->did.s) { - if (dlg_out->did.len < new_did->len) { - shm_free(dlg_out->did.s); - dlg_out->did.s = (char*) shm_malloc(new_did->len); - if (dlg_out->did.s == NULL) - goto error; - } - } else { - dlg_out->did.s = (char*) shm_malloc(new_did->len); - if (dlg_out->did.s == NULL) - goto error; - } - memcpy(dlg_out->did.s, new_did->s, new_did->len); - dlg_out->did.len = new_did->len; - - return 0; +int update_dlg_out_did(struct dlg_cell_out *dlg_out, str *new_did) +{ + //update the did of the dlg_out + if(dlg_out->did.s) { + if(dlg_out->did.len < new_did->len) { + shm_free(dlg_out->did.s); + dlg_out->did.s = (char *)shm_malloc(new_did->len); + if(dlg_out->did.s == NULL) + goto error; + } + } else { + dlg_out->did.s = (char *)shm_malloc(new_did->len); + if(dlg_out->did.s == NULL) + goto error; + } + memcpy(dlg_out->did.s, new_did->s, new_did->len); + dlg_out->did.len = new_did->len; + + return 0; error: - LM_ERR("not more shm mem\n"); - return -1; + LM_ERR("not more shm mem\n"); + return -1; } /*! @@ -1375,27 +1441,28 @@ int update_dlg_out_did(struct dlg_cell_out *dlg_out, str * new_did) { * \param new_did new did to use * \return 1 success, 0 failure */ -int update_dlg_did(struct dlg_cell *dlg, str * new_did) { - //update the did of the dlg_out - if (dlg->did.s) { - if (dlg->did.len < new_did->len) { - shm_free(dlg->did.s); - dlg->did.s = (char*) shm_malloc(new_did->len); - if (dlg->did.s == NULL) - goto error; - } - } else { - dlg->did.s = (char*) shm_malloc(new_did->len); - if (dlg->did.s == NULL) - goto error; - } - memcpy(dlg->did.s, new_did->s, new_did->len); - dlg->did.len = new_did->len; - - return 0; +int update_dlg_did(struct dlg_cell *dlg, str *new_did) +{ + //update the did of the dlg_out + if(dlg->did.s) { + if(dlg->did.len < new_did->len) { + shm_free(dlg->did.s); + dlg->did.s = (char *)shm_malloc(new_did->len); + if(dlg->did.s == NULL) + goto error; + } + } else { + dlg->did.s = (char *)shm_malloc(new_did->len); + if(dlg->did.s == NULL) + goto error; + } + memcpy(dlg->did.s, new_did->s, new_did->len); + dlg->did.len = new_did->len; + + return 0; error: - LM_ERR("not more shm mem\n"); - return -1; + LM_ERR("not more shm mem\n"); + return -1; } @@ -1409,73 +1476,68 @@ int update_dlg_did(struct dlg_cell *dlg, str * new_did) { * \param dlg_out printed dialog * \return 0 on success, -1 on failure */ -static inline int internal_mi_print_dlg_out(struct mi_node *rpl, - struct dlg_cell_out * dlg_out) { - struct mi_node* node = NULL; - struct mi_node* node1 = NULL; - struct mi_attr* attr = NULL; - - node = add_mi_node_child(rpl, 0, "dialog_out", 10, 0, 0); - if (node == 0) - goto error; - - attr = addf_mi_attr(node, 0, "hash", 4, "%u:%u", - dlg_out->h_entry, dlg_out->h_id); - if (attr == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_tag", 6, - dlg_out->to_tag.s, dlg_out->to_tag.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "did", 3, - dlg_out->did.s, dlg_out->did.len); - if (node1 == 0) - goto error; - - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14, - dlg_out->callee_contact.s, - dlg_out->callee_contact.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11, - dlg_out->caller_cseq.s, - dlg_out->caller_cseq.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, - dlg_out->callee_cseq.s, - dlg_out->callee_cseq.len); - if (node1 == 0) - goto error; - - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_route_set", 16, - dlg_out->callee_route_set.s, - dlg_out->callee_route_set.len); - if (node1 == 0) - goto error; - - if (dlg_out->callee_bind_addr) { - node1 = add_mi_node_child(node, 0, - "callee_bind_addr", 16, - dlg_out->callee_bind_addr->sock_str.s, - dlg_out->callee_bind_addr->sock_str.len); - } else { - node1 = add_mi_node_child(node, 0, - "callee_bind_addr", 16, 0, 0); - } - - return 0; +static inline int internal_mi_print_dlg_out( + struct mi_node *rpl, struct dlg_cell_out *dlg_out) +{ + struct mi_node *node = NULL; + struct mi_node *node1 = NULL; + struct mi_attr *attr = NULL; + + node = add_mi_node_child(rpl, 0, "dialog_out", 10, 0, 0); + if(node == 0) + goto error; + + attr = addf_mi_attr( + node, 0, "hash", 4, "%u:%u", dlg_out->h_entry, dlg_out->h_id); + if(attr == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_tag", 6, + dlg_out->to_tag.s, dlg_out->to_tag.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child( + node, MI_DUP_VALUE, "did", 3, dlg_out->did.s, dlg_out->did.len); + if(node1 == 0) + goto error; + + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14, + dlg_out->callee_contact.s, dlg_out->callee_contact.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11, + dlg_out->caller_cseq.s, dlg_out->caller_cseq.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11, + dlg_out->callee_cseq.s, dlg_out->callee_cseq.len); + if(node1 == 0) + goto error; + + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_route_set", 16, + dlg_out->callee_route_set.s, dlg_out->callee_route_set.len); + if(node1 == 0) + goto error; + + if(dlg_out->callee_bind_addr) { + node1 = add_mi_node_child(node, 0, "callee_bind_addr", 16, + dlg_out->callee_bind_addr->sock_str.s, + dlg_out->callee_bind_addr->sock_str.len); + } else { + node1 = add_mi_node_child(node, 0, "callee_bind_addr", 16, 0, 0); + } + + return 0; error: - LM_ERR("failed to add node\n"); + LM_ERR("failed to add node\n"); - return -1; + return -1; } /*! @@ -1486,121 +1548,112 @@ static inline int internal_mi_print_dlg_out(struct mi_node *rpl, * \param with_context if 1 then the dialog context will be also printed * \return 0 on success, -1 on failure */ -static inline int internal_mi_print_dlg(struct mi_node *rpl, - struct dlg_cell *dlg, int with_context) { - struct mi_node* node = NULL; - struct mi_node* node1 = NULL; - struct mi_attr* attr = NULL; - int len; - char* p; - - node = add_mi_node_child(rpl, 0, "dialog", 6, 0, 0); - if (node == 0) - goto error; - - attr = addf_mi_attr(node, 0, "hash", 4, "%u:%u", - dlg->h_entry, dlg->h_id); - if (attr == 0) - goto error; - - p = int2str((unsigned long) dlg->state, &len); - node1 = add_mi_node_child(node, MI_DUP_VALUE, "state", 5, p, len); - if (node1 == 0) - goto error; - - p = int2str((unsigned long) dlg->ref, &len); - node1 = add_mi_node_child(node, MI_DUP_VALUE, "ref_count", 9, p, len); - if (node1 == 0) - goto error; - - p = int2str((unsigned long) dlg->start_ts, &len); - node1 = add_mi_node_child(node, MI_DUP_VALUE, "timestart", 9, p, len); - if (node1 == 0) - goto error; - - p = int2str((unsigned long) dlg->tl.timeout, &len); - node1 = add_mi_node_child(node, MI_DUP_VALUE, "timeout", 7, p, len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6, - dlg->callid.s, dlg->callid.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, - dlg->from_uri.s, dlg->from_uri.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_tag", 8, - dlg->from_tag.s, dlg->from_tag.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "did", 3, - dlg->did.s, dlg->did.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, - dlg->caller_contact.s, - dlg->caller_contact.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "first_req_cseq", 14, - dlg->first_req_cseq.s, - dlg->first_req_cseq.len); - if (node1 == 0) - goto error; - - node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_route_set", 16, - dlg->caller_route_set.s, - dlg->caller_route_set.len); - if (node1 == 0) - goto error; - - if (dlg->caller_bind_addr) { - node1 = add_mi_node_child(node, 0, - "caller_bind_addr", 16, - dlg->caller_bind_addr->sock_str.s, - dlg->caller_bind_addr->sock_str.len); - } else { - node1 = add_mi_node_child(node, 0, - "caller_bind_addr", 16, 0, 0); - } - - if (with_context) { - node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); - if (node1 == 0) - goto error; - run_dlg_callbacks(DLGCB_MI_CONTEXT, - dlg, - NULL, - NULL, - DLG_DIR_NONE, - (void *) node1); - } - - struct dlg_cell_out *dlg_out; - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - dlg_out = d_entry_out->first; - - while (dlg_out) { - - if (internal_mi_print_dlg_out(rpl, dlg_out) != 0) - goto error; - - dlg_out = dlg_out->next; - } - - return 0; +static inline int internal_mi_print_dlg( + struct mi_node *rpl, struct dlg_cell *dlg, int with_context) +{ + struct mi_node *node = NULL; + struct mi_node *node1 = NULL; + struct mi_attr *attr = NULL; + int len; + char *p; + + node = add_mi_node_child(rpl, 0, "dialog", 6, 0, 0); + if(node == 0) + goto error; + + attr = addf_mi_attr(node, 0, "hash", 4, "%u:%u", dlg->h_entry, dlg->h_id); + if(attr == 0) + goto error; + + p = int2str((unsigned long)dlg->state, &len); + node1 = add_mi_node_child(node, MI_DUP_VALUE, "state", 5, p, len); + if(node1 == 0) + goto error; + + p = int2str((unsigned long)dlg->ref, &len); + node1 = add_mi_node_child(node, MI_DUP_VALUE, "ref_count", 9, p, len); + if(node1 == 0) + goto error; + + p = int2str((unsigned long)dlg->start_ts, &len); + node1 = add_mi_node_child(node, MI_DUP_VALUE, "timestart", 9, p, len); + if(node1 == 0) + goto error; + + p = int2str((unsigned long)dlg->tl.timeout, &len); + node1 = add_mi_node_child(node, MI_DUP_VALUE, "timeout", 7, p, len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child( + node, MI_DUP_VALUE, "callid", 6, dlg->callid.s, dlg->callid.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8, + dlg->from_uri.s, dlg->from_uri.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_tag", 8, + dlg->from_tag.s, dlg->from_tag.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child( + node, MI_DUP_VALUE, "did", 3, dlg->did.s, dlg->did.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14, + dlg->caller_contact.s, dlg->caller_contact.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "first_req_cseq", 14, + dlg->first_req_cseq.s, dlg->first_req_cseq.len); + if(node1 == 0) + goto error; + + node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_route_set", 16, + dlg->caller_route_set.s, dlg->caller_route_set.len); + if(node1 == 0) + goto error; + + if(dlg->caller_bind_addr) { + node1 = add_mi_node_child(node, 0, "caller_bind_addr", 16, + dlg->caller_bind_addr->sock_str.s, + dlg->caller_bind_addr->sock_str.len); + } else { + node1 = add_mi_node_child(node, 0, "caller_bind_addr", 16, 0, 0); + } + + if(with_context) { + node1 = add_mi_node_child(node, 0, "context", 7, 0, 0); + if(node1 == 0) + goto error; + run_dlg_callbacks( + DLGCB_MI_CONTEXT, dlg, NULL, NULL, DLG_DIR_NONE, (void *)node1); + } + + struct dlg_cell_out *dlg_out; + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + dlg_out = d_entry_out->first; + + while(dlg_out) { + + if(internal_mi_print_dlg_out(rpl, dlg_out) != 0) + goto error; + + dlg_out = dlg_out->next; + } + + return 0; error: - LM_ERR("failed to add node\n"); + LM_ERR("failed to add node\n"); - return -1; + return -1; } /*! @@ -1610,9 +1663,10 @@ static inline int internal_mi_print_dlg(struct mi_node *rpl, * \param with_context if 1 then the dialog context will be also printed * \return 0 on success, -1 on failure */ -int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { +int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) +{ - return internal_mi_print_dlg(rpl, dlg, with_context); + return internal_mi_print_dlg(rpl, dlg, with_context); } /*! @@ -1622,79 +1676,82 @@ int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) { * \param with_context if 1 then the dialog context will be also printed * \return 0 on success, -1 on failure */ -static int internal_mi_print_dlgs(struct mi_node *rpl, int with_context) { - struct dlg_cell *dlg; - unsigned int i; +static int internal_mi_print_dlgs(struct mi_node *rpl, int with_context) +{ + struct dlg_cell *dlg; + unsigned int i; - LM_DBG("printing %i dialogs\n", d_table->size); + LM_DBG("printing %i dialogs\n", d_table->size); - for (i = 0; i < d_table->size; i++) { - dlg_lock(d_table, &(d_table->entries[i])); + for(i = 0; i < d_table->size; i++) { + dlg_lock(d_table, &(d_table->entries[i])); - for (dlg = d_table->entries[i].first; dlg; dlg = dlg->next) { - if (internal_mi_print_dlg(rpl, dlg, with_context) != 0) - goto error; - } - dlg_unlock(d_table, &(d_table->entries[i])); - } - return 0; + for(dlg = d_table->entries[i].first; dlg; dlg = dlg->next) { + if(internal_mi_print_dlg(rpl, dlg, with_context) != 0) + goto error; + } + dlg_unlock(d_table, &(d_table->entries[i])); + } + return 0; error: - dlg_unlock(d_table, &(d_table->entries[i])); - LM_ERR("failed to print dialog\n"); + dlg_unlock(d_table, &(d_table->entries[i])); + LM_ERR("failed to print dialog\n"); - return -1; + return -1; } -static inline struct mi_root * process_mi_params(struct mi_root *cmd_tree, struct dlg_cell **dlg_p) { - struct mi_node* node; - struct dlg_entry *d_entry; - struct dlg_cell *dlg; - str *callid; - str *from_tag; - unsigned int h_entry; - - node = cmd_tree->node.kids; - if (node == NULL) { - /* no parameters at all */ - *dlg_p = NULL; - return NULL; - } - - /* we have params -> get callid and fromtag */ - callid = &node->value; - LM_DBG("callid='%.*s'\n", callid->len, callid->s); - - node = node->next; - if (!node || !node->value.s || !node->value.len) { - from_tag = NULL; - } else { - from_tag = &node->value; - LM_DBG("from_tag='%.*s'\n", from_tag->len, from_tag->s); - if (node->next != NULL) - return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); - } - - h_entry = core_hash(callid, 0, d_table->size); - - d_entry = &(d_table->entries[h_entry]); - dlg_lock(d_table, d_entry); - - for (dlg = d_entry->first; dlg; dlg = dlg->next) { - if (match_downstream_dialog(dlg, callid, from_tag) == 1) { - if (dlg->state == DLG_STATE_DELETED) { - *dlg_p = NULL; - break; - } else { - *dlg_p = dlg; - dlg_unlock(d_table, d_entry); - return 0; - } - } - } - dlg_unlock(d_table, d_entry); +static inline struct mi_root *process_mi_params( + struct mi_root *cmd_tree, struct dlg_cell **dlg_p) +{ + struct mi_node *node; + struct dlg_entry *d_entry; + struct dlg_cell *dlg; + str *callid; + str *from_tag; + unsigned int h_entry; + + node = cmd_tree->node.kids; + if(node == NULL) { + /* no parameters at all */ + *dlg_p = NULL; + return NULL; + } + + /* we have params -> get callid and fromtag */ + callid = &node->value; + LM_DBG("callid='%.*s'\n", callid->len, callid->s); + + node = node->next; + if(!node || !node->value.s || !node->value.len) { + from_tag = NULL; + } else { + from_tag = &node->value; + LM_DBG("from_tag='%.*s'\n", from_tag->len, from_tag->s); + if(node->next != NULL) + return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); + } + + h_entry = core_hash(callid, 0, d_table->size); + + d_entry = &(d_table->entries[h_entry]); + dlg_lock(d_table, d_entry); + + for(dlg = d_entry->first; dlg; dlg = dlg->next) { + if(match_downstream_dialog(dlg, callid, from_tag) == 1) { + if(dlg->state == DLG_STATE_DELETED) { + *dlg_p = NULL; + break; + } else { + *dlg_p = dlg; + dlg_unlock(d_table, d_entry); + return 0; + } + } + } + dlg_unlock(d_table, d_entry); - return init_mi_tree(404, MI_SSTR("Nu such dialog")); + return init_mi_tree(404, MI_SSTR("Nu such dialog")); } /*! @@ -1704,34 +1761,35 @@ static inline struct mi_root * process_mi_params(struct mi_root *cmd_tree, struc * \return mi node with the dialog information, or NULL on failure */ -struct mi_root * mi_print_dlgs(struct mi_root *cmd_tree, void *param) { - struct mi_root* rpl_tree = NULL; - struct mi_node* rpl = NULL; - struct dlg_cell* dlg = NULL; - - rpl_tree = process_mi_params(cmd_tree, &dlg); - if (rpl_tree) - //param error - return rpl_tree; +struct mi_root *mi_print_dlgs(struct mi_root *cmd_tree, void *param) +{ + struct mi_root *rpl_tree = NULL; + struct mi_node *rpl = NULL; + struct dlg_cell *dlg = NULL; - rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); - if (rpl_tree == 0) - return 0; - rpl = &rpl_tree->node; + rpl_tree = process_mi_params(cmd_tree, &dlg); + if(rpl_tree) + //param error + return rpl_tree; - if (dlg == NULL) { - if (internal_mi_print_dlgs(rpl, 0) != 0) - goto error; - } else { - if (internal_mi_print_dlg(rpl, dlg, 0) != 0) - goto error; - } + rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); + if(rpl_tree == 0) + return 0; + rpl = &rpl_tree->node; + + if(dlg == NULL) { + if(internal_mi_print_dlgs(rpl, 0) != 0) + goto error; + } else { + if(internal_mi_print_dlg(rpl, dlg, 0) != 0) + goto error; + } - return rpl_tree; + return rpl_tree; error: - free_mi_tree(rpl_tree); + free_mi_tree(rpl_tree); - return NULL; + return NULL; } /*! @@ -1740,34 +1798,35 @@ struct mi_root * mi_print_dlgs(struct mi_root *cmd_tree, void *param) { * \param param unused * \return mi node with the dialog information, or NULL on failure */ -struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param) { - struct mi_root* rpl_tree = NULL; - struct mi_node* rpl = NULL; - struct dlg_cell* dlg = NULL; - - rpl_tree = process_mi_params(cmd_tree, &dlg); - if (rpl_tree) - /* param error */ - return rpl_tree; - - rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); - if (rpl_tree == 0) - return 0; - rpl = &rpl_tree->node; +struct mi_root *mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param) +{ + struct mi_root *rpl_tree = NULL; + struct mi_node *rpl = NULL; + struct dlg_cell *dlg = NULL; - if (dlg == NULL) { - if (internal_mi_print_dlgs(rpl, 1) != 0) - goto error; - } else { - if (internal_mi_print_dlg(rpl, dlg, 1) != 0) - goto error; - } + rpl_tree = process_mi_params(cmd_tree, &dlg); + if(rpl_tree) + /* param error */ + return rpl_tree; + + rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); + if(rpl_tree == 0) + return 0; + rpl = &rpl_tree->node; + + if(dlg == NULL) { + if(internal_mi_print_dlgs(rpl, 1) != 0) + goto error; + } else { + if(internal_mi_print_dlg(rpl, dlg, 1) != 0) + goto error; + } - return rpl_tree; + return rpl_tree; error: - free_mi_tree(rpl_tree); + free_mi_tree(rpl_tree); - return NULL; + return NULL; } #endif @@ -1789,7 +1848,7 @@ struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param) { * \param dir direction * \return dialog structure on success, NULL on failure (and slot locked) */ -dlg_cell_t* search_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir) +dlg_cell_t *search_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir) { struct dlg_cell *dlg; unsigned int he; @@ -1797,7 +1856,7 @@ dlg_cell_t* search_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir) he = core_hash(callid, 0, d_table->size); dlg = internal_get_dlg(he, callid, ftag, ttag, dir, 1); - if (dlg == 0) { + if(dlg == 0) { LM_DBG("dialog with callid='%.*s' not found\n", callid->len, callid->s); return 0; } @@ -1825,50 +1884,53 @@ void dlg_hash_release(str *callid) */ void dlg_release(struct dlg_cell *dlg) { - if(dlg==NULL) + if(dlg == NULL) return; unref_dlg(dlg, 1); } -time_t api_get_dlg_expires(str *callid, str *ftag, str *ttag) { - struct dlg_cell *dlg; - time_t expires = 0; - time_t start; +time_t api_get_dlg_expires(str *callid, str *ftag, str *ttag) +{ + struct dlg_cell *dlg; + time_t expires = 0; + time_t start; - if (!callid || !ftag || !ttag) { - LM_ERR("Missing callid, from tag or to tag\n"); - return 0; - } + if(!callid || !ftag || !ttag) { + LM_ERR("Missing callid, from tag or to tag\n"); + return 0; + } - unsigned int direction = DLG_DIR_NONE; - dlg = get_dlg(callid, ftag, ttag, &direction); - if (!dlg) return 0; + unsigned int direction = DLG_DIR_NONE; + dlg = get_dlg(callid, ftag, ttag, &direction); + if(!dlg) + return 0; - if (dlg->state != DLG_STATE_CONFIRMED || !dlg->start_ts) { - /* Dialog not started yet so lets assume start time is now.*/ - start = time(0); - } else { - start = dlg->start_ts; - } + if(dlg->state != DLG_STATE_CONFIRMED || !dlg->start_ts) { + /* Dialog not started yet so lets assume start time is now.*/ + start = time(0); + } else { + start = dlg->start_ts; + } - expires = start + dlg->lifetime; - unref_dlg(dlg, 1); + expires = start + dlg->lifetime; + unref_dlg(dlg, 1); - return expires; + return expires; } -char* state_to_char(unsigned int state) { - switch (state) { - case DLG_STATE_UNCONFIRMED: - return "Unconfirmed"; - case DLG_STATE_EARLY: - return "Early"; - case DLG_STATE_CONFIRMED: - return "Confirmed"; - case DLG_STATE_DELETED: - return "Deleted"; - default: - return "Unknown"; +char *state_to_char(unsigned int state) +{ + switch(state) { + case DLG_STATE_UNCONFIRMED: + return "Unconfirmed"; + case DLG_STATE_EARLY: + return "Early"; + case DLG_STATE_CONFIRMED: + return "Confirmed"; + case DLG_STATE_DELETED: + return "Deleted"; + default: + return "Unknown"; } } @@ -1880,13 +1942,12 @@ char* state_to_char(unsigned int state) { * \param diuid internal unique id per dialog * \return dialog structure on success, NULL on failure */ -dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid) +dlg_cell_t *dlg_get_by_iuid(dlg_iuid_t *diuid) { - if(diuid==NULL) + if(diuid == NULL) return NULL; - if(diuid->h_id==0) + if(diuid->h_id == 0) return NULL; /* dlg ref counter is increased by next line */ return lookup_dlg(diuid->h_entry, diuid->h_id); } - diff --git a/src/modules/ims_dialog/dlg_hash.h b/src/modules/ims_dialog/dlg_hash.h index 7faabfd4c90..2c17f71b783 100644 --- a/src/modules/ims_dialog/dlg_hash.h +++ b/src/modules/ims_dialog/dlg_hash.h @@ -37,128 +37,136 @@ /* states of a dialog */ -#define DLG_STATE_UNCONFIRMED 1 /*!< unconfirmed dialog */ -#define DLG_STATE_EARLY 2 /*!< early dialog */ -#define DLG_STATE_CONFIRMED 4 /*!< confirmed dialog */ +#define DLG_STATE_UNCONFIRMED 1 /*!< unconfirmed dialog */ +#define DLG_STATE_EARLY 2 /*!< early dialog */ +#define DLG_STATE_CONFIRMED 4 /*!< confirmed dialog */ #define DLG_STATE_CONFIRMED_NA 5 /*!< confirmed dialog without an ACK yet */ -#define DLG_STATE_DELETED 6 /*!< deleted dialog */ -#define DLG_STATE_CONCURRENTLY_CONFIRMED 7 /*!< confirmed concurrent dailogs */ +#define DLG_STATE_DELETED 6 /*!< deleted dialog */ +#define DLG_STATE_CONCURRENTLY_CONFIRMED 7 /*!< confirmed concurrent dailogs */ /* events for dialog processing */ -#define DLG_EVENT_TDEL 1 /*!< transaction was destroyed */ -#define DLG_EVENT_RPL1xx 2 /*!< 1xx request */ -#define DLG_EVENT_RPL2xx 3 /*!< 2xx request */ -#define DLG_EVENT_RPL3xx 4 /*!< 3xx request */ -#define DLG_EVENT_REQPRACK 5 /*!< PRACK request */ -#define DLG_EVENT_REQACK 6 /*!< ACK request */ -#define DLG_EVENT_REQBYE 7 /*!< BYE request */ -#define DLG_EVENT_REQCANCEL 8 /*!< CANCEL request */ -#define DLG_EVENT_REQ 9 /*!< other requests */ +#define DLG_EVENT_TDEL 1 /*!< transaction was destroyed */ +#define DLG_EVENT_RPL1xx 2 /*!< 1xx request */ +#define DLG_EVENT_RPL2xx 3 /*!< 2xx request */ +#define DLG_EVENT_RPL3xx 4 /*!< 3xx request */ +#define DLG_EVENT_REQPRACK 5 /*!< PRACK request */ +#define DLG_EVENT_REQACK 6 /*!< ACK request */ +#define DLG_EVENT_REQBYE 7 /*!< BYE request */ +#define DLG_EVENT_REQCANCEL 8 /*!< CANCEL request */ +#define DLG_EVENT_REQ 9 /*!< other requests */ /* dialog flags */ -#define DLG_FLAG_NEW (1<<0) /*!< new dialog */ -#define DLG_FLAG_CHANGED (1<<1) /*!< dialog was changed */ -#define DLG_FLAG_HASBYE (1<<2) /*!< bye was received */ -#define DLG_FLAG_TOBYE (1<<3) /*!< flag from dialog context */ -#define DLG_FLAG_CALLERBYE (1<<4) /*!< bye from caller */ -#define DLG_FLAG_CALLEEBYE (1<<5) /*!< bye from callee */ -#define DLG_FLAG_LOCALDLG (1<<6) /*!< local dialog, unused */ -#define DLG_FLAG_CHANGED_VARS (1<<7) /*!< dialog-variables changed */ -#define DLG_FLAG_HASCANCEL (1<<8) /*!< cancel was received */ +#define DLG_FLAG_NEW (1 << 0) /*!< new dialog */ +#define DLG_FLAG_CHANGED (1 << 1) /*!< dialog was changed */ +#define DLG_FLAG_HASBYE (1 << 2) /*!< bye was received */ +#define DLG_FLAG_TOBYE (1 << 3) /*!< flag from dialog context */ +#define DLG_FLAG_CALLERBYE (1 << 4) /*!< bye from caller */ +#define DLG_FLAG_CALLEEBYE (1 << 5) /*!< bye from callee */ +#define DLG_FLAG_LOCALDLG (1 << 6) /*!< local dialog, unused */ +#define DLG_FLAG_CHANGED_VARS (1 << 7) /*!< dialog-variables changed */ +#define DLG_FLAG_HASCANCEL (1 << 8) /*!< cancel was received */ /* dialog-variable flags (in addition to dialog-flags) */ -#define DLG_FLAG_DEL (1<<9) /*!< delete this var */ -#define DLG_FLAG_INSERTED (1<<10) /*!< DLG already written to DB - could have been put in by early media or confirmed */ -#define DLG_FLAG_TM (1<<11) /*!< dialog is set in transaction */ -#define DLG_FLAG_EXPIRED (1<<12)/*!< dialog is expired */ +#define DLG_FLAG_DEL (1 << 9) /*!< delete this var */ +#define DLG_FLAG_INSERTED \ + (1 << 10) /*!< DLG already written to DB - could have been put in by early media or confirmed */ +#define DLG_FLAG_TM (1 << 11) /*!< dialog is set in transaction */ +#define DLG_FLAG_EXPIRED (1 << 12) /*!< dialog is expired */ -#define DLG_CALLER_LEG 0 /*!< attribute that belongs to a caller leg */ -#define DLG_CALLEE_LEG 1 /*!< attribute that belongs to a callee leg */ +#define DLG_CALLER_LEG 0 /*!< attribute that belongs to a caller leg */ +#define DLG_CALLEE_LEG 1 /*!< attribute that belongs to a callee leg */ -#define DLG_DIR_NONE 0 /*!< dialog has no direction */ -#define DLG_DIR_DOWNSTREAM 1 /*!< dialog has downstream direction */ -#define DLG_DIR_UPSTREAM 2 /*!< dialog has upstream direction */ +#define DLG_DIR_NONE 0 /*!< dialog has no direction */ +#define DLG_DIR_DOWNSTREAM 1 /*!< dialog has downstream direction */ +#define DLG_DIR_UPSTREAM 2 /*!< dialog has upstream direction */ /*! internal unique ide per dialog */ -typedef struct dlg_iuid { - unsigned int h_id; /*!< id in the hash table entry (seq nr in slot) */ - unsigned int h_entry; /*!< index of hash table entry (the slot number) */ +typedef struct dlg_iuid +{ + unsigned int h_id; /*!< id in the hash table entry (seq nr in slot) */ + unsigned int h_entry; /*!< index of hash table entry (the slot number) */ } dlg_iuid_t; /*! entries in the main dialog table */ -struct dlg_entry_out { - struct dlg_cell_out *first; /*!< dialog list */ - struct dlg_cell_out *last; /*!< optimisation, end of the dialog list */ - unsigned int count; /*! number of out entries in the linked list */ +struct dlg_entry_out +{ + struct dlg_cell_out *first; /*!< dialog list */ + struct dlg_cell_out *last; /*!< optimisation, end of the dialog list */ + unsigned int count; /*! number of out entries in the linked list */ }; /*! entries in the dialog list */ -typedef struct dlg_cell { - volatile int ref; /*!< reference counter */ - struct dlg_cell *next; /*!< next entry in the list */ - struct dlg_cell *prev; /*!< previous entry in the list */ - unsigned int h_id; /*!< id of the hash table entry */ - unsigned int h_entry; /*!< number of hash entry */ - str did; - str callid; /*!< callid from SIP message */ - str from_tag; /*!< from tags of caller*/ - str from_uri; /*!< from uri from SIP message */ - str first_req_cseq; /*!< CSEQ of caller*/ - str req_uri; /*!< r-uri from SIP message */ - str caller_contact; /*!< contact of caller*/ - str caller_route_set; /*!< route set of caller*/ - struct socket_info * caller_bind_addr; /*! binded address of caller*/ - unsigned int state; /*!< dialog state */ - unsigned int init_ts;/*!< init (creation) time (absolute UNIX ts)*/ - unsigned int start_ts; /*!< start time (absolute UNIX ts)*/ - unsigned int lifetime; /*!< dialog lifetime */ - unsigned int toroute; /*!< index of route that is executed on timeout */ - str toroute_name; /*!< name of route that is executed on timeout */ - unsigned int dflags; /*!< internal dialog flags */ - unsigned int sflags; /*!< script dialog flags */ - struct dlg_tl tl; /*!< dialog timer list */ - struct dlg_head_cbl cbs; /*!< dialog callbacks */ - struct dlg_profile_link *profile_links; /*!< dialog profiles */ - struct dlg_var *vars; /*!< dialog variables */ - struct dlg_entry_out dlg_entry_out; /*!< list of dialog_out entries */ - struct cell *transaction; /*!< ptr to associated transaction for this dialog TM module cell ptr */ - gen_lock_t *dlg_out_entries_lock; /*!< lock for dialog_out linked list */ - unsigned int from_rr_nb; /*!< information from record routing */ +typedef struct dlg_cell +{ + volatile int ref; /*!< reference counter */ + struct dlg_cell *next; /*!< next entry in the list */ + struct dlg_cell *prev; /*!< previous entry in the list */ + unsigned int h_id; /*!< id of the hash table entry */ + unsigned int h_entry; /*!< number of hash entry */ + str did; + str callid; /*!< callid from SIP message */ + str from_tag; /*!< from tags of caller*/ + str from_uri; /*!< from uri from SIP message */ + str first_req_cseq; /*!< CSEQ of caller*/ + str req_uri; /*!< r-uri from SIP message */ + str caller_contact; /*!< contact of caller*/ + str caller_route_set; /*!< route set of caller*/ + struct socket_info *caller_bind_addr; /*! binded address of caller*/ + unsigned int state; /*!< dialog state */ + unsigned int init_ts; /*!< init (creation) time (absolute UNIX ts)*/ + unsigned int start_ts; /*!< start time (absolute UNIX ts)*/ + unsigned int lifetime; /*!< dialog lifetime */ + unsigned int toroute; /*!< index of route that is executed on timeout */ + str toroute_name; /*!< name of route that is executed on timeout */ + unsigned int dflags; /*!< internal dialog flags */ + unsigned int sflags; /*!< script dialog flags */ + struct dlg_tl tl; /*!< dialog timer list */ + struct dlg_head_cbl cbs; /*!< dialog callbacks */ + struct dlg_profile_link *profile_links; /*!< dialog profiles */ + struct dlg_var *vars; /*!< dialog variables */ + struct dlg_entry_out dlg_entry_out; /*!< list of dialog_out entries */ + struct cell * + transaction; /*!< ptr to associated transaction for this dialog TM module cell ptr */ + gen_lock_t *dlg_out_entries_lock; /*!< lock for dialog_out linked list */ + unsigned int from_rr_nb; /*!< information from record routing */ } dlg_cell_t; -struct dlg_cell_out { - struct dlg_cell_out *next; /*!< next entry in the list */ - struct dlg_cell_out *prev; /*!< previous entry in the list */ - unsigned int h_id; /*!< id of the hash table entry */ - unsigned int h_entry; /*!< number of hash entry */ - str branch; - str did; - str to_uri; /*!< to uri */ - str to_tag; /*!< to tags of callee*/ - str caller_cseq; /*!< CSEQ of caller*/ - str callee_cseq; /*!< CSEQ of callee*/ - str callee_contact; /*!< contact of callee*/ - str callee_route_set; /*!< route set of caller*/ - struct socket_info * callee_bind_addr; /*! binded address of caller*/ - unsigned int dflags; /*!< internal dialog flags */ - unsigned int deleted; +struct dlg_cell_out +{ + struct dlg_cell_out *next; /*!< next entry in the list */ + struct dlg_cell_out *prev; /*!< previous entry in the list */ + unsigned int h_id; /*!< id of the hash table entry */ + unsigned int h_entry; /*!< number of hash entry */ + str branch; + str did; + str to_uri; /*!< to uri */ + str to_tag; /*!< to tags of callee*/ + str caller_cseq; /*!< CSEQ of caller*/ + str callee_cseq; /*!< CSEQ of callee*/ + str callee_contact; /*!< contact of callee*/ + str callee_route_set; /*!< route set of caller*/ + struct socket_info *callee_bind_addr; /*! binded address of caller*/ + unsigned int dflags; /*!< internal dialog flags */ + unsigned int deleted; }; /*! entries in the main dialog table */ -typedef struct dlg_entry { - struct dlg_cell *first; /*!< dialog list */ - struct dlg_cell *last; /*!< optimisation, end of the dialog list */ - unsigned int next_id; /*!< next id */ - unsigned int lock_idx; /*!< lock index */ +typedef struct dlg_entry +{ + struct dlg_cell *first; /*!< dialog list */ + struct dlg_cell *last; /*!< optimisation, end of the dialog list */ + unsigned int next_id; /*!< next id */ + unsigned int lock_idx; /*!< lock index */ } dlg_entry_t; /*! main dialog table */ -typedef struct dlg_table { - unsigned int size; /*!< size of the dialog table */ - struct dlg_entry *entries; /*!< dialog hash table */ - unsigned int locks_no; /*!< number of locks */ - gen_lock_set_t *locks; /*!< lock table */ +typedef struct dlg_table +{ + unsigned int size; /*!< size of the dialog table */ + struct dlg_entry *entries; /*!< dialog hash table */ + unsigned int locks_no; /*!< number of locks */ + gen_lock_set_t *locks; /*!< lock table */ } dlg_table_t; @@ -171,7 +179,7 @@ extern struct dlg_table *d_table; * \param _entry locked entry */ #define dlg_lock(_table, _entry) \ - lock_set_get( (_table)->locks, (_entry)->lock_idx); + lock_set_get((_table)->locks, (_entry)->lock_idx); /*! @@ -180,7 +188,7 @@ extern struct dlg_table *d_table; * \param _entry locked entry */ #define dlg_unlock(_table, _entry) \ - lock_set_release( (_table)->locks, (_entry)->lock_idx); + lock_set_release((_table)->locks, (_entry)->lock_idx); /*! * \brief Unlink a dialog from the list without locking @@ -188,19 +196,21 @@ extern struct dlg_table *d_table; * \param d_entry unlinked entry * \param dlg unlinked dialog */ -static inline void unlink_unsafe_dlg(struct dlg_entry *d_entry, struct dlg_cell *dlg) { - if (dlg->next) - dlg->next->prev = dlg->prev; - else - d_entry->last = dlg->prev; - if (dlg->prev) - dlg->prev->next = dlg->next; - else - d_entry->first = dlg->next; - - dlg->next = dlg->prev = 0; - - return; +static inline void unlink_unsafe_dlg( + struct dlg_entry *d_entry, struct dlg_cell *dlg) +{ + if(dlg->next) + dlg->next->prev = dlg->prev; + else + d_entry->last = dlg->prev; + if(dlg->prev) + dlg->prev->next = dlg->next; + else + d_entry->first = dlg->next; + + dlg->next = dlg->prev = 0; + + return; } @@ -236,8 +246,8 @@ void free_dlg_out_cell(struct dlg_cell_out *dlg_out); * \param req_uri dialog r-uri * \return created dialog structure on success, NULL otherwise */ -struct dlg_cell* build_new_dlg(str *callid, str *from_uri, - str *from_tag, str *req_uri); +struct dlg_cell *build_new_dlg( + str *callid, str *from_uri, str *from_tag, str *req_uri); /*! @@ -251,9 +261,8 @@ struct dlg_cell* build_new_dlg(str *callid, str *from_uri, * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG * \return 0 on success, -1 on failure */ -int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact, - str *cseq, struct socket_info *bind_addr, unsigned int leg); - +int dlg_set_leg_info(struct dlg_cell *dlg, str *tag, str *rr, str *contact, + str *cseq, struct socket_info *bind_addr, unsigned int leg); /*! @@ -264,7 +273,8 @@ int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact, * \param to_tag dialog to tag * \return 0 on success, -1 on failure */ -int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq, str *to_tag); +int dlg_update_cseq( + struct dlg_cell *dlg, unsigned int leg, str *cseq, str *to_tag); /*! * \brief Update or set the contact for an existing dialog @@ -274,7 +284,8 @@ int dlg_update_cseq(struct dlg_cell *dlg, unsigned int leg, str *cseq, str *to_t * \param to_tag dialog to tag * \return 0 on success, -1 on failure */ -int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *contact, str *to_tag); +int dlg_update_contact( + struct dlg_cell *dlg, unsigned int leg, str *contact, str *to_tag); /*! * \brief Set time-out route @@ -292,7 +303,7 @@ int dlg_set_toroute(struct dlg_cell *dlg, str *route); * \param diuid internal unique id per dialog * \return dialog structure on success, NULL on failure */ -dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid); +dlg_cell_t *dlg_get_by_iuid(dlg_iuid_t *diuid); /*! * \brief Lookup a dialog in the global list @@ -303,7 +314,7 @@ dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid); * \param h_id id of the hash table entry * \return dialog structure on success, NULL on failure */ -struct dlg_cell* lookup_dlg(unsigned int h_entry, unsigned int h_id); +struct dlg_cell *lookup_dlg(unsigned int h_entry, unsigned int h_id); /*! * \brief Search dialog that corresponds to CallId, From Tag and To Tag @@ -323,7 +334,7 @@ struct dlg_cell* lookup_dlg(unsigned int h_entry, unsigned int h_id); * \param dir direction * \return dialog structure on success, NULL on failure (and slot locked) */ -dlg_cell_t* search_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir); +dlg_cell_t *search_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir); /*! * \brief Release hash table slot by call-id @@ -347,7 +358,7 @@ void dlg_hash_release(str *callid); * \param dir direction * \return dialog structure on success, NULL on failure */ -struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir); +struct dlg_cell *get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir); /*! @@ -399,8 +410,8 @@ void ref_dlg(struct dlg_cell *dlg, unsigned int cnt); * \param unref set to 1 when the dialog was deleted, 0 otherwise * \param to_tag dialog to tag */ -void next_state_dlg(struct dlg_cell *dlg, int event, - int *old_state, int *new_state, int *unref, str *to_tag); +void next_state_dlg(struct dlg_cell *dlg, int event, int *old_state, + int *new_state, int *unref, str *to_tag); /*! @@ -412,128 +423,131 @@ void next_state_dlg(struct dlg_cell *dlg, int event, * \param dir direction of the message, if DLG_DIR_NONE it will set * \return 1 if dialog structure and message content matches, 0 otherwise */ -static inline int match_dialog(struct dlg_cell *dlg, str *callid, - str *ftag, str *ttag, unsigned int *dir) { - - struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); - struct dlg_cell_out *dlg_out; - - if (d_entry_out->first == 0) { - //there are no dialog out entries yet - LM_DBG("No dlg outs yet...\n"); - if (*dir == DLG_DIR_DOWNSTREAM) { - if (dlg->callid.len == callid->len && - dlg->from_tag.len == ftag->len && - strncmp(dlg->callid.s, callid->s, callid->len) == 0 && - strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) { - return 1; - } - } else if (*dir == DLG_DIR_UPSTREAM) { - if (dlg->callid.len == callid->len && - dlg->from_tag.len == ttag->len && - strncmp(dlg->callid.s, callid->s, callid->len) == 0 && - strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) { - return 1; - } - } else { - - if (dlg->callid.len != callid->len) { - return 0; - } - if (dlg->from_tag.len == ttag->len && - strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 && - strncmp(dlg->callid.s, callid->s, callid->len) == 0) { - - *dir = DLG_DIR_UPSTREAM; - return 1; - } else if (dlg->from_tag.len == ftag->len && - strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 && - strncmp(dlg->callid.s, callid->s, callid->len) == 0) { - - *dir = DLG_DIR_DOWNSTREAM; - return 1; - } - LM_DBG("No match found\n"); - } - } else { - LM_DBG("searching dlg_outs\n"); - //there is a dialog out entry - if (*dir == DLG_DIR_DOWNSTREAM) { - if (dlg->callid.len == callid->len && - dlg->from_tag.len == ftag->len && - strncmp(dlg->callid.s, callid->s, callid->len) == 0 && - strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) { - //now need to scroll through d_out_entries to see if to_tag matches! - dlg_out = d_entry_out->first; - while (dlg_out) { - if (dlg_out->to_tag.len == ttag->len && - memcmp(dlg_out->to_tag.s, ttag->s, dlg_out->to_tag.len) == 0) { - return 1; - } - dlg_out = dlg_out->next; - } - } - } else if (*dir == DLG_DIR_UPSTREAM) { - if (dlg->callid.len == callid->len && - dlg->from_tag.len == ttag->len && - strncmp(dlg->callid.s, callid->s, callid->len) == 0 && - strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) { - dlg_out = d_entry_out->first; - while (dlg_out) { - if (dlg_out->to_tag.len == ftag->len && - memcmp(dlg_out->to_tag.s, ftag->s, dlg_out->to_tag.len) == 0) { - return 1; - } - dlg_out = dlg_out->next; - } - } - } else { - if (dlg->callid.len != callid->len) { - LM_DBG("no match cid: %d %d", dlg->callid.len, callid->len); - return 0; - } - - LM_DBG("p: %p ft[%.*s] tt [%.*s]", d_entry_out->first, - dlg->from_tag.len, dlg->from_tag.s, - ttag->len, ttag->s); - if (dlg->from_tag.len == ttag->len && - strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 && - strncmp(dlg->callid.s, callid->s, callid->len) == 0) { - //now need to scroll thought d_out_entries to see if to_tag matches! - dlg_out = d_entry_out->first; - while (dlg_out) { - LM_DBG("dout: tt[%.*s]", - dlg_out->to_tag.len, dlg_out->to_tag.s); - if (dlg_out->to_tag.len == ftag->len && - memcmp(dlg_out->to_tag.s, ftag->s, dlg_out->to_tag.len) == 0) { - *dir = DLG_DIR_UPSTREAM; - return 1; - } - dlg_out = dlg_out->next; - } - } else if (dlg->from_tag.len == ftag->len && - strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 && - strncmp(dlg->callid.s, callid->s, callid->len) == 0) { - //now need to scroll thought d_out_entries to see if to_tag matches! - dlg_out = d_entry_out->first; - while (dlg_out) { - LM_DBG("dout: tt[%.*s]", - dlg_out->to_tag.len, dlg_out->to_tag.s); - if (dlg_out->to_tag.len == ttag->len && - memcmp(dlg_out->to_tag.s, ttag->s, dlg_out->to_tag.len) == 0) { - *dir = DLG_DIR_DOWNSTREAM; - return 1; - } - dlg_out = dlg_out->next; - } - *dir = DLG_DIR_UPSTREAM; - return 1; - } - else - LM_DBG("no match tags: "); - } - } - return 0; +static inline int match_dialog(struct dlg_cell *dlg, str *callid, str *ftag, + str *ttag, unsigned int *dir) +{ + + struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out); + struct dlg_cell_out *dlg_out; + + if(d_entry_out->first == 0) { + //there are no dialog out entries yet + LM_DBG("No dlg outs yet...\n"); + if(*dir == DLG_DIR_DOWNSTREAM) { + if(dlg->callid.len == callid->len && dlg->from_tag.len == ftag->len + && strncmp(dlg->callid.s, callid->s, callid->len) == 0 + && strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) { + return 1; + } + } else if(*dir == DLG_DIR_UPSTREAM) { + if(dlg->callid.len == callid->len && dlg->from_tag.len == ttag->len + && strncmp(dlg->callid.s, callid->s, callid->len) == 0 + && strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) { + return 1; + } + } else { + + if(dlg->callid.len != callid->len) { + return 0; + } + if(dlg->from_tag.len == ttag->len + && strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 + && strncmp(dlg->callid.s, callid->s, callid->len) == 0) { + + *dir = DLG_DIR_UPSTREAM; + return 1; + } else if(dlg->from_tag.len == ftag->len + && strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 + && strncmp(dlg->callid.s, callid->s, callid->len) == 0) { + + *dir = DLG_DIR_DOWNSTREAM; + return 1; + } + LM_DBG("No match found\n"); + } + } else { + LM_DBG("searching dlg_outs\n"); + //there is a dialog out entry + if(*dir == DLG_DIR_DOWNSTREAM) { + if(dlg->callid.len == callid->len && dlg->from_tag.len == ftag->len + && strncmp(dlg->callid.s, callid->s, callid->len) == 0 + && strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0) { + //now need to scroll through d_out_entries to see if to_tag matches! + dlg_out = d_entry_out->first; + while(dlg_out) { + if(dlg_out->to_tag.len == ttag->len + && memcmp(dlg_out->to_tag.s, ttag->s, + dlg_out->to_tag.len) + == 0) { + return 1; + } + dlg_out = dlg_out->next; + } + } + } else if(*dir == DLG_DIR_UPSTREAM) { + if(dlg->callid.len == callid->len && dlg->from_tag.len == ttag->len + && strncmp(dlg->callid.s, callid->s, callid->len) == 0 + && strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0) { + dlg_out = d_entry_out->first; + while(dlg_out) { + if(dlg_out->to_tag.len == ftag->len + && memcmp(dlg_out->to_tag.s, ftag->s, + dlg_out->to_tag.len) + == 0) { + return 1; + } + dlg_out = dlg_out->next; + } + } + } else { + if(dlg->callid.len != callid->len) { + LM_DBG("no match cid: %d %d", dlg->callid.len, callid->len); + return 0; + } + + LM_DBG("p: %p ft[%.*s] tt [%.*s]", d_entry_out->first, + dlg->from_tag.len, dlg->from_tag.s, ttag->len, ttag->s); + if(dlg->from_tag.len == ttag->len + && strncmp(dlg->from_tag.s, ttag->s, ttag->len) == 0 + && strncmp(dlg->callid.s, callid->s, callid->len) == 0) { + //now need to scroll thought d_out_entries to see if to_tag matches! + dlg_out = d_entry_out->first; + while(dlg_out) { + LM_DBG("dout: tt[%.*s]", dlg_out->to_tag.len, + dlg_out->to_tag.s); + if(dlg_out->to_tag.len == ftag->len + && memcmp(dlg_out->to_tag.s, ftag->s, + dlg_out->to_tag.len) + == 0) { + *dir = DLG_DIR_UPSTREAM; + return 1; + } + dlg_out = dlg_out->next; + } + } else if(dlg->from_tag.len == ftag->len + && strncmp(dlg->from_tag.s, ftag->s, ftag->len) == 0 + && strncmp(dlg->callid.s, callid->s, callid->len) == 0) { + //now need to scroll thought d_out_entries to see if to_tag matches! + dlg_out = d_entry_out->first; + while(dlg_out) { + LM_DBG("dout: tt[%.*s]", dlg_out->to_tag.len, + dlg_out->to_tag.s); + if(dlg_out->to_tag.len == ttag->len + && memcmp(dlg_out->to_tag.s, ttag->s, + dlg_out->to_tag.len) + == 0) { + *dir = DLG_DIR_DOWNSTREAM; + return 1; + } + dlg_out = dlg_out->next; + } + *dir = DLG_DIR_UPSTREAM; + return 1; + } else + LM_DBG("no match tags: "); + } + } + return 0; } /*! @@ -543,21 +557,22 @@ static inline int match_dialog(struct dlg_cell *dlg, str *callid, * \param ftag SIP message from tag * \return 1 if dialog structure matches the SIP dialog, 0 otherwise */ -static inline int match_downstream_dialog(struct dlg_cell *dlg, str *callid, str *ftag) { - if (dlg == NULL || callid == NULL) - return 0; - if (ftag == NULL) { - if (dlg->callid.len != callid->len || - strncmp(dlg->callid.s, callid->s, callid->len) != 0) - return 0; - } else { - if (dlg->callid.len != callid->len || - dlg->from_tag.len != ftag->len || - strncmp(dlg->callid.s, callid->s, callid->len) != 0 || - strncmp(dlg->from_tag.s, ftag->s, ftag->len) != 0) - return 0; - } - return 1; +static inline int match_downstream_dialog( + struct dlg_cell *dlg, str *callid, str *ftag) +{ + if(dlg == NULL || callid == NULL) + return 0; + if(ftag == NULL) { + if(dlg->callid.len != callid->len + || strncmp(dlg->callid.s, callid->s, callid->len) != 0) + return 0; + } else { + if(dlg->callid.len != callid->len || dlg->from_tag.len != ftag->len + || strncmp(dlg->callid.s, callid->s, callid->len) != 0 + || strncmp(dlg->from_tag.s, ftag->s, ftag->len) != 0) + return 0; + } + return 1; } /*! @@ -569,7 +584,8 @@ static inline int match_downstream_dialog(struct dlg_cell *dlg, str *callid, str * \return created dlg_out structure on success, NULL otherwise */ -struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str *to_uri, str* to_tag, str* branch); +struct dlg_cell_out *build_new_dlg_out( + struct dlg_cell *dlg, str *to_uri, str *to_tag, str *branch); /*! * \brief Remove all dlg_out entries from dlg structure expect that identified as dlg_do_not_remove @@ -579,7 +595,8 @@ struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str *to_uri, str* t * \return void */ -void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, struct dlg_cell *dlg, int only_mark); +void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, + struct dlg_cell *dlg, int only_mark); /*! * \brief Remove dlg_out entry identified by to_tag from dlg structure @@ -621,6 +638,6 @@ time_t api_get_dlg_expires(str *callid, str *ftag, str *ttag); void dlg_release(struct dlg_cell *dlg); -char* state_to_char(unsigned int state); +char *state_to_char(unsigned int state); #endif diff --git a/src/modules/ims_dialog/dlg_load.h b/src/modules/ims_dialog/dlg_load.h index 65af7eda3ff..be2d5f61ca3 100644 --- a/src/modules/ims_dialog/dlg_load.h +++ b/src/modules/ims_dialog/dlg_load.h @@ -33,11 +33,11 @@ #include "../../core/sr_module.h" /* terminate_dlg function prototype */ -typedef int (*ims_terminate_dlg_f)(str *callid, str *ftag, str *ttag, str *hdrs, - str *reason); +typedef int (*ims_terminate_dlg_f)( + str *callid, str *ftag, str *ttag, str *hdrs, str *reason); -typedef int (*ims_lookup_terminate_dlg_f)(unsigned int h_entry, - unsigned int h_id, str *hdrs); +typedef int (*ims_lookup_terminate_dlg_f)( + unsigned int h_entry, unsigned int h_id, str *hdrs); /* get the current dialog based on message function prototype */ typedef struct dlg_cell *(*ims_get_dlg_f)(struct sip_msg *msg); @@ -47,32 +47,33 @@ typedef time_t (*ims_get_dlg_expires_f)(str *callid, str *ftag, str *ttag); typedef void (*ims_release_dlg_f)(struct dlg_cell *dlg); -typedef struct ims_dlg_binds { - ims_register_dlgcb_f register_dlgcb; - ims_register_dlgcb_nodlg_f register_dlgcb_nodlg; - ims_terminate_dlg_f terminate_dlg; - ims_lookup_terminate_dlg_f lookup_terminate_dlg; - ims_set_dlg_variable_f set_dlg_var; - ims_get_dlg_variable_f get_dlg_var; - ims_get_dlg_expires_f get_dlg_expires; - ims_get_dlg_f get_dlg; - ims_release_dlg_f release_dlg; +typedef struct ims_dlg_binds +{ + ims_register_dlgcb_f register_dlgcb; + ims_register_dlgcb_nodlg_f register_dlgcb_nodlg; + ims_terminate_dlg_f terminate_dlg; + ims_lookup_terminate_dlg_f lookup_terminate_dlg; + ims_set_dlg_variable_f set_dlg_var; + ims_get_dlg_variable_f get_dlg_var; + ims_get_dlg_expires_f get_dlg_expires; + ims_get_dlg_f get_dlg; + ims_release_dlg_f release_dlg; } ims_dlg_api_t; -typedef int(*load_ims_dlg_f)(ims_dlg_api_t *dlgb ); +typedef int (*load_ims_dlg_f)(ims_dlg_api_t *dlgb); int load_ims_dlg(ims_dlg_api_t *dlgb); -static inline int load_ims_dlg_api(ims_dlg_api_t *dlgb ) +static inline int load_ims_dlg_api(ims_dlg_api_t *dlgb) { load_ims_dlg_f load_ims_dlg_p; /* import the DLG auto-loading function */ - if ( !(load_ims_dlg_p=(load_ims_dlg_f)find_export("load_ims_dlg", 0, 0))) + if(!(load_ims_dlg_p = (load_ims_dlg_f)find_export("load_ims_dlg", 0, 0))) return -1; /* let the auto-loading function load all DLG stuff */ - if (load_ims_dlg_p( dlgb )==-1) + if(load_ims_dlg_p(dlgb) == -1) return -1; return 0; diff --git a/src/modules/ims_dialog/dlg_ng_stats.c b/src/modules/ims_dialog/dlg_ng_stats.c index 744a394dc89..93334b53e9b 100644 --- a/src/modules/ims_dialog/dlg_ng_stats.c +++ b/src/modules/ims_dialog/dlg_ng_stats.c @@ -3,24 +3,23 @@ struct dialog_ng_counters_h dialog_ng_cnts_h = {0}; /* dialog_ng counters definitions */ -counter_def_t dialog_ng_cnt_defs[] = { - {&dialog_ng_cnts_h.active, "active", 0, 0, 0, - "number of current active (answered) dialogs"}, - {&dialog_ng_cnts_h.early, "early", 0, 0, 0, - "number of current early dialogs"}, - {&dialog_ng_cnts_h.expired, "expired", 0, 0, 0, - "number of expired dialogs (forcibly killed)"}, - {&dialog_ng_cnts_h.processed, "processed", 0, 0, 0, - "number of processed dialogs"}, - {0, 0, 0, 0, 0, 0 } -}; +counter_def_t dialog_ng_cnt_defs[] = { + {&dialog_ng_cnts_h.active, "active", 0, 0, 0, + "number of current active (answered) dialogs"}, + {&dialog_ng_cnts_h.early, "early", 0, 0, 0, + "number of current early dialogs"}, + {&dialog_ng_cnts_h.expired, "expired", 0, 0, 0, + "number of expired dialogs (forcibly killed)"}, + {&dialog_ng_cnts_h.processed, "processed", 0, 0, 0, + "number of processed dialogs"}, + {0, 0, 0, 0, 0, 0}}; /** initialize dialog_ng statistics. * @return < 0 on errror, 0 on success. */ int dialog_ng_stats_init() { - if (counter_register_array("dialog_ng", dialog_ng_cnt_defs) < 0) + if(counter_register_array("dialog_ng", dialog_ng_cnt_defs) < 0) goto error; return 0; error: diff --git a/src/modules/ims_dialog/dlg_ng_stats.h b/src/modules/ims_dialog/dlg_ng_stats.h index 9dfd53a182c..66f6950cc82 100644 --- a/src/modules/ims_dialog/dlg_ng_stats.h +++ b/src/modules/ims_dialog/dlg_ng_stats.h @@ -1,14 +1,14 @@ #ifndef DIALOG_NG_STATS_H -#define DIALOG_NG_STATS_H +#define DIALOG_NG_STATS_H #include "../../core/counters.h" -struct dialog_ng_counters_h { - counter_handle_t active; - counter_handle_t early; - counter_handle_t expired; - counter_handle_t processed; - +struct dialog_ng_counters_h +{ + counter_handle_t active; + counter_handle_t early; + counter_handle_t expired; + counter_handle_t processed; }; extern struct dialog_ng_counters_h dialog_ng_cnts_h; @@ -16,4 +16,4 @@ extern struct dialog_ng_counters_h dialog_ng_cnts_h; int dialog_ng_stats_init(); void dialog_ng_stats_destroy(); -#endif /* DIALOG_NG_STATS_H */ +#endif /* DIALOG_NG_STATS_H */ diff --git a/src/modules/ims_dialog/dlg_profile.c b/src/modules/ims_dialog/dlg_profile.c index 4337311029a..6ceab5161b2 100644 --- a/src/modules/ims_dialog/dlg_profile.c +++ b/src/modules/ims_dialog/dlg_profile.c @@ -46,8 +46,8 @@ extern struct tm_binds d_tmb; /*! global dialog message id */ -static unsigned int current_dlg_msg_id = 0 ; -static unsigned int current_dlg_msg_pid = 0 ; +static unsigned int current_dlg_msg_id = 0; +static unsigned int current_dlg_msg_pid = 0; /*! pending dialog links */ static struct dlg_profile_link *current_pending_linkers = NULL; @@ -56,8 +56,8 @@ static struct dlg_profile_link *current_pending_linkers = NULL; static struct dlg_profile_table *profiles = NULL; -static struct dlg_profile_table* new_dlg_profile( str *name, - unsigned int size, unsigned int has_value); +static struct dlg_profile_table *new_dlg_profile( + str *name, unsigned int size, unsigned int has_value); static sruid_t _dlg_profile_sruid; @@ -69,54 +69,55 @@ static sruid_t _dlg_profile_sruid; * \param has_value set to 0 for a profile without value, otherwise it has a value * \return 0 on success, -1 on failure */ -int add_profile_definitions( char* profiles, unsigned int has_value) +int add_profile_definitions(char *profiles, unsigned int has_value) { char *p; char *d; str name; unsigned int i; - if (profiles==NULL || strlen(profiles)==0 ) + if(profiles == NULL || strlen(profiles) == 0) return 0; p = profiles; do { /* locate name of profile */ name.s = p; - d = strchr( p, ';'); - if (d) { - name.len = d-p; + d = strchr(p, ';'); + if(d) { + name.len = d - p; d++; } else { name.len = strlen(p); } /* we have the name -> trim it for spaces */ - trim_spaces_lr( name ); + trim_spaces_lr(name); /* check len name */ - if (name.len==0) + if(name.len == 0) /* ignore */ continue; /* check the name format */ - for(i=0;i, char %c - use only " - "alphanumerical characters\n", name.len,name.s,name.s[i]); + "alphanumerical characters\n", + name.len, name.s, name.s[i]); return -1; } } /* name ok -> create the profile */ - LM_DBG("creating profile <%.*s>\n",name.len,name.s); + LM_DBG("creating profile <%.*s>\n", name.len, name.s); - if (new_dlg_profile( &name, PROFILE_HASH_SIZE, has_value)==NULL) { - LM_ERR("failed to create new profile <%.*s>\n",name.len,name.s); + if(new_dlg_profile(&name, PROFILE_HASH_SIZE, has_value) == NULL) { + LM_ERR("failed to create new profile <%.*s>\n", name.len, name.s); return -1; } - }while( (p=d)!=NULL ); + } while((p = d) != NULL); return 0; } @@ -128,13 +129,13 @@ int add_profile_definitions( char* profiles, unsigned int has_value) * \param name searched dialog profile * \return pointer to the profile on success, NULL otherwise */ -struct dlg_profile_table* search_dlg_profile(str *name) +struct dlg_profile_table *search_dlg_profile(str *name) { struct dlg_profile_table *profile; - for( profile=profiles ; profile ; profile=profile->next ) { - if (name->len==profile->name.len && - memcmp(name->s,profile->name.s,name->len)==0 ) + for(profile = profiles; profile; profile = profile->next) { + if(name->len == profile->name.len + && memcmp(name->s, profile->name.s, name->len) == 0) return profile; } return NULL; @@ -149,67 +150,68 @@ struct dlg_profile_table* search_dlg_profile(str *name) * \param has_value set to 0 for a profile without value, otherwise it has a value * \return pointer to the created dialog on success, NULL otherwise */ -static struct dlg_profile_table* new_dlg_profile( str *name, unsigned int size, - unsigned int has_value) +static struct dlg_profile_table *new_dlg_profile( + str *name, unsigned int size, unsigned int has_value) { struct dlg_profile_table *profile; struct dlg_profile_table *ptmp; unsigned int len; unsigned int i; - if ( name->s==NULL || name->len==0 || size==0 ) { + if(name->s == NULL || name->len == 0 || size == 0) { LM_ERR("invalid parameters\n"); return NULL; } - for( len=0,i=0 ; i<8*sizeof(size) ; i++ ) { - if ( size & (1<\n", - name->len, name->s); + if(profile != NULL) { + LM_ERR("duplicate dialog profile registered <%.*s>\n", name->len, + name->s); return NULL; } - len = sizeof(struct dlg_profile_table) + - size*sizeof(struct dlg_profile_entry) + - name->len + 1; + len = sizeof(struct dlg_profile_table) + + size * sizeof(struct dlg_profile_entry) + name->len + 1; profile = (struct dlg_profile_table *)shm_malloc(len); - if (profile==NULL) { + if(profile == NULL) { LM_ERR("no more shm mem\n"); return NULL; } - memset( profile , 0 , len); + memset(profile, 0, len); profile->size = size; - profile->has_value = (has_value==0)?0:1; + profile->has_value = (has_value == 0) ? 0 : 1; /* init lock */ - if (lock_init( &profile->lock )==NULL) { + if(lock_init(&profile->lock) == NULL) { LM_ERR("failed to init lock\n"); shm_free(profile); return NULL; } /* set inner pointers */ - profile->entries = (struct dlg_profile_entry*)(profile + 1); - profile->name.s = ((char*)profile->entries) + - size*sizeof(struct dlg_profile_entry); + profile->entries = (struct dlg_profile_entry *)(profile + 1); + profile->name.s = ((char *)profile->entries) + + size * sizeof(struct dlg_profile_entry); /* copy the name of the profile */ - memcpy( profile->name.s, name->s, name->len ); + memcpy(profile->name.s, name->s, name->len); profile->name.len = name->len; profile->name.s[profile->name.len] = 0; /* link profile */ - for( ptmp=profiles ; ptmp && ptmp->next; ptmp=ptmp->next ); - if (ptmp==NULL) + for(ptmp = profiles; ptmp && ptmp->next; ptmp = ptmp->next) + ; + if(ptmp == NULL) profiles = profile; else ptmp->next = profile; @@ -224,11 +226,11 @@ static struct dlg_profile_table* new_dlg_profile( str *name, unsigned int size, */ static void destroy_dlg_profile(struct dlg_profile_table *profile) { - if (profile==NULL) + if(profile == NULL) return; - lock_destroy( &profile->lock ); - shm_free( profile ); + lock_destroy(&profile->lock); + shm_free(profile); return; } @@ -243,7 +245,7 @@ void destroy_dlg_profiles(void) while(profiles) { profile = profiles; profiles = profiles->next; - destroy_dlg_profile( profile ); + destroy_dlg_profile(profile); } return; } @@ -263,22 +265,22 @@ void destroy_linkers(struct dlg_profile_link *linker) l = linker; linker = linker->next; /* unlink from profile table */ - if (l->hash_linker.next) { + if(l->hash_linker.next) { p_entry = &l->profile->entries[l->hash_linker.hash]; - lock_get( &l->profile->lock ); + lock_get(&l->profile->lock); lh = &l->hash_linker; /* last element on the list? */ - if (lh==lh->next) { + if(lh == lh->next) { p_entry->first = NULL; } else { - if (p_entry->first==lh) + if(p_entry->first == lh) p_entry->first = lh->next; lh->next->prev = lh->prev; lh->prev->next = lh->next; } lh->next = lh->prev = NULL; - p_entry->content --; - lock_release( &l->profile->lock ); + p_entry->content--; + lock_release(&l->profile->lock); } /* free memory */ shm_free(l); @@ -293,48 +295,47 @@ void destroy_linkers(struct dlg_profile_link *linker) * \param param unused * \return 1 */ -int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param ) +int profile_cleanup(struct sip_msg *msg, unsigned int flags, void *param) { - dlg_cell_t *dlg; - - current_dlg_msg_id = 0; - current_dlg_msg_pid = 0; - dlg = dlg_get_ctx_dialog(); - if (dlg != NULL) { - if (dlg->dflags & DLG_FLAG_TM) { - unref_dlg(dlg, 1); - } else { - /* dialog didn't make it to tm */ - unref_dlg(dlg, 2); - } - } - if (current_pending_linkers) { - destroy_linkers(current_pending_linkers); - current_pending_linkers = NULL; - } - - /* need to return non-zero - 0 will break the exec of the request */ - return 1; -} + dlg_cell_t *dlg; + + current_dlg_msg_id = 0; + current_dlg_msg_pid = 0; + dlg = dlg_get_ctx_dialog(); + if(dlg != NULL) { + if(dlg->dflags & DLG_FLAG_TM) { + unref_dlg(dlg, 1); + } else { + /* dialog didn't make it to tm */ + unref_dlg(dlg, 2); + } + } + if(current_pending_linkers) { + destroy_linkers(current_pending_linkers); + current_pending_linkers = NULL; + } + /* need to return non-zero - 0 will break the exec of the request */ + return 1; +} -struct dlg_cell* get_dialog_from_tm(struct cell *t) +struct dlg_cell *get_dialog_from_tm(struct cell *t) { - if (t==NULL || t==T_UNDEFINED) - return NULL; + if(t == NULL || t == T_UNDEFINED) + return NULL; - struct tm_callback* x = (struct tm_callback*)(t->tmcb_hl.first); + struct tm_callback *x = (struct tm_callback *)(t->tmcb_hl.first); - while(x){ - membar_depends(); - if (x->types==TMCB_MAX && x->callback==dlg_tmcb_dummy){ - return (struct dlg_cell*)(x->param); - } - x=x->next; - } + while(x) { + membar_depends(); + if(x->types == TMCB_MAX && x->callback == dlg_tmcb_dummy) { + return (struct dlg_cell *)(x->param); + } + x = x->next; + } - return NULL; + return NULL; } /*! @@ -345,15 +346,15 @@ struct dlg_cell* get_dialog_from_tm(struct cell *t) * \param profile dialog profile table (for hash size) * \return value hash if the value has a value, hash over dialog otherwise */ -inline static unsigned int calc_hash_profile(str *value, struct dlg_cell *dlg, - struct dlg_profile_table *profile) +inline static unsigned int calc_hash_profile( + str *value, struct dlg_cell *dlg, struct dlg_profile_table *profile) { - if (profile->has_value) { + if(profile->has_value) { /* do hash over the value */ - return core_hash( value, NULL, profile->size); + return core_hash(value, NULL, profile->size); } else { /* do hash over dialog pointer */ - return ((unsigned long)dlg) % profile->size ; + return ((unsigned long)dlg) % profile->size; } } @@ -363,7 +364,8 @@ inline static unsigned int calc_hash_profile(str *value, struct dlg_cell *dlg, * \param linker dialog linker * \param dlg dialog cell */ -static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *dlg) +static void link_dlg_profile( + struct dlg_profile_link *linker, struct dlg_cell *dlg) { unsigned int hash; struct dlg_profile_entry *p_entry; @@ -372,16 +374,16 @@ static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *d /* add the linker to the dialog */ /* FIXME zero h_id is not 100% for testing if the dialog is inserted * into the hash table -> we need circular lists -bogdan */ - if (dlg->h_id) { + if(dlg->h_id) { d_entry = &d_table->entries[dlg->h_entry]; - dlg_lock( d_table, d_entry); + dlg_lock(d_table, d_entry); linker->next = dlg->profile_links; - dlg->profile_links =linker; + dlg->profile_links = linker; linker->hash_linker.dlg = dlg; - dlg_unlock( d_table, d_entry); + dlg_unlock(d_table, d_entry); } else { linker->next = dlg->profile_links; - dlg->profile_links =linker; + dlg->profile_links = linker; linker->hash_linker.dlg = dlg; } @@ -391,18 +393,18 @@ static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *d /* insert into profile hash table */ p_entry = &linker->profile->entries[hash]; - lock_get( &linker->profile->lock ); - if (p_entry->first) { + lock_get(&linker->profile->lock); + if(p_entry->first) { linker->hash_linker.prev = p_entry->first->prev; linker->hash_linker.next = p_entry->first; p_entry->first->prev->next = &linker->hash_linker; p_entry->first->prev = &linker->hash_linker; } else { - p_entry->first = linker->hash_linker.next - = linker->hash_linker.prev = &linker->hash_linker; + p_entry->first = linker->hash_linker.next = linker->hash_linker.prev = + &linker->hash_linker; } - p_entry->content ++; - lock_release( &linker->profile->lock ); + p_entry->content++; + lock_release(&linker->profile->lock); } @@ -413,31 +415,30 @@ static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *d */ void set_current_dialog(sip_msg_t *msg, dlg_cell_t *dlg) { - struct dlg_profile_link *linker; - struct dlg_profile_link *tlinker; - - LM_DBG("setting current dialog [%u:%u]\n", dlg->h_entry, dlg->h_id); - /* if linkers are not from current request, just discard them */ - if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { - current_dlg_msg_id = msg->id; - current_dlg_msg_pid = msg->pid; - destroy_linkers(current_pending_linkers); - } else { - /* add the linker, one by one, to the dialog */ - linker = current_pending_linkers; - while (linker) { - tlinker = linker; - linker = linker->next; - /* process tlinker */ - tlinker->next = NULL; - link_dlg_profile( tlinker, dlg); - } - } - current_pending_linkers = NULL; + struct dlg_profile_link *linker; + struct dlg_profile_link *tlinker; + + LM_DBG("setting current dialog [%u:%u]\n", dlg->h_entry, dlg->h_id); + /* if linkers are not from current request, just discard them */ + if(msg->id != current_dlg_msg_id || msg->pid != current_dlg_msg_pid) { + current_dlg_msg_id = msg->id; + current_dlg_msg_pid = msg->pid; + destroy_linkers(current_pending_linkers); + } else { + /* add the linker, one by one, to the dialog */ + linker = current_pending_linkers; + while(linker) { + tlinker = linker; + linker = linker->next; + /* process tlinker */ + tlinker->next = NULL; + link_dlg_profile(tlinker, dlg); + } + } + current_pending_linkers = NULL; } - /*! * \brief Set a dialog profile * \param msg SIP message @@ -445,7 +446,8 @@ void set_current_dialog(sip_msg_t *msg, dlg_cell_t *dlg) * \param profile dialog profile table * \return 0 on success, -1 on failure */ -int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *profile) +int set_dlg_profile( + struct sip_msg *msg, str *value, struct dlg_profile_table *profile) { dlg_cell_t *dlg = NULL; dlg_profile_link_t *linker; @@ -453,16 +455,17 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p /* get current dialog */ dlg = dlg_get_msg_dialog(msg); - if (dlg==NULL && !is_route_type(REQUEST_ROUTE)) { + if(dlg == NULL && !is_route_type(REQUEST_ROUTE)) { LM_CRIT("BUG - dialog not found in a non REQUEST route (%d)\n", - REQUEST_ROUTE); + REQUEST_ROUTE); return -1; } /* build new linker */ - linker = (struct dlg_profile_link*)shm_malloc( - sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) ); - if (linker==NULL) { + linker = (struct dlg_profile_link *)shm_malloc( + sizeof(struct dlg_profile_link) + + (profile->has_value ? value->len : 0)); + if(linker == NULL) { LM_ERR("no more shm memory\n"); goto error; } @@ -473,28 +476,28 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p linker->hash_linker.linker = linker; /* set the value */ - if (profile->has_value) { - linker->hash_linker.value.s = (char*)(linker+1); - memcpy( linker->hash_linker.value.s, value->s, value->len); + if(profile->has_value) { + linker->hash_linker.value.s = (char *)(linker + 1); + memcpy(linker->hash_linker.value.s, value->s, value->len); linker->hash_linker.value.len = value->len; } sruid_next_safe(&_dlg_profile_sruid); strcpy(linker->hash_linker.puid, _dlg_profile_sruid.uid.s); linker->hash_linker.puid_len = _dlg_profile_sruid.uid.len; - if (dlg!=NULL) { + if(dlg != NULL) { /* add linker directly to the dialog and profile */ - link_dlg_profile( linker, dlg); + link_dlg_profile(linker, dlg); } else { /* if existing linkers are not from current request, just discard them */ - if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { + if(msg->id != current_dlg_msg_id || msg->pid != current_dlg_msg_pid) { current_dlg_msg_id = msg->id; current_dlg_msg_pid = msg->pid; destroy_linkers(current_pending_linkers); current_pending_linkers = NULL; } /* no dialog yet -> set linker as pending */ - if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { + if(msg->id != current_dlg_msg_id || msg->pid != current_dlg_msg_pid) { current_dlg_msg_id = msg->id; current_dlg_msg_pid = msg->pid; destroy_linkers(current_pending_linkers); @@ -519,15 +522,15 @@ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *p * \param profile dialog profile table * \return 1 on success, -1 on failure */ -int unset_dlg_profile(struct sip_msg *msg, str *value, - struct dlg_profile_table *profile) +int unset_dlg_profile( + struct sip_msg *msg, str *value, struct dlg_profile_table *profile) { dlg_cell_t *dlg; dlg_profile_link_t *linker; dlg_profile_link_t *linker_prev; dlg_entry_t *d_entry; - if (is_route_type(REQUEST_ROUTE)) { + if(is_route_type(REQUEST_ROUTE)) { LM_ERR("dialog delete profile cannot be used in request route\n"); return -1; } @@ -535,22 +538,24 @@ int unset_dlg_profile(struct sip_msg *msg, str *value, /* get current dialog */ dlg = dlg_get_msg_dialog(msg); - if (dlg==NULL) { + if(dlg == NULL) { LM_WARN("dialog is NULL for delete profile\n"); return -1; } /* check the dialog linkers */ d_entry = &d_table->entries[dlg->h_entry]; - dlg_lock( d_table, d_entry); + dlg_lock(d_table, d_entry); linker = dlg->profile_links; linker_prev = NULL; - for( ; linker ; linker_prev=linker,linker=linker->next) { - if (linker->profile==profile) { - if (profile->has_value==0) { + for(; linker; linker_prev = linker, linker = linker->next) { + if(linker->profile == profile) { + if(profile->has_value == 0) { goto found; - } else if (value && value->len==linker->hash_linker.value.len && - memcmp(value->s,linker->hash_linker.value.s,value->len)==0){ + } else if(value && value->len == linker->hash_linker.value.len + && memcmp(value->s, linker->hash_linker.value.s, + value->len) + == 0) { goto found; } /* allow further search - maybe the dialog is inserted twice in @@ -558,20 +563,20 @@ int unset_dlg_profile(struct sip_msg *msg, str *value, */ } } - dlg_unlock( d_table, d_entry); + dlg_unlock(d_table, d_entry); dlg_release(dlg); return -1; found: /* table still locked */ /* remove the linker element from dialog */ - if (linker_prev==NULL) { + if(linker_prev == NULL) { dlg->profile_links = linker->next; } else { linker_prev->next = linker->next; } linker->next = NULL; - dlg_unlock( d_table, d_entry); + dlg_unlock(d_table, d_entry); /* remove linker from profile table and free it */ destroy_linkers(linker); dlg_release(dlg); @@ -586,55 +591,58 @@ int unset_dlg_profile(struct sip_msg *msg, str *value, * \param value value * \return 1 on success, -1 on failure */ -int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile, - str *value) { +int is_dlg_in_profile( + struct sip_msg *msg, struct dlg_profile_table *profile, str *value) +{ struct dlg_cell *dlg; struct dlg_profile_link *linker; struct dlg_entry *d_entry; - int ret; + int ret; LM_DBG("Getting current dialog"); /* get current dialog */ dlg = dlg_get_msg_dialog(msg); - if (dlg == NULL) { + if(dlg == NULL) { LM_DBG("Error: Current dlg is null"); return -1; } LM_DBG("Current dlg found"); - ret = -1; + ret = -1; /* check the dialog linkers */ d_entry = &d_table->entries[dlg->h_entry]; - dlg_lock( d_table, d_entry); - for (linker = dlg->profile_links; linker; linker = linker->next) { + dlg_lock(d_table, d_entry); + for(linker = dlg->profile_links; linker; linker = linker->next) { LM_DBG("Running through linkers"); - if (linker->profile == profile) { + if(linker->profile == profile) { LM_DBG("Profile matches"); - if (profile->has_value == 0) { + if(profile->has_value == 0) { LM_DBG("Profile has value is zero returning true"); - dlg_unlock( d_table, d_entry); + dlg_unlock(d_table, d_entry); ret = 1; - goto done; - } else if (value && value->len == linker->hash_linker.value.len - && memcmp(value->s, linker->hash_linker.value.s, value->len) - == 0) { - LM_DBG("Profile has value equal to passed value returning true"); - dlg_unlock( d_table, d_entry); + goto done; + } else if(value && value->len == linker->hash_linker.value.len + && memcmp(value->s, linker->hash_linker.value.s, + value->len) + == 0) { + LM_DBG("Profile has value equal to passed value returning " + "true"); + dlg_unlock(d_table, d_entry); ret = 1; - goto done; + goto done; } /* allow further search - maybe the dialog is inserted twice in * the same profile, but with different values -bogdan */ } } - dlg_unlock( d_table, d_entry); - + dlg_unlock(d_table, d_entry); + done: - dlg_release(dlg); - return ret; + dlg_release(dlg); + return ret; } @@ -646,36 +654,36 @@ int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile, */ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value) { - unsigned int n,i; + unsigned int n, i; struct dlg_profile_hash *ph; - if (profile->has_value==0 || value==NULL) { + if(profile->has_value == 0 || value == NULL) { /* iterate through the hash and count all records */ - lock_get( &profile->lock ); - for( i=0,n=0 ; isize ; i++ ) + lock_get(&profile->lock); + for(i = 0, n = 0; i < profile->size; i++) n += profile->entries[i].content; - lock_release( &profile->lock ); + lock_release(&profile->lock); return n; } else { /* iterate through the hash entry and count only matching */ /* calculate the hash position */ - i = calc_hash_profile( value, NULL, profile); + i = calc_hash_profile(value, NULL, profile); n = 0; - lock_get( &profile->lock ); + lock_get(&profile->lock); ph = profile->entries[i].first; if(ph) { do { /* compare */ - if ( value->len==ph->value.len && - memcmp(value->s,ph->value.s,value->len)==0 ) { + if(value->len == ph->value.len + && memcmp(value->s, ph->value.s, value->len) == 0) { /* found */ n++; } /* next */ - ph=ph->next; - }while( ph!=profile->entries[i].first ); + ph = ph->next; + } while(ph != profile->entries[i].first); } - lock_release( &profile->lock ); + lock_release(&profile->lock); return n; } } @@ -683,11 +691,12 @@ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value) /* * Determine if message is in a dialog currently being tracked */ -int is_known_dlg(struct sip_msg *msg) { +int is_known_dlg(struct sip_msg *msg) +{ dlg_cell_t *dlg; dlg = dlg_get_msg_dialog(msg); - + if(dlg == NULL) return -1; @@ -705,12 +714,12 @@ int is_known_dlg(struct sip_msg *msg) { * \param param unused * \return MI root output on success, NULL on failure */ -struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param) +struct mi_root *mi_get_profile(struct mi_root *cmd_tree, void *param) { - struct mi_node* node; - struct mi_root* rpl_tree= NULL; - struct mi_node* rpl = NULL; - struct mi_attr* attr; + struct mi_node *node; + struct mi_root *rpl_tree = NULL; + struct mi_node *rpl = NULL; + struct mi_attr *attr; struct dlg_profile_table *profile; str *value; str *profile_name; @@ -719,47 +728,48 @@ struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param) char *p; node = cmd_tree->node.kids; - if (node==NULL || !node->value.s || !node->value.len) - return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); + if(node == NULL || !node->value.s || !node->value.len) + return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); profile_name = &node->value; - if (node->next) { + if(node->next) { node = node->next; - if (!node->value.s || !node->value.len) - return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM)); - if (node->next) - return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); + if(!node->value.s || !node->value.len) + return init_mi_tree(400, MI_SSTR(MI_BAD_PARM)); + if(node->next) + return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); value = &node->value; } else { value = NULL; } /* search for the profile */ - profile = search_dlg_profile( profile_name ); - if (profile==NULL) - return init_mi_tree( 404, MI_SSTR("Profile not found")); + profile = search_dlg_profile(profile_name); + if(profile == NULL) + return init_mi_tree(404, MI_SSTR("Profile not found")); - size = get_profile_size( profile , value ); + size = get_profile_size(profile, value); - rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); - if (rpl_tree==0) + rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); + if(rpl_tree == 0) return 0; rpl = &rpl_tree->node; node = add_mi_node_child(rpl, MI_DUP_VALUE, "profile", 7, NULL, 0); - if (node==0) { + if(node == 0) { free_mi_tree(rpl_tree); return NULL; } - attr = add_mi_attr(node, MI_DUP_VALUE, "name", 4, - profile->name.s, profile->name.len); + attr = add_mi_attr( + node, MI_DUP_VALUE, "name", 4, profile->name.s, profile->name.len); if(attr == NULL) { goto error; } - if (value) { - attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, value->s, value->len); + if(value) { + attr = add_mi_attr( + node, MI_DUP_VALUE, "value", 5, value->s, value->len); } else { attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, NULL, 0); } @@ -767,7 +777,7 @@ struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param) goto error; } - p= int2str((unsigned long)size, &len); + p = int2str((unsigned long)size, &len); attr = add_mi_attr(node, MI_DUP_VALUE, "count", 5, p, len); if(attr == NULL) { goto error; @@ -786,11 +796,11 @@ struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param) * \param param unused * \return MI root output on success, NULL on failure */ -struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param ) +struct mi_root *mi_profile_list(struct mi_root *cmd_tree, void *param) { - struct mi_node* node; - struct mi_root* rpl_tree= NULL; - struct mi_node* rpl = NULL; + struct mi_node *node; + struct mi_root *rpl_tree = NULL; + struct mi_node *rpl = NULL; struct dlg_profile_table *profile; struct dlg_profile_hash *ph; str *profile_name; @@ -798,66 +808,66 @@ struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param ) unsigned int i; node = cmd_tree->node.kids; - if (node==NULL || !node->value.s || !node->value.len) - return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); + if(node == NULL || !node->value.s || !node->value.len) + return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); profile_name = &node->value; - if (node->next) { + if(node->next) { node = node->next; - if (!node->value.s || !node->value.len) - return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM)); - if (node->next) - return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM)); + if(!node->value.s || !node->value.len) + return init_mi_tree(400, MI_SSTR(MI_BAD_PARM)); + if(node->next) + return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM)); value = &node->value; } else { value = NULL; } /* search for the profile */ - profile = search_dlg_profile( profile_name ); - if (profile==NULL) - return init_mi_tree( 404, MI_SSTR("Profile not found")); + profile = search_dlg_profile(profile_name); + if(profile == NULL) + return init_mi_tree(404, MI_SSTR("Profile not found")); - rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK)); - if (rpl_tree==0) + rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK)); + if(rpl_tree == 0) return 0; rpl = &rpl_tree->node; /* go through the hash and print the dialogs */ - if (profile->has_value==0 || value==NULL) { + if(profile->has_value == 0 || value == NULL) { /* no value */ - lock_get( &profile->lock ); - for ( i=0 ; i< profile->size ; i++ ) { + lock_get(&profile->lock); + for(i = 0; i < profile->size; i++) { ph = profile->entries[i].first; if(ph) { do { /* print dialog */ - if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 ) + if(mi_print_dlg(rpl, ph->dlg, 0) != 0) goto error; /* next */ - ph=ph->next; - }while( ph!=profile->entries[i].first ); + ph = ph->next; + } while(ph != profile->entries[i].first); } - lock_release( &profile->lock ); + lock_release(&profile->lock); } } else { /* check for value also */ - lock_get( &profile->lock ); - for ( i=0 ; i< profile->size ; i++ ) { + lock_get(&profile->lock); + for(i = 0; i < profile->size; i++) { ph = profile->entries[i].first; if(ph) { do { - if ( value->len==ph->value.len && - memcmp(value->s,ph->value.s,value->len)==0 ) { + if(value->len == ph->value.len + && memcmp(value->s, ph->value.s, value->len) == 0) { /* print dialog */ - if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 ) + if(mi_print_dlg(rpl, ph->dlg, 0) != 0) goto error; } /* next */ - ph=ph->next; - }while( ph!=profile->entries[i].first ); + ph = ph->next; + } while(ph != profile->entries[i].first); } - lock_release( &profile->lock ); + lock_release(&profile->lock); } } diff --git a/src/modules/ims_dialog/dlg_profile.h b/src/modules/ims_dialog/dlg_profile.h index 3220898ee23..15e6a9a2139 100644 --- a/src/modules/ims_dialog/dlg_profile.h +++ b/src/modules/ims_dialog/dlg_profile.h @@ -26,7 +26,6 @@ */ - #ifndef _DIALOG_DLG_PROFILE_H_ #define _DIALOG_DLG_PROFILE_H_ @@ -38,7 +37,6 @@ #include "../../core/utils/sruid.h" - /*! * \file * \brief Profile related functions for the dialog module @@ -48,8 +46,9 @@ /*! dialog profile hash list */ -typedef struct dlg_profile_hash { - str value; /*!< hash value */ +typedef struct dlg_profile_hash +{ + str value; /*!< hash value */ struct dlg_cell *dlg; /*!< dialog cell */ char puid[SRUID_SIZE]; int puid_len; @@ -63,31 +62,35 @@ typedef struct dlg_profile_hash { /*! list with links to dialog profiles */ -typedef struct dlg_profile_link { +typedef struct dlg_profile_link +{ struct dlg_profile_hash hash_linker; - struct dlg_profile_link *next; + struct dlg_profile_link *next; struct dlg_profile_table *profile; } dlg_profile_link_t; /*! dialog profile entry */ -struct dlg_profile_entry { +struct dlg_profile_entry +{ struct dlg_profile_hash *first; unsigned int content; /*!< content of the entry */ }; /*! dialog profile table */ -struct dlg_profile_table { - str name; /*!< name of the dialog profile */ +struct dlg_profile_table +{ + str name; /*!< name of the dialog profile */ unsigned int size; /*!< size of the dialog profile */ - unsigned int has_value; /*!< 0 for profiles without value, otherwise it has a value */ + unsigned int + has_value; /*!< 0 for profiles without value, otherwise it has a value */ gen_lock_t lock; /*! lock for concurrent access */ struct dlg_profile_entry *entries; struct dlg_profile_table *next; }; -struct dlg_cell* get_dialog_from_tm(struct cell *t); +struct dlg_cell *get_dialog_from_tm(struct cell *t); /*! * \brief Add profile definitions to the global list @@ -96,7 +99,7 @@ struct dlg_cell* get_dialog_from_tm(struct cell *t); * \param has_value set to 0 for a profile without value, otherwise it has a value * \return 0 on success, -1 on failure */ -int add_profile_definitions( char* profiles, unsigned int has_value); +int add_profile_definitions(char *profiles, unsigned int has_value); /*! @@ -111,7 +114,7 @@ void destroy_dlg_profiles(void); * \param name searched dialog profile * \return pointer to the profile on success, NULL otherwise */ -struct dlg_profile_table* search_dlg_profile(str *name); +struct dlg_profile_table *search_dlg_profile(str *name); /*! @@ -121,13 +124,13 @@ struct dlg_profile_table* search_dlg_profile(str *name); * \param param unused * \return 1 */ -int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param ); +int profile_cleanup(struct sip_msg *msg, unsigned int flags, void *param); /*! * \brief Destroy dialog linkers * \param linker dialog linker - */ + */ void destroy_linkers(struct dlg_profile_link *linker); @@ -146,8 +149,8 @@ void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg); * \param profile dialog profile table * \return 0 on success, -1 on failure */ -int set_dlg_profile(struct sip_msg *msg, str *value, - struct dlg_profile_table *profile); +int set_dlg_profile( + struct sip_msg *msg, str *value, struct dlg_profile_table *profile); /*! @@ -157,8 +160,8 @@ int set_dlg_profile(struct sip_msg *msg, str *value, * \param profile dialog profile table * \return 1 on success, -1 on failure */ -int unset_dlg_profile(struct sip_msg *msg, str *value, - struct dlg_profile_table *profile); +int unset_dlg_profile( + struct sip_msg *msg, str *value, struct dlg_profile_table *profile); /*! @@ -168,8 +171,8 @@ int unset_dlg_profile(struct sip_msg *msg, str *value, * \param value value * \return 1 on success, -1 on failure */ -int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile, - str *value); +int is_dlg_in_profile( + struct sip_msg *msg, struct dlg_profile_table *profile, str *value); /*! @@ -187,7 +190,7 @@ unsigned int get_profile_size(struct dlg_profile_table *profile, str *value); * \param param MI parameter * \return MI root output on success, NULL on failure */ -struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param ); +struct mi_root *mi_get_profile(struct mi_root *cmd_tree, void *param); /*! @@ -196,7 +199,7 @@ struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param ); * \param param unused * \return MI root output on success, NULL on failure */ -struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param ); +struct mi_root *mi_profile_list(struct mi_root *cmd_tree, void *param); /*! * \brief return true if the messages belongs to a tracked dialog diff --git a/src/modules/ims_dialog/dlg_req_within.c b/src/modules/ims_dialog/dlg_req_within.c index f34ede926ea..14a632bb001 100644 --- a/src/modules/ims_dialog/dlg_req_within.c +++ b/src/modules/ims_dialog/dlg_req_within.c @@ -37,213 +37,219 @@ #include "dlg_db_handler.h" #include "dlg_ng_stats.h" -#define MAX_FWD_HDR "Max-Forwards: " MAX_FWD CRLF -#define MAX_FWD_HDR_LEN (sizeof(MAX_FWD_HDR) - 1) +#define MAX_FWD_HDR "Max-Forwards: " MAX_FWD CRLF +#define MAX_FWD_HDR_LEN (sizeof(MAX_FWD_HDR) - 1) extern str dlg_extra_hdrs; extern int dlg_db_mode; extern struct dialog_ng_counters_h dialog_ng_cnts_h; -int free_tm_dlg(dlg_t *td) { - if (td) { - if (td->route_set) - free_rr(&td->route_set); - pkg_free(td); - } - return 0; +int free_tm_dlg(dlg_t *td) +{ + if(td) { + if(td->route_set) + free_rr(&td->route_set); + pkg_free(td); + } + return 0; } -dlg_t * build_dlg_t(struct dlg_cell * cell, int dir) { - - dlg_t* td = NULL; - str cseq; - unsigned int loc_seq; - str route_set; - str contact; - - struct dlg_cell_out *dlg_out = 0; - struct dlg_entry_out* dlg_entry_out = 0; - - /* if trying to send by to callee we need to get the corresponding dlg_out cell */ - lock_get(cell->dlg_out_entries_lock); - dlg_entry_out = &cell->dlg_entry_out; - - dlg_out = dlg_entry_out->first; - //must be concurrent call - lets choose - TODO - ie. check if there is more - - if (!dlg_out) { - LM_ERR("Trying to send BYE for dialog with no callee leg\n"); - lock_release(cell->dlg_out_entries_lock); - return NULL; - } - - td = (dlg_t*) pkg_malloc(sizeof (dlg_t)); - if (!td) { - - LM_ERR("out of pkg memory\n"); - lock_release(cell->dlg_out_entries_lock); - return NULL; - } - memset(td, 0, sizeof (dlg_t)); - - if (dir == DLG_CALLER_LEG) { - cseq = cell->first_req_cseq; - route_set = cell->caller_route_set; - contact = cell->caller_contact; - td->rem_uri = cell->from_uri; - td->loc_uri = dlg_out->to_uri; - td->id.rem_tag = cell->from_tag; - td->id.loc_tag = dlg_out->to_tag; - td->send_sock = cell->caller_bind_addr; - } else { - cseq = dlg_out->callee_cseq; - route_set = dlg_out->callee_route_set; - contact = dlg_out->callee_contact; - td->rem_uri = dlg_out->to_uri; - td->loc_uri = cell->from_uri; - td->id.rem_tag = dlg_out->to_tag; - td->id.loc_tag = cell->from_tag; - td->send_sock = dlg_out->callee_bind_addr; - } - - if (str2int(&cseq, &loc_seq) != 0) { - LM_ERR("invalid cseq\n"); - goto error; - } - - /*we don not increase here the cseq as this will be done by TM*/ - td->loc_seq.value = loc_seq; - td->loc_seq.is_set = 1; - - /*route set*/ - if (route_set.s && route_set.len) { - - if (parse_rr_body(route_set.s, route_set.len, &td->route_set) != 0) { - LM_ERR("failed to parse route set\n"); - goto error; - } - } - - if (contact.s == 0 || contact.len == 0) { - - LM_ERR("no contact available\n"); - goto error; - } - - td->id.call_id = cell->callid; - td->rem_target = contact; - td->state = DLG_CONFIRMED; - - lock_release(cell->dlg_out_entries_lock); - return td; +dlg_t *build_dlg_t(struct dlg_cell *cell, int dir) +{ + + dlg_t *td = NULL; + str cseq; + unsigned int loc_seq; + str route_set; + str contact; + + struct dlg_cell_out *dlg_out = 0; + struct dlg_entry_out *dlg_entry_out = 0; + + /* if trying to send by to callee we need to get the corresponding dlg_out cell */ + lock_get(cell->dlg_out_entries_lock); + dlg_entry_out = &cell->dlg_entry_out; + + dlg_out = dlg_entry_out->first; + //must be concurrent call - lets choose - TODO - ie. check if there is more + + if(!dlg_out) { + LM_ERR("Trying to send BYE for dialog with no callee leg\n"); + lock_release(cell->dlg_out_entries_lock); + return NULL; + } + + td = (dlg_t *)pkg_malloc(sizeof(dlg_t)); + if(!td) { + + LM_ERR("out of pkg memory\n"); + lock_release(cell->dlg_out_entries_lock); + return NULL; + } + memset(td, 0, sizeof(dlg_t)); + + if(dir == DLG_CALLER_LEG) { + cseq = cell->first_req_cseq; + route_set = cell->caller_route_set; + contact = cell->caller_contact; + td->rem_uri = cell->from_uri; + td->loc_uri = dlg_out->to_uri; + td->id.rem_tag = cell->from_tag; + td->id.loc_tag = dlg_out->to_tag; + td->send_sock = cell->caller_bind_addr; + } else { + cseq = dlg_out->callee_cseq; + route_set = dlg_out->callee_route_set; + contact = dlg_out->callee_contact; + td->rem_uri = dlg_out->to_uri; + td->loc_uri = cell->from_uri; + td->id.rem_tag = dlg_out->to_tag; + td->id.loc_tag = cell->from_tag; + td->send_sock = dlg_out->callee_bind_addr; + } + + if(str2int(&cseq, &loc_seq) != 0) { + LM_ERR("invalid cseq\n"); + goto error; + } + + /*we don not increase here the cseq as this will be done by TM*/ + td->loc_seq.value = loc_seq; + td->loc_seq.is_set = 1; + + /*route set*/ + if(route_set.s && route_set.len) { + + if(parse_rr_body(route_set.s, route_set.len, &td->route_set) != 0) { + LM_ERR("failed to parse route set\n"); + goto error; + } + } -error: - lock_release(cell->dlg_out_entries_lock); - free_tm_dlg(td); - return NULL; -} + if(contact.s == 0 || contact.len == 0) { -/*callback function to handle responses to the BYE request */ -void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps) { + LM_ERR("no contact available\n"); + goto error; + } - struct dlg_cell* dlg; - int event, old_state, new_state, unref, ret; - struct dlg_cell_out *dlg_out = 0; + td->id.call_id = cell->callid; + td->rem_target = contact; + td->state = DLG_CONFIRMED; - if (ps->param == NULL || *ps->param == NULL) { - LM_ERR("invalid parameter\n"); - return; - } + lock_release(cell->dlg_out_entries_lock); + return td; - if (ps->code < 200) { - LM_DBG("receiving a provisional reply\n"); - return; - } +error: + lock_release(cell->dlg_out_entries_lock); + free_tm_dlg(td); + return NULL; +} - LM_DBG("receiving a final reply %d\n", ps->code); +/*callback function to handle responses to the BYE request */ +void bye_reply_cb(struct cell *t, int type, struct tmcb_params *ps) +{ + + struct dlg_cell *dlg; + int event, old_state, new_state, unref, ret; + struct dlg_cell_out *dlg_out = 0; + + if(ps->param == NULL || *ps->param == NULL) { + LM_ERR("invalid parameter\n"); + return; + } + + if(ps->code < 200) { + LM_DBG("receiving a provisional reply\n"); + return; + } + + LM_DBG("receiving a final reply %d\n", ps->code); + + dlg = (struct dlg_cell *)(*(ps->param)); + event = DLG_EVENT_REQBYE; + + //get the corresponding dlg out structure for this REQ + struct dlg_entry_out *dlg_entry_out = &dlg->dlg_entry_out; + lock_get(dlg->dlg_out_entries_lock); + dlg_out = dlg_entry_out->first; //TODO check for concurrent call + if(!dlg_out) + return; + + next_state_dlg( + dlg, event, &old_state, &new_state, &unref, &dlg_out->to_tag); + + lock_release(dlg->dlg_out_entries_lock); + + if(new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) { + + LM_DBG("removing dialog with h_entry %u and h_id %u\n", dlg->h_entry, + dlg->h_id); + + /* remove from timer */ + ret = remove_dialog_timer(&dlg->tl); + if(ret < 0) { + LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " + "with clid '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s); + } else if(ret > 0) { + LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " + "with clid '%.*s'\n", + dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, + dlg->callid.s); + } else { + unref++; + } - dlg = (struct dlg_cell *) (*(ps->param)); - event = DLG_EVENT_REQBYE; + counter_add(dialog_ng_cnts_h.active, -1); - //get the corresponding dlg out structure for this REQ - struct dlg_entry_out *dlg_entry_out = &dlg->dlg_entry_out; - lock_get(dlg->dlg_out_entries_lock); - dlg_out = dlg_entry_out->first; //TODO check for concurrent call - if (!dlg_out) - return; + /* dialog terminated (BYE) */ + run_dlg_callbacks( + DLGCB_TERMINATED, dlg, ps->req, ps->rpl, DLG_DIR_NONE, 0); + + /* derefering the dialog */ + unref_dlg(dlg, + unref); /*removed the extra +1 on the unref that is usually added in the unref of next_state_dlg */ + } - next_state_dlg(dlg, event, &old_state, &new_state, &unref, &dlg_out->to_tag); - - lock_release(dlg->dlg_out_entries_lock); - - if (new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) { - - LM_DBG("removing dialog with h_entry %u and h_id %u\n", - dlg->h_entry, dlg->h_id); - - /* remove from timer */ - ret = remove_dialog_timer(&dlg->tl); - if (ret < 0) { - LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " - "with clid '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s); - } else if (ret > 0) { - LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] " - "with clid '%.*s'\n", - dlg, dlg->h_entry, dlg->h_id, - dlg->callid.len, dlg->callid.s); - } else { - unref++; - } - - counter_add(dialog_ng_cnts_h.active, -1); - - /* dialog terminated (BYE) */ - run_dlg_callbacks(DLGCB_TERMINATED, dlg, ps->req, ps->rpl, DLG_DIR_NONE, 0); - - /* derefering the dialog */ - unref_dlg(dlg, unref); /*removed the extra +1 on the unref that is usually added in the unref of next_state_dlg */ - } - - if (new_state == DLG_STATE_DELETED && old_state == DLG_STATE_DELETED) { - /* trash the dialog from DB and memory */ - if (dlg_db_mode) - remove_dialog_in_from_db(dlg); - - /* force delete from mem */ - unref_dlg(dlg, 1); - } + if(new_state == DLG_STATE_DELETED && old_state == DLG_STATE_DELETED) { + /* trash the dialog from DB and memory */ + if(dlg_db_mode) + remove_dialog_in_from_db(dlg); + /* force delete from mem */ + unref_dlg(dlg, 1); + } } -static inline int build_extra_hdr(struct dlg_cell * cell, str *extra_hdrs, - str *str_hdr) { - char *p; +static inline int build_extra_hdr( + struct dlg_cell *cell, str *extra_hdrs, str *str_hdr) +{ + char *p; - str_hdr->len = MAX_FWD_HDR_LEN + dlg_extra_hdrs.len; - if (extra_hdrs && extra_hdrs->len > 0) - str_hdr->len += extra_hdrs->len; + str_hdr->len = MAX_FWD_HDR_LEN + dlg_extra_hdrs.len; + if(extra_hdrs && extra_hdrs->len > 0) + str_hdr->len += extra_hdrs->len; - str_hdr->s = (char*) pkg_malloc(str_hdr->len * sizeof (char)); - if (!str_hdr->s) { - LM_ERR("out of pkg memory\n"); - goto error; - } + str_hdr->s = (char *)pkg_malloc(str_hdr->len * sizeof(char)); + if(!str_hdr->s) { + LM_ERR("out of pkg memory\n"); + goto error; + } - memcpy(str_hdr->s, MAX_FWD_HDR, MAX_FWD_HDR_LEN); - p = str_hdr->s + MAX_FWD_HDR_LEN; - if (dlg_extra_hdrs.len) { - memcpy(p, dlg_extra_hdrs.s, dlg_extra_hdrs.len); - p += dlg_extra_hdrs.len; - } - if (extra_hdrs && extra_hdrs->len > 0) - memcpy(p, extra_hdrs->s, extra_hdrs->len); + memcpy(str_hdr->s, MAX_FWD_HDR, MAX_FWD_HDR_LEN); + p = str_hdr->s + MAX_FWD_HDR_LEN; + if(dlg_extra_hdrs.len) { + memcpy(p, dlg_extra_hdrs.s, dlg_extra_hdrs.len); + p += dlg_extra_hdrs.len; + } + if(extra_hdrs && extra_hdrs->len > 0) + memcpy(p, extra_hdrs->s, extra_hdrs->len); - return 0; + return 0; error: - return -1; + return -1; } /* cell- pointer to a struct dlg_cell @@ -251,49 +257,52 @@ static inline int build_extra_hdr(struct dlg_cell * cell, str *extra_hdrs, * DLG_CALLER_LEG (0): caller * DLG_CALLEE_LEG (1): callee */ -static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs) { - uac_req_t uac_r; - dlg_t* dialog_info; - str met = {"BYE", 3}; - int result; - /* do not send BYE request for non-confirmed dialogs (not supported) */ - if (cell->state != DLG_STATE_CONFIRMED) { - LM_ERR("terminating only 1 side of non-confirmed dialogs not supported by this function\n"); - return -1; - } - - /*verify direction*/ - if ((dialog_info = build_dlg_t(cell, dir)) == 0) { - LM_ERR("failed to create dlg_t\n"); - goto err; - } - - LM_DBG("sending BYE to %s\n", (dir == DLG_CALLER_LEG) ? "caller" : "callee"); - - ref_dlg(cell, 1); - - memset(&uac_r, '\0', sizeof (uac_req_t)); - set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED, - bye_reply_cb, (void*) cell); - - result = d_tmb.t_request_within(&uac_r); - - if (result < 0) { - LM_ERR("failed to send the BYE request\n"); - goto err1; - } - - free_tm_dlg(dialog_info); - - LM_DBG("BYE sent to %s\n", (dir == 0) ? "caller" : "callee"); - return 0; +static inline int send_bye(struct dlg_cell *cell, int dir, str *hdrs) +{ + uac_req_t uac_r; + dlg_t *dialog_info; + str met = {"BYE", 3}; + int result; + /* do not send BYE request for non-confirmed dialogs (not supported) */ + if(cell->state != DLG_STATE_CONFIRMED) { + LM_ERR("terminating only 1 side of non-confirmed dialogs not supported " + "by this function\n"); + return -1; + } + + /*verify direction*/ + if((dialog_info = build_dlg_t(cell, dir)) == 0) { + LM_ERR("failed to create dlg_t\n"); + goto err; + } + + LM_DBG("sending BYE to %s\n", + (dir == DLG_CALLER_LEG) ? "caller" : "callee"); + + ref_dlg(cell, 1); + + memset(&uac_r, '\0', sizeof(uac_req_t)); + set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED, + bye_reply_cb, (void *)cell); + + result = d_tmb.t_request_within(&uac_r); + + if(result < 0) { + LM_ERR("failed to send the BYE request\n"); + goto err1; + } + + free_tm_dlg(dialog_info); + + LM_DBG("BYE sent to %s\n", (dir == 0) ? "caller" : "callee"); + return 0; err1: - unref_dlg(cell, 1); + unref_dlg(cell, 1); err: - if (dialog_info) - free_tm_dlg(dialog_info); - return -1; + if(dialog_info) + free_tm_dlg(dialog_info); + return -1; } /*static void early_transaction_destroyed(struct cell* t, int type, struct tmcb_params *param) { @@ -310,233 +319,243 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs) { * 1: callee * 2: all */ -int dlg_terminate(struct dlg_cell *dlg, struct sip_msg *msg, str *reason, int side, str *extra_hdrs) { - - struct cell* t; - str default_reason = {"call failed", 11}; - int cfg_cmd = 0; - str default_extra_headers = {0,0}; - - if (!dlg) { - LM_ERR("calling end_dialog with NULL pointer dlg\n"); - return -1; - } - - if (!extra_hdrs) - extra_hdrs = &default_extra_headers; - - - if (msg) { - //assume called from cfg command -> dlg_terminate, as opposed to internal API or mi interface - cfg_cmd = 1; - } - - if (!reason || reason->len <= 0 || !reason->s) { - reason = &default_reason; - } - - if (dlg->state != DLG_STATE_CONFIRMED) { - if (side != 2) { - LM_ERR("can't terminate only 1 side of an early dialog\n"); - return -1; - } - if (dlg->transaction) { - LM_DBG("terminating early dialog with %d outbound forks on transaction %p\n", - dlg->transaction->nr_of_outgoings, dlg->transaction); - - t = dlg->transaction; - - if (t && t!=(void*) -1 && t->uas.request) { - if (t->method.len!=6 || t->method.s[0]!='I' || t->method.s[1]!='N' || t->method.s[2]!='V') - { - //well this is the transaction of a subsequent request within the dialog - //and the dialog is not confirmed yet, so it is a PRACK or an UPDATE - //could also be an option, but the important thing is how am i going to get - //the transaction of the invite, that is the one i have to cancel - LM_WARN("this is not my transaction so where am i?\n"); - return 1; //TODO - need to check why we got in here once before? this crashed on t_reply as t seemed invalid - } +int dlg_terminate(struct dlg_cell *dlg, struct sip_msg *msg, str *reason, + int side, str *extra_hdrs) +{ + + struct cell *t; + str default_reason = {"call failed", 11}; + int cfg_cmd = 0; + str default_extra_headers = {0, 0}; + + if(!dlg) { + LM_ERR("calling end_dialog with NULL pointer dlg\n"); + return -1; + } + + if(!extra_hdrs) + extra_hdrs = &default_extra_headers; - //TODO: here we are assuming none of the CALLEE's have sent a 200, in - //which case we would have to send an ACK, BYE - //so right now - we are sending 488 to caller and CANCEL's to all CALLEEs - - LM_DBG("tearing down dialog in EARLY state - no clients responded > 199\n"); - if (cfg_cmd) { - d_tmb.t_reply(msg,488,reason->s); - d_tmb.t_release(msg); - } else { - d_tmb.t_reply(t->uas.request,488,reason->s); - d_tmb.t_release(t->uas.request); - } - } - } else { - LM_WARN("can't terminate early dialog without a transaction\n"); - return -1; - } - } else { - LM_DBG("terminating confirmed dialog\n"); - if (side == DLG_CALLER_LEG /* 0 */ || side == DLG_CALLEE_LEG /* 1 */) { - if (dlg_bye(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL, side) < 0) - return -1; - - } else { - if (dlg_bye_all(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL) < 0) - return -1; - } - } - return 1; + + if(msg) { + //assume called from cfg command -> dlg_terminate, as opposed to internal API or mi interface + cfg_cmd = 1; + } + + if(!reason || reason->len <= 0 || !reason->s) { + reason = &default_reason; + } + + if(dlg->state != DLG_STATE_CONFIRMED) { + if(side != 2) { + LM_ERR("can't terminate only 1 side of an early dialog\n"); + return -1; + } + if(dlg->transaction) { + LM_DBG("terminating early dialog with %d outbound forks on " + "transaction %p\n", + dlg->transaction->nr_of_outgoings, dlg->transaction); + + t = dlg->transaction; + + if(t && t != (void *)-1 && t->uas.request) { + if(t->method.len != 6 || t->method.s[0] != 'I' + || t->method.s[1] != 'N' || t->method.s[2] != 'V') { + //well this is the transaction of a subsequent request within the dialog + //and the dialog is not confirmed yet, so it is a PRACK or an UPDATE + //could also be an option, but the important thing is how am i going to get + //the transaction of the invite, that is the one i have to cancel + LM_WARN("this is not my transaction so where am i?\n"); + return 1; //TODO - need to check why we got in here once before? this crashed on t_reply as t seemed invalid + } + + //TODO: here we are assuming none of the CALLEE's have sent a 200, in + //which case we would have to send an ACK, BYE + //so right now - we are sending 488 to caller and CANCEL's to all CALLEEs + + LM_DBG("tearing down dialog in EARLY state - no clients " + "responded > 199\n"); + if(cfg_cmd) { + d_tmb.t_reply(msg, 488, reason->s); + d_tmb.t_release(msg); + } else { + d_tmb.t_reply(t->uas.request, 488, reason->s); + d_tmb.t_release(t->uas.request); + } + } + } else { + LM_WARN("can't terminate early dialog without a transaction\n"); + return -1; + } + } else { + LM_DBG("terminating confirmed dialog\n"); + if(side == DLG_CALLER_LEG /* 0 */ || side == DLG_CALLEE_LEG /* 1 */) { + if(dlg_bye(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL, side) + < 0) + return -1; + + } else { + if(dlg_bye_all(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL) < 0) + return -1; + } + } + return 1; } #ifdef MI_REMOVED /*parameters from MI: callid, from tag, to tag*/ /* TODO: add reason parameter to mi interface */ -struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param) { - - struct mi_node* node; - struct dlg_cell * dlg = NULL; - str mi_extra_hdrs = {"Reason: mi_terminated\r\n", 23}; - int status, msg_len; - char *msg; - - str callid = {NULL, 0}; - str ftag = {NULL, 0}; - str ttag = {NULL, 0}; - str reason = {"mi_terminated", 13}; - - if (d_table == NULL) - goto end; - - node = cmd_tree->node.kids; - - if (node == NULL || node->next == NULL || node->next->next == NULL) - return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); - - if (!node->value.s || !node->value.len) { - goto error; - } else { - callid = node->value; - } - node = node->next; - if (!node->value.s || !node->value.len) { - goto error; - } else { - ftag = node->value; - } - node = node->next; - if (!node->value.s || !node->value.len) { - goto error; - } else { - ttag = node->value; - } - - if (node->next) { - node = node->next; - if (node->value.len && node->value.s) - mi_extra_hdrs = node->value; - } - - unsigned int dir = DLG_DIR_NONE; - LM_DBG("Looking for callid [%.*s]\n", callid.len, callid.s); - dlg = get_dlg(&callid, &ftag, &ttag, &dir); //increments ref count! - - if (dlg) { - LM_DBG("Found dialog to terminate and it is in state [%i] [%.*s]\n", dlg->state, mi_extra_hdrs.len, mi_extra_hdrs.s); - - if (dlg_terminate(dlg, 0, &reason, /* all sides of a dialog*/ 2, &mi_extra_hdrs) < 0) { - status = 500; - msg = MI_DLG_OPERATION_ERR; - msg_len = MI_DLG_OPERATION_ERR_LEN; - } else { - status = 200; - msg = MI_OK_S; - msg_len = MI_OK_LEN; - } - unref_dlg(dlg, 1); - - return init_mi_tree(status, msg, msg_len); - } +struct mi_root *mi_terminate_dlg(struct mi_root *cmd_tree, void *param) +{ + + struct mi_node *node; + struct dlg_cell *dlg = NULL; + str mi_extra_hdrs = {"Reason: mi_terminated\r\n", 23}; + int status, msg_len; + char *msg; + + str callid = {NULL, 0}; + str ftag = {NULL, 0}; + str ttag = {NULL, 0}; + str reason = {"mi_terminated", 13}; + + if(d_table == NULL) + goto end; + + node = cmd_tree->node.kids; + + if(node == NULL || node->next == NULL || node->next->next == NULL) + return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); + + if(!node->value.s || !node->value.len) { + goto error; + } else { + callid = node->value; + } + node = node->next; + if(!node->value.s || !node->value.len) { + goto error; + } else { + ftag = node->value; + } + node = node->next; + if(!node->value.s || !node->value.len) { + goto error; + } else { + ttag = node->value; + } + + if(node->next) { + node = node->next; + if(node->value.len && node->value.s) + mi_extra_hdrs = node->value; + } + + unsigned int dir = DLG_DIR_NONE; + LM_DBG("Looking for callid [%.*s]\n", callid.len, callid.s); + dlg = get_dlg(&callid, &ftag, &ttag, &dir); //increments ref count! + + if(dlg) { + LM_DBG("Found dialog to terminate and it is in state [%i] [%.*s]\n", + dlg->state, mi_extra_hdrs.len, mi_extra_hdrs.s); + + if(dlg_terminate(dlg, 0, &reason, /* all sides of a dialog*/ 2, + &mi_extra_hdrs) + < 0) { + status = 500; + msg = MI_DLG_OPERATION_ERR; + msg_len = MI_DLG_OPERATION_ERR_LEN; + } else { + status = 200; + msg = MI_OK_S; + msg_len = MI_OK_LEN; + } + unref_dlg(dlg, 1); + + return init_mi_tree(status, msg, msg_len); + } end: - return init_mi_tree(404, MI_DIALOG_NOT_FOUND, MI_DIALOG_NOT_FOUND_LEN); + return init_mi_tree(404, MI_DIALOG_NOT_FOUND, MI_DIALOG_NOT_FOUND_LEN); error: - return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); - + return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); } #endif -int dlg_bye(struct dlg_cell *dlg, str *hdrs, int side) { - str all_hdrs = {0, 0}; - int ret; - - if (side == DLG_CALLER_LEG) { - if (dlg->dflags & DLG_FLAG_CALLERBYE) - return -1; - dlg->dflags |= DLG_FLAG_CALLERBYE; - } else { - if (dlg->dflags & DLG_FLAG_CALLEEBYE) - return -1; - dlg->dflags |= DLG_FLAG_CALLEEBYE; - } - if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { - LM_ERR("failed to build dlg headers\n"); - return -1; - } - ret = send_bye(dlg, side, &all_hdrs); - pkg_free(all_hdrs.s); - return ret; +int dlg_bye(struct dlg_cell *dlg, str *hdrs, int side) +{ + str all_hdrs = {0, 0}; + int ret; + + if(side == DLG_CALLER_LEG) { + if(dlg->dflags & DLG_FLAG_CALLERBYE) + return -1; + dlg->dflags |= DLG_FLAG_CALLERBYE; + } else { + if(dlg->dflags & DLG_FLAG_CALLEEBYE) + return -1; + dlg->dflags |= DLG_FLAG_CALLEEBYE; + } + if((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { + LM_ERR("failed to build dlg headers\n"); + return -1; + } + ret = send_bye(dlg, side, &all_hdrs); + pkg_free(all_hdrs.s); + return ret; } /* Wrapper for terminating dialog from API - from other modules */ -int w_api_terminate_dlg(str *callid, str *ftag, str *ttag, str *hdrs, str* reason) { - struct dlg_cell *dlg; +int w_api_terminate_dlg( + str *callid, str *ftag, str *ttag, str *hdrs, str *reason) +{ + struct dlg_cell *dlg; - unsigned int dir = DLG_DIR_NONE; - dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! + unsigned int dir = DLG_DIR_NONE; + dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! - if (!dlg) { - LM_ERR("Asked to tear down non existent dialog\n"); - return -1; - } + if(!dlg) { + LM_ERR("Asked to tear down non existent dialog\n"); + return -1; + } - unref_dlg(dlg, 1); - - return dlg_terminate(dlg, NULL, reason, 2, hdrs); + unref_dlg(dlg, 1); + return dlg_terminate(dlg, NULL, reason, 2, hdrs); } -int dlg_bye_all(struct dlg_cell *dlg, str *hdrs) { - str all_hdrs = {0, 0}; - int ret; - - if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { - LM_ERR("failed to build dlg headers\n"); - return -1; - } +int dlg_bye_all(struct dlg_cell *dlg, str *hdrs) +{ + str all_hdrs = {0, 0}; + int ret; - ret = send_bye(dlg, DLG_CALLER_LEG, &all_hdrs); - ret |= send_bye(dlg, DLG_CALLEE_LEG, &all_hdrs); + if((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { + LM_ERR("failed to build dlg headers\n"); + return -1; + } - pkg_free(all_hdrs.s); - return ret; + ret = send_bye(dlg, DLG_CALLER_LEG, &all_hdrs); + ret |= send_bye(dlg, DLG_CALLEE_LEG, &all_hdrs); + pkg_free(all_hdrs.s); + return ret; } /* Wrapper for terminating dialog from API - from other modules */ -int w_api_lookup_terminate_dlg(unsigned int h_entry, unsigned int h_id, str *hdrs) { - struct dlg_cell *dlg; +int w_api_lookup_terminate_dlg( + unsigned int h_entry, unsigned int h_id, str *hdrs) +{ + struct dlg_cell *dlg; - dlg = lookup_dlg(h_entry, h_id); //increments ref count! + dlg = lookup_dlg(h_entry, h_id); //increments ref count! - if (!dlg) { - LM_ERR("Asked to tear down non existent dialog\n"); - return -1; - } + if(!dlg) { + LM_ERR("Asked to tear down non existent dialog\n"); + return -1; + } - unref_dlg(dlg, 1); - - return dlg_terminate(dlg, NULL, NULL/*reason*/, 2, hdrs); + unref_dlg(dlg, 1); + return dlg_terminate(dlg, NULL, NULL /*reason*/, 2, hdrs); } - diff --git a/src/modules/ims_dialog/dlg_req_within.h b/src/modules/ims_dialog/dlg_req_within.h index 2055509f74c..f6f5b2c7e62 100644 --- a/src/modules/ims_dialog/dlg_req_within.h +++ b/src/modules/ims_dialog/dlg_req_within.h @@ -25,33 +25,34 @@ */ - - #ifndef DLG_REQUEST_WITHIN_H #define DLG_REQUEST_WITHIN_H #include "dlg_hash.h" #include "../../modules/tm/tm_load.h" -#define MAX_FWD "70" -#define MAX_SIZE 256 -#define RCV_BYE_REPLY 1 +#define MAX_FWD "70" +#define MAX_SIZE 256 +#define RCV_BYE_REPLY 1 -#define MI_DIALOG_NOT_FOUND "Requested Dialog not found" -#define MI_DIALOG_NOT_FOUND_LEN (sizeof(MI_DIALOG_NOT_FOUND)-1) -#define MI_DLG_OPERATION_ERR "Operation failed" -#define MI_DLG_OPERATION_ERR_LEN (sizeof(MI_DLG_OPERATION_ERR)-1) +#define MI_DIALOG_NOT_FOUND "Requested Dialog not found" +#define MI_DIALOG_NOT_FOUND_LEN (sizeof(MI_DIALOG_NOT_FOUND) - 1) +#define MI_DLG_OPERATION_ERR "Operation failed" +#define MI_DLG_OPERATION_ERR_LEN (sizeof(MI_DLG_OPERATION_ERR) - 1) extern struct tm_binds d_tmb; -struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ); +struct mi_root *mi_terminate_dlg(struct mi_root *cmd_tree, void *param); -dlg_t* build_dlg_t(struct dlg_cell * cell, int dir); +dlg_t *build_dlg_t(struct dlg_cell *cell, int dir); int free_tm_dlg(dlg_t *td); int dlg_bye(struct dlg_cell *dlg, str *hdrs, int side); int dlg_bye_all(struct dlg_cell *dlg, str *hdrs); -int w_api_terminate_dlg(str *call_id, str *from_tag, str *to_tag, str *hdrs, str* reason); -int w_api_lookup_terminate_dlg(unsigned int h_entry, unsigned int h_id, str *hdrs); -int dlg_terminate(struct dlg_cell *dlg, struct sip_msg* msg, str *reason, int side, str *extra_headers); +int w_api_terminate_dlg( + str *call_id, str *from_tag, str *to_tag, str *hdrs, str *reason); +int w_api_lookup_terminate_dlg( + unsigned int h_entry, unsigned int h_id, str *hdrs); +int dlg_terminate(struct dlg_cell *dlg, struct sip_msg *msg, str *reason, + int side, str *extra_headers); #endif diff --git a/src/modules/ims_dialog/dlg_timer.c b/src/modules/ims_dialog/dlg_timer.c index cf4ca3a3c78..b762908abc6 100644 --- a/src/modules/ims_dialog/dlg_timer.c +++ b/src/modules/ims_dialog/dlg_timer.c @@ -52,22 +52,22 @@ dlg_timer_handler timer_hdl = 0; */ int init_dlg_timer(dlg_timer_handler hdl) { - d_timer = (struct dlg_timer*)shm_malloc(sizeof(struct dlg_timer)); - if (d_timer==0) { + d_timer = (struct dlg_timer *)shm_malloc(sizeof(struct dlg_timer)); + if(d_timer == 0) { LM_ERR("no more shm mem\n"); return -1; } - memset( d_timer, 0, sizeof(struct dlg_timer) ); + memset(d_timer, 0, sizeof(struct dlg_timer)); d_timer->first.next = d_timer->first.prev = &(d_timer->first); d_timer->lock = lock_alloc(); - if (d_timer->lock==0) { + if(d_timer->lock == 0) { LM_ERR("failed to alloc lock\n"); goto error0; } - if (lock_init(d_timer->lock)==0) { + if(lock_init(d_timer->lock) == 0) { LM_ERR("failed to init lock\n"); goto error1; } @@ -88,7 +88,7 @@ int init_dlg_timer(dlg_timer_handler hdl) */ void destroy_dlg_timer(void) { - if (d_timer==0) + if(d_timer == 0) return; lock_destroy(d_timer->lock); @@ -106,15 +106,15 @@ void destroy_dlg_timer(void) */ static inline void insert_dialog_timer_unsafe(struct dlg_tl *tl) { - struct dlg_tl* ptr; + struct dlg_tl *ptr; /* insert in sorted order */ - for(ptr = d_timer->first.prev; ptr != &d_timer->first ; ptr = ptr->prev) { - if ( ptr->timeout <= tl->timeout ) + for(ptr = d_timer->first.prev; ptr != &d_timer->first; ptr = ptr->prev) { + if(ptr->timeout <= tl->timeout) break; } - LM_DBG("inserting %p for %d\n", tl,tl->timeout); + LM_DBG("inserting %p for %d\n", tl, tl->timeout); tl->prev = ptr; tl->next = ptr->next; tl->prev->next = tl; @@ -130,18 +130,18 @@ static inline void insert_dialog_timer_unsafe(struct dlg_tl *tl) */ int insert_dlg_timer(struct dlg_tl *tl, int interval) { - lock_get( d_timer->lock); + lock_get(d_timer->lock); - if (tl->next!=0 || tl->prev!=0) { + if(tl->next != 0 || tl->prev != 0) { LM_CRIT("Trying to insert a bogus dlg tl=%p tl->next=%p tl->prev=%p\n", - tl, tl->next, tl->prev); - lock_release( d_timer->lock); + tl, tl->next, tl->prev); + lock_release(d_timer->lock); return -1; } - tl->timeout = get_ticks()+interval; - insert_dialog_timer_unsafe( tl ); + tl->timeout = get_ticks() + interval; + insert_dialog_timer_unsafe(tl); - lock_release( d_timer->lock); + lock_release(d_timer->lock); return 0; } @@ -167,17 +167,17 @@ static inline void remove_dialog_timer_unsafe(struct dlg_tl *tl) */ int remove_dialog_timer(struct dlg_tl *tl) { - lock_get( d_timer->lock); + lock_get(d_timer->lock); - if (tl->prev==NULL && tl->timeout==0) { - lock_release( d_timer->lock); + if(tl->prev == NULL && tl->timeout == 0) { + lock_release(d_timer->lock); return 1; } - if (tl->prev==NULL || tl->next==NULL) { - LM_CRIT("bogus tl=%p tl->prev=%p tl->next=%p\n", - tl, tl->prev, tl->next); - lock_release( d_timer->lock); + if(tl->prev == NULL || tl->next == NULL) { + LM_CRIT("bogus tl=%p tl->prev=%p tl->next=%p\n", tl, tl->prev, + tl->next); + lock_release(d_timer->lock); return -1; } @@ -186,7 +186,7 @@ int remove_dialog_timer(struct dlg_tl *tl) tl->prev = NULL; tl->timeout = 0; - lock_release( d_timer->lock); + lock_release(d_timer->lock); return 0; } @@ -200,19 +200,19 @@ int remove_dialog_timer(struct dlg_tl *tl) */ int update_dlg_timer(struct dlg_tl *tl, int timeout) { - lock_get( d_timer->lock); + lock_get(d_timer->lock); - if (tl->next==0 || tl->prev==0) { + if(tl->next == 0 || tl->prev == 0) { LM_CRIT("Trying to update a bogus dlg tl=%p tl->next=%p tl->prev=%p\n", - tl, tl->next, tl->prev); - lock_release( d_timer->lock); + tl, tl->next, tl->prev); + lock_release(d_timer->lock); return -1; } - remove_dialog_timer_unsafe( tl ); - tl->timeout = get_ticks()+timeout; - insert_dialog_timer_unsafe( tl ); + remove_dialog_timer_unsafe(tl); + tl->timeout = get_ticks() + timeout; + insert_dialog_timer_unsafe(tl); - lock_release( d_timer->lock); + lock_release(d_timer->lock); return 0; } @@ -222,35 +222,36 @@ int update_dlg_timer(struct dlg_tl *tl, int timeout) * \param time time for expiration check * \return list of expired dialogs on success, 0 on failure */ -static inline struct dlg_tl* get_expired_dlgs(unsigned int time) +static inline struct dlg_tl *get_expired_dlgs(unsigned int time) { - struct dlg_tl *tl , *end, *ret; + struct dlg_tl *tl, *end, *ret; - lock_get( d_timer->lock); + lock_get(d_timer->lock); - if (d_timer->first.next==&(d_timer->first) - || d_timer->first.next->timeout > time ) { - lock_release( d_timer->lock); + if(d_timer->first.next == &(d_timer->first) + || d_timer->first.next->timeout > time) { + lock_release(d_timer->lock); return 0; } end = &d_timer->first; tl = d_timer->first.next; LM_DBG("start with tl=%p tl->prev=%p tl->next=%p (%d) at %d " - "and end with end=%p end->prev=%p end->next=%p\n", - tl,tl->prev,tl->next,tl->timeout,time, - end,end->prev,end->next); - while( tl!=end && tl->timeout <= time) { - LM_DBG("getting tl=%p tl->prev=%p tl->next=%p with %d\n", - tl,tl->prev,tl->next,tl->timeout); + "and end with end=%p end->prev=%p end->next=%p\n", + tl, tl->prev, tl->next, tl->timeout, time, end, end->prev, + end->next); + while(tl != end && tl->timeout <= time) { + LM_DBG("getting tl=%p tl->prev=%p tl->next=%p with %d\n", tl, tl->prev, + tl->next, tl->timeout); tl->prev = 0; tl->timeout = 0; - tl=tl->next; + tl = tl->next; } - LM_DBG("end with tl=%p tl->prev=%p tl->next=%p and d_timer->first.next->prev=%p\n", - tl,tl->prev,tl->next,d_timer->first.next->prev); + LM_DBG("end with tl=%p tl->prev=%p tl->next=%p and " + "d_timer->first.next->prev=%p\n", + tl, tl->prev, tl->next, d_timer->first.next->prev); - if (tl==end && d_timer->first.next->prev) { + if(tl == end && d_timer->first.next->prev) { ret = 0; } else { ret = d_timer->first.next; @@ -259,7 +260,7 @@ static inline struct dlg_tl* get_expired_dlgs(unsigned int time) tl->prev = &d_timer->first; } - lock_release( d_timer->lock); + lock_release(d_timer->lock); return ret; } @@ -271,17 +272,17 @@ static inline struct dlg_tl* get_expired_dlgs(unsigned int time) * \param ticks for expiration checks * \param attr unused */ -void dlg_timer_routine(unsigned int ticks , void * attr) +void dlg_timer_routine(unsigned int ticks, void *attr) { struct dlg_tl *tl, *ctl; - tl = get_expired_dlgs( ticks ); + tl = get_expired_dlgs(ticks); - while (tl) { + while(tl) { ctl = tl; tl = tl->next; ctl->next = NULL; LM_DBG("tl=%p next=%p\n", ctl, tl); - timer_hdl( ctl ); + timer_hdl(ctl); } } diff --git a/src/modules/ims_dialog/dlg_timer.h b/src/modules/ims_dialog/dlg_timer.h index 6f4e255868f..97b740ac100 100644 --- a/src/modules/ims_dialog/dlg_timer.h +++ b/src/modules/ims_dialog/dlg_timer.h @@ -41,17 +41,17 @@ /*! dialog timeout list */ struct dlg_tl { - struct dlg_tl *next; - struct dlg_tl *prev; - volatile unsigned int timeout; /*!< timeout in seconds */ + struct dlg_tl *next; + struct dlg_tl *prev; + volatile unsigned int timeout; /*!< timeout in seconds */ }; /*! dialog timer */ struct dlg_timer { - struct dlg_tl first; /*!< dialog timeout list */ - gen_lock_t *lock; /*!< lock for the list */ + struct dlg_tl first; /*!< dialog timeout list */ + gen_lock_t *lock; /*!< lock for the list */ }; @@ -109,6 +109,6 @@ int update_dlg_timer(struct dlg_tl *tl, int timeout); * \param ticks for expiration checks * \param attr unused */ -void dlg_timer_routine(unsigned int ticks , void * attr); +void dlg_timer_routine(unsigned int ticks, void *attr); #endif diff --git a/src/modules/ims_dialog/dlg_var.c b/src/modules/ims_dialog/dlg_var.c index e0648c6dc79..884b5562e4d 100644 --- a/src/modules/ims_dialog/dlg_var.c +++ b/src/modules/ims_dialog/dlg_var.c @@ -33,13 +33,13 @@ dlg_ctx_t _dlg_ctx; extern int spiral_detected; /*! global variable table, in case the dialog does not exist yet */ -struct dlg_var * var_table = 0; +struct dlg_var *var_table = 0; /*! ID of the current message */ int msg_id; int dlg_cfg_cb(struct sip_msg *foo, unsigned int flags, void *bar) { - if(get_route_type()==LOCAL_ROUTE) { + if(get_route_type() == LOCAL_ROUTE) { return 1; } memset(&_dlg_ctx, 0, sizeof(dlg_ctx_t)); @@ -51,8 +51,8 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val) { struct dlg_var *var; - var =(struct dlg_var*)shm_malloc(sizeof(struct dlg_var)); - if (var==NULL) { + var = (struct dlg_var *)shm_malloc(sizeof(struct dlg_var)); + if(var == NULL) { LM_ERR("no more shm mem\n"); return NULL; } @@ -60,8 +60,8 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val) var->vflags = DLG_FLAG_NEW; /* set key */ var->key.len = key->len; - var->key.s = (char*)shm_malloc(var->key.len); - if (var->key.s==NULL) { + var->key.s = (char *)shm_malloc(var->key.len); + if(var->key.s == NULL) { shm_free(var); LM_ERR("no more shm mem\n"); return NULL; @@ -69,8 +69,8 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val) memcpy(var->key.s, key->s, key->len); /* set value */ var->value.len = val->len; - var->value.s = (char*)shm_malloc(var->value.len); - if (var->value.s==NULL) { + var->value.s = (char *)shm_malloc(var->value.len); + if(var->value.s == NULL) { shm_free(var->key.s); shm_free(var); LM_ERR("no more shm mem\n"); @@ -81,9 +81,10 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val) } /*! Delete the current var-list */ -void free_local_varlist() { +void free_local_varlist() +{ struct dlg_var *var; - while (var_table) { + while(var_table) { var = var_table; var_table = var_table->next; shm_free(var->key.s); @@ -93,15 +94,17 @@ void free_local_varlist() { } /*! Retrieve the local var-list pointer */ -struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointer) { +struct dlg_var *get_local_varlist_pointer( + struct sip_msg *msg, int clear_pointer) +{ struct dlg_var *var; /* New list, delete the old one */ - if (msg->id != msg_id) { + if(msg->id != msg_id) { free_local_varlist(); msg_id = msg->id; } var = var_table; - if (clear_pointer) + if(clear_pointer) var_table = NULL; return var; } @@ -109,30 +112,32 @@ struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointe /* Adds, updates and deletes dialog variables */ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val) { - struct dlg_var * var = NULL; - struct dlg_var * it; - struct dlg_var * it_prev; - struct dlg_var ** var_list; + struct dlg_var *var = NULL; + struct dlg_var *it; + struct dlg_var *it_prev; + struct dlg_var **var_list; - if (dlg) + if(dlg) var_list = &dlg->vars; else var_list = &var_table; - if ( val && (var=new_dlg_var(key, val))==NULL) { + if(val && (var = new_dlg_var(key, val)) == NULL) { LM_ERR("failed to create new dialog variable\n"); return -1; } /* iterate the list */ - for( it_prev=NULL, it=*var_list ; it ; it_prev=it,it=it->next) { - if (key->len==it->key.len && memcmp(key->s,it->key.s,key->len)==0 - && (it->vflags & DLG_FLAG_DEL) == 0) { + for(it_prev = NULL, it = *var_list; it; it_prev = it, it = it->next) { + if(key->len == it->key.len && memcmp(key->s, it->key.s, key->len) == 0 + && (it->vflags & DLG_FLAG_DEL) == 0) { /* found -> replace or delete it */ - if (val==NULL) { + if(val == NULL) { /* delete it */ - if (it_prev) it_prev->next = it->next; - else *var_list = it->next; + if(it_prev) + it_prev->next = it->next; + else + *var_list = it->next; /* Set the delete-flag for the current var: */ it->vflags &= DLG_FLAG_DEL; } else { @@ -140,8 +145,10 @@ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val) var->next = it->next; /* Take the previous vflags: */ var->vflags = it->vflags & DLG_FLAG_CHANGED; - if (it_prev) it_prev->next = var; - else *var_list = var; + if(it_prev) + it_prev->next = var; + else + *var_list = var; } /* Free this var: */ @@ -153,8 +160,9 @@ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val) } /* not found: */ - if (!var) { - LM_DBG("dialog variable <%.*s> does not exist in variable list\n", key->len, key->s); + if(!var) { + LM_DBG("dialog variable <%.*s> does not exist in variable list\n", + key->len, key->s); return 1; } @@ -165,19 +173,19 @@ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val) return 0; } -str * get_dlg_variable_unsafe(struct dlg_cell *dlg, str *key) +str *get_dlg_variable_unsafe(struct dlg_cell *dlg, str *key) { struct dlg_var *var, *var_list; - if (dlg) + if(dlg) var_list = dlg->vars; else var_list = var_table; /* iterate the list */ - for(var=var_list ; var ; var=var->next) { - if (key->len==var->key.len && memcmp(key->s,var->key.s,key->len)==0 - && (var->vflags & DLG_FLAG_DEL) == 0) { + for(var = var_list; var; var = var->next) { + if(key->len == var->key.len && memcmp(key->s, var->key.s, key->len) == 0 + && (var->vflags & DLG_FLAG_DEL) == 0) { return &var->value; } } @@ -187,7 +195,7 @@ str * get_dlg_variable_unsafe(struct dlg_cell *dlg, str *key) int pv_parse_dialog_var_name(pv_spec_p sp, str *in) { - if(in==NULL || in->s==NULL || sp==NULL) + if(in == NULL || in->s == NULL || sp == NULL) return -1; sp->pvp.pvn.type = PV_NAME_INTSTR; @@ -198,138 +206,134 @@ int pv_parse_dialog_var_name(pv_spec_p sp, str *in) } /*! Internal debugging function: Prints the list of dialogs */ -void print_lists(struct dlg_cell *dlg) { +void print_lists(struct dlg_cell *dlg) +{ struct dlg_var *varlist; varlist = var_table; LM_DBG("Internal var-list (%p):\n", varlist); - while (varlist) { - LM_DBG("%.*s=%.*s (flags %i)\n", - varlist->key.len, varlist->key.s, - varlist->value.len, varlist->value.s, - varlist->vflags); + while(varlist) { + LM_DBG("%.*s=%.*s (flags %i)\n", varlist->key.len, varlist->key.s, + varlist->value.len, varlist->value.s, varlist->vflags); varlist = varlist->next; } - if (dlg) { + if(dlg) { varlist = dlg->vars; LM_DBG("Dialog var-list (%p):\n", varlist); - while (varlist) { - LM_DBG("%.*s=%.*s (flags %i)\n", - varlist->key.len, varlist->key.s, - varlist->value.len, varlist->value.s, - varlist->vflags); + while(varlist) { + LM_DBG("%.*s=%.*s (flags %i)\n", varlist->key.len, varlist->key.s, + varlist->value.len, varlist->value.s, varlist->vflags); varlist = varlist->next; } } } -str * api_get_dlg_variable(str *callid, str *ftag, str *ttag, str *key) { - struct dlg_cell *dlg; +str *api_get_dlg_variable(str *callid, str *ftag, str *ttag, str *key) +{ + struct dlg_cell *dlg; - unsigned int dir = DLG_DIR_NONE; - dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! + unsigned int dir = DLG_DIR_NONE; + dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! - if (!dlg) { - LM_ERR("Asked to tear down non existent dialog\n"); - return NULL; - } + if(!dlg) { + LM_ERR("Asked to tear down non existent dialog\n"); + return NULL; + } - unref_dlg(dlg, 1); + unref_dlg(dlg, 1); - return get_dlg_variable(dlg, key); + return get_dlg_variable(dlg, key); } -str * get_dlg_variable(struct dlg_cell *dlg, str *key) +str *get_dlg_variable(struct dlg_cell *dlg, str *key) { - str* var = NULL; + str *var = NULL; - if( !dlg || !key || key->len > strlen(key->s)) - { - LM_ERR("BUG - bad parameters\n"); + if(!dlg || !key || key->len > strlen(key->s)) { + LM_ERR("BUG - bad parameters\n"); - return NULL; - } + return NULL; + } - dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); - var = get_dlg_variable_unsafe( dlg, key); - dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); + var = get_dlg_variable_unsafe(dlg, key); + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); - return var; + return var; } -int api_set_dlg_variable(str *callid, str *ftag, str *ttag, str *key, str *val) { - struct dlg_cell *dlg; - - unsigned int dir = DLG_DIR_NONE; - dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! - - if (!dlg) { - LM_ERR("Asked to tear down non existent dialog\n"); - return -1; - } +int api_set_dlg_variable(str *callid, str *ftag, str *ttag, str *key, str *val) +{ + struct dlg_cell *dlg; - unref_dlg(dlg, 1); + unsigned int dir = DLG_DIR_NONE; + dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! - return set_dlg_variable(dlg, key, val); + if(!dlg) { + LM_ERR("Asked to tear down non existent dialog\n"); + return -1; + } + unref_dlg(dlg, 1); + return set_dlg_variable(dlg, key, val); } int set_dlg_variable(struct dlg_cell *dlg, str *key, str *val) { - if( !dlg || !key || key->len > strlen(key->s) || (val && val->len > strlen(val->s))) - { - LM_ERR("BUG - bad parameters\n"); - return -1; - } + if(!dlg || !key || key->len > strlen(key->s) + || (val && val->len > strlen(val->s))) { + LM_ERR("BUG - bad parameters\n"); + return -1; + } - dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); + dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); - if( !val) - { - if (set_dlg_variable_unsafe(dlg, key, NULL)!=0) { - LM_ERR("failed to delete dialog variable <%.*s>\n", key->len,key->s); - goto error; - } - } else { - if (set_dlg_variable_unsafe(dlg, key, val)!=0) { - LM_ERR("failed to store dialog values <%.*s>\n",key->len,key->s); - goto error; - } - } + if(!val) { + if(set_dlg_variable_unsafe(dlg, key, NULL) != 0) { + LM_ERR("failed to delete dialog variable <%.*s>\n", key->len, + key->s); + goto error; + } + } else { + if(set_dlg_variable_unsafe(dlg, key, val) != 0) { + LM_ERR("failed to store dialog values <%.*s>\n", key->len, key->s); + goto error; + } + } - dlg->dflags &= DLG_FLAG_CHANGED_VARS; - dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + dlg->dflags &= DLG_FLAG_CHANGED_VARS; + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); - if ( dlg_db_mode==DB_MODE_REALTIME ) - update_dialog_dbinfo(dlg); + if(dlg_db_mode == DB_MODE_REALTIME) + update_dialog_dbinfo(dlg); - print_lists(dlg); + print_lists(dlg); - return 0; + return 0; error: - dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); - return -1; + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + return -1; } int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { dlg_cell_t *dlg; - str * value; + str *value; str spv; - if (param==NULL || param->pvn.type!=PV_NAME_INTSTR - || param->pvn.u.isname.type!=AVP_NAME_STR - || param->pvn.u.isname.name.s.s==NULL) { + if(param == NULL || param->pvn.type != PV_NAME_INTSTR + || param->pvn.u.isname.type != AVP_NAME_STR + || param->pvn.u.isname.name.s.s == NULL) { LM_CRIT("BUG - bad parameters\n"); return -1; } /* Retrieve the dialog for current message */ - dlg=dlg_get_msg_dialog( msg); + dlg = dlg_get_msg_dialog(msg); - if (dlg) { + if(dlg) { /* Lock the dialog */ dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); } else { @@ -343,8 +347,9 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) spv.s = NULL; if(value) { spv.len = pv_get_buffer_size(); - if(spv.lenlen+1) { - LM_ERR("pv buffer too small (%d) - needed %d\n", spv.len, value->len); + if(spv.len < value->len + 1) { + LM_ERR("pv buffer too small (%d) - needed %d\n", spv.len, + value->len); } else { spv.s = pv_get_buffer(); strncpy(spv.s, value->s, value->len); @@ -356,34 +361,35 @@ int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) print_lists(dlg); /* unlock dialog */ - if (dlg) { + if(dlg) { dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); dlg_release(dlg); } - if (spv.s) + if(spv.s) return pv_get_strval(msg, param, res, &spv); return pv_get_null(msg, param, res); } -int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) +int pv_set_dlg_variable( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) { dlg_cell_t *dlg = NULL; int ret = -1; - if (param==NULL || param->pvn.type!=PV_NAME_INTSTR - || param->pvn.u.isname.type!=AVP_NAME_STR - || param->pvn.u.isname.name.s.s==NULL ) { + if(param == NULL || param->pvn.type != PV_NAME_INTSTR + || param->pvn.u.isname.type != AVP_NAME_STR + || param->pvn.u.isname.name.s.s == NULL) { LM_CRIT("BUG - bad parameters\n"); goto error; } /* Retrieve the dialog for current message */ - dlg=dlg_get_msg_dialog( msg); + dlg = dlg_get_msg_dialog(msg); - if (dlg) { + if(dlg) { /* Lock the dialog */ dlg_lock(d_table, &(d_table->entries[dlg->h_entry])); } else { @@ -391,12 +397,12 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value get_local_varlist_pointer(msg, 0); } - if (val==NULL || val->flags&(PV_VAL_NONE|PV_VAL_NULL|PV_VAL_EMPTY)) { + if(val == NULL || val->flags & (PV_VAL_NONE | PV_VAL_NULL | PV_VAL_EMPTY)) { /* if NULL, remove the value */ ret = set_dlg_variable_unsafe(dlg, ¶m->pvn.u.isname.name.s, NULL); - if(ret!= 0) { + if(ret != 0) { /* unlock dialog */ - if (dlg) { + if(dlg) { dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); dlg_release(dlg); } @@ -404,27 +410,29 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value } } else { /* if value, must be string */ - if ( !(val->flags&PV_VAL_STR)) { + if(!(val->flags & PV_VAL_STR)) { LM_ERR("non-string values are not supported\n"); /* unlock dialog */ - if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + if(dlg) + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); goto error; } - ret = set_dlg_variable_unsafe(dlg, ¶m->pvn.u.isname.name.s, &val->rs); - if(ret!= 0) { + ret = set_dlg_variable_unsafe( + dlg, ¶m->pvn.u.isname.name.s, &val->rs); + if(ret != 0) { /* unlock dialog */ - if (dlg) dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); + if(dlg) + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); goto error; } } /* unlock dialog */ - if (dlg) { + if(dlg) { dlg->dflags |= DLG_FLAG_CHANGED_VARS; dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); - if ( dlg_db_mode==DB_MODE_REALTIME ) + if(dlg_db_mode == DB_MODE_REALTIME) update_dialog_dbinfo(dlg); - } print_lists(dlg); @@ -435,126 +443,128 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value return -1; } -int pv_get_dlg_ctx(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res) +int pv_get_dlg_ctx(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - if(param==NULL) + if(param == NULL) return -1; - switch(param->pvn.u.isname.name.n) - { + switch(param->pvn.u.isname.name.n) { case 1: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.flags); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.flags); case 2: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.timeout); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.timeout); case 3: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.to_bye); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.to_bye); case 4: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.to_route); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.to_route); case 5: - _dlg_ctx.set = (_dlg_ctx.dlg==NULL)?0:1; - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.set); + _dlg_ctx.set = (_dlg_ctx.dlg == NULL) ? 0 : 1; + return pv_get_uintval(msg, param, res, (unsigned int)_dlg_ctx.set); case 6: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.dir); + return pv_get_uintval(msg, param, res, (unsigned int)_dlg_ctx.dir); default: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.on); + return pv_get_uintval(msg, param, res, (unsigned int)_dlg_ctx.on); } return 0; } -int pv_set_dlg_ctx(struct sip_msg* msg, pv_param_t *param, - int op, pv_value_t *val) +int pv_set_dlg_ctx( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val) { int n; char *rtp; - if(param==NULL) + if(param == NULL) return -1; - if(val==NULL) + if(val == NULL) n = 0; else n = val->ri; - switch(param->pvn.u.isname.name.n) - { + switch(param->pvn.u.isname.name.n) { case 1: _dlg_ctx.flags = n; - break; + break; case 2: _dlg_ctx.timeout = n; - break; + break; case 3: _dlg_ctx.to_bye = n; - break; + break; case 4: - if(val->flags&PV_VAL_STR) { - if(val->rs.s[val->rs.len]=='\0' - && val->rs.lenflags & PV_VAL_STR) { + if(val->rs.s[val->rs.len] == '\0' + && val->rs.len < DLG_TOROUTE_SIZE) { _dlg_ctx.to_route = route_lookup(&main_rt, val->rs.s); strcpy(_dlg_ctx.to_route_name, val->rs.s); - } else _dlg_ctx.to_route = 0; + } else + _dlg_ctx.to_route = 0; } else { - if(n!=0) { + if(n != 0) { rtp = int2str(n, NULL); _dlg_ctx.to_route = route_lookup(&main_rt, rtp); strcpy(_dlg_ctx.to_route_name, rtp); - } else _dlg_ctx.to_route = 0; + } else + _dlg_ctx.to_route = 0; } - if(_dlg_ctx.to_route <0) _dlg_ctx.to_route = 0; - break; + if(_dlg_ctx.to_route < 0) + _dlg_ctx.to_route = 0; + break; default: _dlg_ctx.on = n; - break; + break; } return 0; } int pv_parse_dlg_ctx_name(pv_spec_p sp, str *in) { - if(sp==NULL || in==NULL || in->len<=0) + if(sp == NULL || in == NULL || in->len <= 0) return -1; - switch(in->len) - { + switch(in->len) { case 2: - if(strncmp(in->s, "on", 2)==0) + if(strncmp(in->s, "on", 2) == 0) sp->pvp.pvn.u.isname.name.n = 0; - else goto error; - break; + else + goto error; + break; case 3: - if(strncmp(in->s, "set", 3)==0) + if(strncmp(in->s, "set", 3) == 0) sp->pvp.pvn.u.isname.name.n = 5; - else if(strncmp(in->s, "dir", 3)==0) + else if(strncmp(in->s, "dir", 3) == 0) sp->pvp.pvn.u.isname.name.n = 6; - else goto error; - break; + else + goto error; + break; case 5: - if(strncmp(in->s, "flags", 6)==0) + if(strncmp(in->s, "flags", 6) == 0) sp->pvp.pvn.u.isname.name.n = 1; - else goto error; - break; + else + goto error; + break; case 7: - if(strncmp(in->s, "timeout", 7)==0) + if(strncmp(in->s, "timeout", 7) == 0) sp->pvp.pvn.u.isname.name.n = 2; - else goto error; - break; + else + goto error; + break; case 11: - if(strncmp(in->s, "timeout_bye", 11)==0) + if(strncmp(in->s, "timeout_bye", 11) == 0) sp->pvp.pvn.u.isname.name.n = 3; - else goto error; - break; + else + goto error; + break; case 13: - if(strncmp(in->s, "timeout_route", 13)==0) + if(strncmp(in->s, "timeout_route", 13) == 0) sp->pvp.pvn.u.isname.name.n = 4; - else goto error; - break; + else + goto error; + break; default: goto error; } @@ -568,22 +578,20 @@ int pv_parse_dlg_ctx_name(pv_spec_p sp, str *in) return -1; } -int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res) +int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - if(param==NULL) + if(param == NULL) return -1; if(_dlg_ctx.dlg == NULL) return pv_get_null(msg, param, res); - switch(param->pvn.u.isname.name.n) - { + switch(param->pvn.u.isname.name.n) { case 1: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.dlg->h_id); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.dlg->h_id); case 2: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.dlg->state); -/* + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.dlg->state); + /* case 3: if(_dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].s==NULL || _dlg_ctx.dlg->route_set[DLG_CALLEE_LEG].len<=0) @@ -680,96 +688,106 @@ int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, (unsigned int)_dlg_ctx.dlg->h_entry); */ default: - return pv_get_uintval(msg, param, res, - (unsigned int)_dlg_ctx.dlg->ref); + return pv_get_uintval( + msg, param, res, (unsigned int)_dlg_ctx.dlg->ref); } return 0; } int pv_parse_dlg_name(pv_spec_p sp, str *in) { - if(sp==NULL || in==NULL || in->len<=0) + if(sp == NULL || in == NULL || in->len <= 0) return -1; - switch(in->len) - { + switch(in->len) { case 3: - if(strncmp(in->s, "ref", 3)==0) + if(strncmp(in->s, "ref", 3) == 0) sp->pvp.pvn.u.isname.name.n = 0; - else goto error; - break; + else + goto error; + break; case 4: - if(strncmp(in->s, "h_id", 4)==0) + if(strncmp(in->s, "h_id", 4) == 0) sp->pvp.pvn.u.isname.name.n = 1; - else goto error; - break; + else + goto error; + break; case 5: - if(strncmp(in->s, "state", 5)==0) + if(strncmp(in->s, "state", 5) == 0) sp->pvp.pvn.u.isname.name.n = 2; - else if(strncmp(in->s, "to_rs", 5)==0) + else if(strncmp(in->s, "to_rs", 5) == 0) sp->pvp.pvn.u.isname.name.n = 3; - else goto error; - break; + else + goto error; + break; case 6: - if(strncmp(in->s, "dflags", 6)==0) + if(strncmp(in->s, "dflags", 6) == 0) sp->pvp.pvn.u.isname.name.n = 4; - else if(strncmp(in->s, "sflags", 6)==0) + else if(strncmp(in->s, "sflags", 6) == 0) sp->pvp.pvn.u.isname.name.n = 5; - else if(strncmp(in->s, "callid", 6)==0) + else if(strncmp(in->s, "callid", 6) == 0) sp->pvp.pvn.u.isname.name.n = 6; - else if(strncmp(in->s, "to_uri", 6)==0) + else if(strncmp(in->s, "to_uri", 6) == 0) sp->pvp.pvn.u.isname.name.n = 7; - else if(strncmp(in->s, "to_tag", 6)==0) + else if(strncmp(in->s, "to_tag", 6) == 0) sp->pvp.pvn.u.isname.name.n = 8; - else goto error; - break; + else + goto error; + break; case 7: - if(strncmp(in->s, "toroute", 7)==0) + if(strncmp(in->s, "toroute", 7) == 0) sp->pvp.pvn.u.isname.name.n = 9; - else if(strncmp(in->s, "to_cseq", 7)==0) + else if(strncmp(in->s, "to_cseq", 7) == 0) sp->pvp.pvn.u.isname.name.n = 10; - else if(strncmp(in->s, "from_rs", 7)==0) + else if(strncmp(in->s, "from_rs", 7) == 0) sp->pvp.pvn.u.isname.name.n = 11; - else if(strncmp(in->s, "h_entry", 7)==0) + else if(strncmp(in->s, "h_entry", 7) == 0) sp->pvp.pvn.u.isname.name.n = 21; - else goto error; - break; + else + goto error; + break; case 8: - if(strncmp(in->s, "from_uri", 8)==0) + if(strncmp(in->s, "from_uri", 8) == 0) sp->pvp.pvn.u.isname.name.n = 12; - else if(strncmp(in->s, "from_tag", 8)==0) + else if(strncmp(in->s, "from_tag", 8) == 0) sp->pvp.pvn.u.isname.name.n = 13; - else if(strncmp(in->s, "lifetime", 8)==0) + else if(strncmp(in->s, "lifetime", 8) == 0) sp->pvp.pvn.u.isname.name.n = 14; - else if(strncmp(in->s, "start_ts", 8)==0) + else if(strncmp(in->s, "start_ts", 8) == 0) sp->pvp.pvn.u.isname.name.n = 15; - else goto error; - break; + else + goto error; + break; case 9: - if(strncmp(in->s, "from_cseq", 9)==0) + if(strncmp(in->s, "from_cseq", 9) == 0) sp->pvp.pvn.u.isname.name.n = 16; - else goto error; - break; + else + goto error; + break; case 10: - if(strncmp(in->s, "to_contact", 10)==0) + if(strncmp(in->s, "to_contact", 10) == 0) sp->pvp.pvn.u.isname.name.n = 17; - else goto error; - break; + else + goto error; + break; case 11: - if(strncmp(in->s, "to_bindaddr", 11)==0) + if(strncmp(in->s, "to_bindaddr", 11) == 0) sp->pvp.pvn.u.isname.name.n = 18; - else goto error; - break; + else + goto error; + break; case 12: - if(strncmp(in->s, "from_contact", 12)==0) + if(strncmp(in->s, "from_contact", 12) == 0) sp->pvp.pvn.u.isname.name.n = 19; - else goto error; - break; + else + goto error; + break; case 13: - if(strncmp(in->s, "from_bindaddr", 20)==0) + if(strncmp(in->s, "from_bindaddr", 20) == 0) sp->pvp.pvn.u.isname.name.n = 2; - else goto error; - break; + else + goto error; + break; default: goto error; } @@ -795,12 +813,12 @@ void dlg_reset_ctx_iuid(void) _dlg_ctx.iuid.h_id = 0; } -dlg_cell_t* dlg_get_ctx_dialog(void) +dlg_cell_t *dlg_get_ctx_dialog(void) { return dlg_get_by_iuid(&_dlg_ctx.iuid); } -dlg_ctx_t* dlg_get_dlg_ctx(void) +dlg_ctx_t *dlg_get_dlg_ctx(void) { return &_dlg_ctx; } diff --git a/src/modules/ims_dialog/dlg_var.h b/src/modules/ims_dialog/dlg_var.h index 706028dd206..39fb46935e5 100644 --- a/src/modules/ims_dialog/dlg_var.h +++ b/src/modules/ims_dialog/dlg_var.h @@ -25,70 +25,73 @@ #include "../../core/pvar.h" #include "dlg_hash.h" -#define DLG_TOROUTE_SIZE 32 +#define DLG_TOROUTE_SIZE 32 /*! dialog context */ -typedef struct _dlg_ctx { - int on; - unsigned int flags; - unsigned int iflags; - int to_route; - char to_route_name[DLG_TOROUTE_SIZE]; - int to_bye; - int timeout; - struct dlg_cell *dlg; - dlg_iuid_t iuid; - int cpid; - int set; - unsigned int dir; - int t; /* set to 1 if tm req in callback executed */ - int expect_t; /* set to 1 if expects that t is set after config */ +typedef struct _dlg_ctx +{ + int on; + unsigned int flags; + unsigned int iflags; + int to_route; + char to_route_name[DLG_TOROUTE_SIZE]; + int to_bye; + int timeout; + struct dlg_cell *dlg; + dlg_iuid_t iuid; + int cpid; + int set; + unsigned int dir; + int t; /* set to 1 if tm req in callback executed */ + int expect_t; /* set to 1 if expects that t is set after config */ } dlg_ctx_t; /* A dialog-variable */ -struct dlg_var { - str key; - str value; - unsigned int vflags; /*!< internal variable flags */ - struct dlg_var *next; +struct dlg_var +{ + str key; + str value; + unsigned int vflags; /*!< internal variable flags */ + struct dlg_var *next; }; -str * api_get_dlg_variable(str *callid, str *ftag, str *ttag, str *key); -str * get_dlg_variable(struct dlg_cell *dlg, str *key); +str *api_get_dlg_variable(str *callid, str *ftag, str *ttag, str *key); +str *get_dlg_variable(struct dlg_cell *dlg, str *key); int api_set_dlg_variable(str *callid, str *ftag, str *ttag, str *key, str *val); int set_dlg_variable(struct dlg_cell *dlg, str *key, str *val); int pv_parse_dialog_var_name(pv_spec_p sp, str *in); -int pv_get_dlg_variable(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +int pv_get_dlg_variable( + struct sip_msg *msg, pv_param_t *param, pv_value_t *res); -int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val); +int pv_set_dlg_variable( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); /*! Retrieve the current var-list */ -struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointer); +struct dlg_var *get_local_varlist_pointer( + struct sip_msg *msg, int clear_pointer); /* Adds, updates and deletes dialog variables */ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val); extern dlg_ctx_t _dlg_ctx; -int pv_get_dlg_ctx(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); -int pv_set_dlg_ctx(struct sip_msg* msg, pv_param_t *param, - int op, pv_value_t *val); +int pv_get_dlg_ctx(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); +int pv_set_dlg_ctx( + struct sip_msg *msg, pv_param_t *param, int op, pv_value_t *val); int pv_parse_dlg_ctx_name(pv_spec_p sp, str *in); -int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); +int pv_get_dlg(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); int pv_parse_dlg_name(pv_spec_p sp, str *in); int dlg_cfg_cb(struct sip_msg *foo, unsigned int flags, void *bar); void dlg_set_ctx_iuid(dlg_cell_t *dlg); void dlg_reset_ctx_iuid(void); -dlg_cell_t* dlg_get_ctx_dialog(void); +dlg_cell_t *dlg_get_ctx_dialog(void); -dlg_ctx_t* dlg_get_dlg_ctx(void); +dlg_ctx_t *dlg_get_dlg_ctx(void); int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar); diff --git a/src/modules/ims_dialog/ims_dialog.c b/src/modules/ims_dialog/ims_dialog.c index 5da9d058e31..439fb6c3ebb 100644 --- a/src/modules/ims_dialog/ims_dialog.c +++ b/src/modules/ims_dialog/ims_dialog.c @@ -4,7 +4,6 @@ #include - #include "../../core/sr_module.h" #include "../../lib/srdb1/db.h" #include "../../core/dprint.h" @@ -43,21 +42,21 @@ static void mod_destroy(void); /* module parameter */ static int dlg_hash_size = 4096; -static char* rr_param = "did"; +static char *rr_param = "did"; static int dlg_flag = -1; static str timeout_spec = {NULL, 0}; static int default_timeout = 60 * 60 * 12; /* 12 hours */ static int seq_match_mode = SEQ_MATCH_STRICT_ID; -static char* profiles_wv_s = NULL; -static char* profiles_nv_s = NULL; +static char *profiles_wv_s = NULL; +static char *profiles_nv_s = NULL; int detect_spirals = 1; str dlg_extra_hdrs = {NULL, 0}; str dlg_bridge_controller = str_init("sip:controller@kamailio.org"); str ruri_pvar_param = str_init("$ru"); -pv_elem_t * ruri_param_model = NULL; +pv_elem_t *ruri_param_model = NULL; struct tm_binds d_tmb; struct rr_binds d_rrb; @@ -70,214 +69,217 @@ static str db_url = str_init(DEFAULT_DB_URL); static unsigned int db_update_period = DB_DEFAULT_UPDATE_PERIOD; /* commands wrappers and fixups */ -static int fixup_profile(void** param, int param_no); -static int fixup_get_profile2(void** param, int param_no); -static int fixup_get_profile3(void** param, int param_no); -static int fixup_dlg_bridge(void** param, int param_no); -static int fixup_dlg_terminate(void** param, int param_no); -static int w_set_dlg_profile(struct sip_msg*, char*, char*); -static int w_unset_dlg_profile(struct sip_msg*, char*, char*); -static int w_is_in_profile(struct sip_msg*, char*, char*); -static int w_get_profile_size2(struct sip_msg*, char*, char*); -static int w_get_profile_size3(struct sip_msg*, char*, char*, char*); +static int fixup_profile(void **param, int param_no); +static int fixup_get_profile2(void **param, int param_no); +static int fixup_get_profile3(void **param, int param_no); +static int fixup_dlg_bridge(void **param, int param_no); +static int fixup_dlg_terminate(void **param, int param_no); +static int w_set_dlg_profile(struct sip_msg *, char *, char *); +static int w_unset_dlg_profile(struct sip_msg *, char *, char *); +static int w_is_in_profile(struct sip_msg *, char *, char *); +static int w_get_profile_size2(struct sip_msg *, char *, char *); +static int w_get_profile_size3(struct sip_msg *, char *, char *, char *); static int w_dlg_isflagset(struct sip_msg *msg, char *flag, str *s2); static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2); static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2); -static int w_dlg_terminate(struct sip_msg*, char*, char*); -static int w_dlg_get(struct sip_msg*, char*, char*, char*); +static int w_dlg_terminate(struct sip_msg *, char *, char *); +static int w_dlg_get(struct sip_msg *, char *, char *, char *); static int w_is_known_dlg(struct sip_msg *); -static int pv_get_dlg_count( struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); +static int pv_get_dlg_count( + struct sip_msg *msg, pv_param_t *param, pv_value_t *res); static cmd_export_t cmds[] = { - {"set_dlg_profile", (cmd_function) w_set_dlg_profile, 1, fixup_profile, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"set_dlg_profile", (cmd_function) w_set_dlg_profile, 2, fixup_profile, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"unset_dlg_profile", (cmd_function) w_unset_dlg_profile, 1, fixup_profile, - 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"unset_dlg_profile", (cmd_function) w_unset_dlg_profile, 2, fixup_profile, - 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"is_in_profile", (cmd_function) w_is_in_profile, 1, fixup_profile, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"is_in_profile", (cmd_function) w_is_in_profile, 2, fixup_profile, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"get_profile_size", (cmd_function) w_get_profile_size2, 2, fixup_get_profile2, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"get_profile_size", (cmd_function) w_get_profile_size3, 3, fixup_get_profile3, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_setflag", (cmd_function) w_dlg_setflag, 1, fixup_igp_null, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_resetflag", (cmd_function) w_dlg_resetflag, 1, fixup_igp_null, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_isflagset", (cmd_function) w_dlg_isflagset, 1, fixup_igp_null, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_terminate", (cmd_function) w_dlg_terminate, 1, fixup_dlg_terminate, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_terminate", (cmd_function) w_dlg_terminate, 2, fixup_dlg_terminate, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"dlg_get", (cmd_function)w_dlg_get, 3, fixup_dlg_bridge, 0, ANY_ROUTE }, - {"is_known_dlg", (cmd_function) w_is_known_dlg, 0, NULL, - 0, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, - {"load_ims_dlg", (cmd_function)load_ims_dlg, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0} -}; - -static param_export_t mod_params[] = { - { "hash_size", INT_PARAM, &dlg_hash_size}, - { "rr_param", PARAM_STRING, &rr_param}, - { "dlg_flag", INT_PARAM, &dlg_flag}, - { "timeout_avp", PARAM_STR, &timeout_spec}, - { "default_timeout", INT_PARAM, &default_timeout}, - { "dlg_extra_hdrs", PARAM_STR, &dlg_extra_hdrs}, - //In this new dialog module we always match using DID - { "dlg_match_mode", INT_PARAM, &seq_match_mode}, - - { "db_url", PARAM_STR, &db_url }, - { "db_mode", INT_PARAM, &dlg_db_mode_param }, - { "db_update_period", INT_PARAM, &db_update_period }, - { "db_fetch_rows", INT_PARAM, &db_fetch_rows } - , - { "detect_spirals", INT_PARAM, &detect_spirals }, - { "profiles_with_value",PARAM_STRING, &profiles_wv_s }, - { "profiles_no_value", PARAM_STRING, &profiles_nv_s }, - { "bridge_controller", PARAM_STR, &dlg_bridge_controller }, - { "ruri_pvar", PARAM_STR, &ruri_pvar_param }, - - { 0, 0, 0} -}; + {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 1, fixup_profile, + 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"set_dlg_profile", (cmd_function)w_set_dlg_profile, 2, fixup_profile, + 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 1, + fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"unset_dlg_profile", (cmd_function)w_unset_dlg_profile, 2, + fixup_profile, 0, FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"is_in_profile", (cmd_function)w_is_in_profile, 1, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"is_in_profile", (cmd_function)w_is_in_profile, 2, fixup_profile, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"get_profile_size", (cmd_function)w_get_profile_size2, 2, + fixup_get_profile2, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"get_profile_size", (cmd_function)w_get_profile_size3, 3, + fixup_get_profile3, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_setflag", (cmd_function)w_dlg_setflag, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_resetflag", (cmd_function)w_dlg_resetflag, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_isflagset", (cmd_function)w_dlg_isflagset, 1, fixup_igp_null, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_terminate", (cmd_function)w_dlg_terminate, 1, fixup_dlg_terminate, + 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_terminate", (cmd_function)w_dlg_terminate, 2, fixup_dlg_terminate, + 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"dlg_get", (cmd_function)w_dlg_get, 3, fixup_dlg_bridge, 0, ANY_ROUTE}, + {"is_known_dlg", (cmd_function)w_is_known_dlg, 0, NULL, 0, + REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE}, + {"load_ims_dlg", (cmd_function)load_ims_dlg, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0}}; + +static param_export_t mod_params[] = {{"hash_size", INT_PARAM, &dlg_hash_size}, + {"rr_param", PARAM_STRING, &rr_param}, + {"dlg_flag", INT_PARAM, &dlg_flag}, + {"timeout_avp", PARAM_STR, &timeout_spec}, + {"default_timeout", INT_PARAM, &default_timeout}, + {"dlg_extra_hdrs", PARAM_STR, &dlg_extra_hdrs}, + //In this new dialog module we always match using DID + {"dlg_match_mode", INT_PARAM, &seq_match_mode}, + + {"db_url", PARAM_STR, &db_url}, + {"db_mode", INT_PARAM, &dlg_db_mode_param}, + {"db_update_period", INT_PARAM, &db_update_period}, + {"db_fetch_rows", INT_PARAM, &db_fetch_rows}, + {"detect_spirals", INT_PARAM, &detect_spirals}, + {"profiles_with_value", PARAM_STRING, &profiles_wv_s}, + {"profiles_no_value", PARAM_STRING, &profiles_nv_s}, + {"bridge_controller", PARAM_STR, &dlg_bridge_controller}, + {"ruri_pvar", PARAM_STR, &ruri_pvar_param}, + + {0, 0, 0}}; #ifdef MI_REMOVED static mi_export_t mi_cmds[] = { - { "dlg_list", mi_print_dlgs, 0, 0, 0}, - { "dlg_terminate_dlg", mi_terminate_dlg, 0, 0, 0}, - { 0, 0, 0, 0, 0} - /* TODO: restore old dialog functionality later - also expose dialog_out cmds, possibly*/ + {"dlg_list", mi_print_dlgs, 0, 0, 0}, + {"dlg_terminate_dlg", mi_terminate_dlg, 0, 0, 0}, {0, 0, 0, 0, 0} + /* TODO: restore old dialog functionality later - also expose dialog_out cmds, possibly*/ }; #endif static rpc_export_t rpc_methods[]; static pv_export_t mod_items[] = { - { {"DLG_count", sizeof("DLG_count")-1}, PVT_OTHER, pv_get_dlg_count, 0, - 0, 0, 0, 0 }, - { {"DLG_lifetime",sizeof("DLG_lifetime")-1}, PVT_OTHER, pv_get_dlg_lifetime, 0, - 0, 0, 0, 0 }, - { {"DLG_status", sizeof("DLG_status")-1}, PVT_OTHER, pv_get_dlg_status, 0, - 0, 0, 0, 0 }, - { {"dlg_ctx", sizeof("dlg_ctx")-1}, PVT_OTHER, pv_get_dlg_ctx, - pv_set_dlg_ctx, pv_parse_dlg_ctx_name, 0, 0, 0 }, - { {"dlg", sizeof("dlg")-1}, PVT_OTHER, pv_get_dlg, - 0, pv_parse_dlg_name, 0, 0, 0 }, - { {"dlg_var", sizeof("dlg_var")-1}, PVT_OTHER, pv_get_dlg_variable, - pv_set_dlg_variable, pv_parse_dialog_var_name, 0, 0, 0}, - { {0, 0}, 0, 0, 0, 0, 0, 0, 0 } -}; - -struct module_exports exports = { - "ims_dialog", /* module's name */ - DEFAULT_DLFLAGS, /* dlopen flags */ - cmds, /* exported functions */ - mod_params, /* param exports */ - 0, /* exported RPC methods */ - mod_items, /* exported pseudo-variables */ - 0, /* reply processing function */ - mod_init, /* module initialization function */ - child_init, /* per-child init function */ - mod_destroy -}; + {{"DLG_count", sizeof("DLG_count") - 1}, PVT_OTHER, pv_get_dlg_count, 0, + 0, 0, 0, 0}, + {{"DLG_lifetime", sizeof("DLG_lifetime") - 1}, PVT_OTHER, + pv_get_dlg_lifetime, 0, 0, 0, 0, 0}, + {{"DLG_status", sizeof("DLG_status") - 1}, PVT_OTHER, pv_get_dlg_status, + 0, 0, 0, 0, 0}, + {{"dlg_ctx", sizeof("dlg_ctx") - 1}, PVT_OTHER, pv_get_dlg_ctx, + pv_set_dlg_ctx, pv_parse_dlg_ctx_name, 0, 0, 0}, + {{"dlg", sizeof("dlg") - 1}, PVT_OTHER, pv_get_dlg, 0, + pv_parse_dlg_name, 0, 0, 0}, + {{"dlg_var", sizeof("dlg_var") - 1}, PVT_OTHER, pv_get_dlg_variable, + pv_set_dlg_variable, pv_parse_dialog_var_name, 0, 0, 0}, + {{0, 0}, 0, 0, 0, 0, 0, 0, 0}}; + +struct module_exports exports = {"ims_dialog", /* module's name */ + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* exported functions */ + mod_params, /* param exports */ + 0, /* exported RPC methods */ + mod_items, /* exported pseudo-variables */ + 0, /* reply processing function */ + mod_init, /* module initialization function */ + child_init, /* per-child init function */ + mod_destroy}; + +static int fixup_profile(void **param, int param_no) +{ + struct dlg_profile_table *profile; + pv_elem_t *model = NULL; + str s; + + s.s = (char *)(*param); + s.len = strlen(s.s); + if(s.len == 0) { + LM_ERR("param %d is empty string!\n", param_no); + return E_CFG; + } -static int fixup_profile(void** param, int param_no) { - struct dlg_profile_table *profile; - pv_elem_t *model = NULL; - str s; - - s.s = (char*) (*param); - s.len = strlen(s.s); - if (s.len == 0) { - LM_ERR("param %d is empty string!\n", param_no); - return E_CFG; - } - - if (param_no == 1) { - profile = search_dlg_profile(&s); - if (profile == NULL) { - LM_CRIT("profile <%s> not definited\n", s.s); - return E_CFG; - } - pkg_free(*param); - *param = (void*) profile; - return 0; - } else if (param_no == 2) { - if (pv_parse_format(&s, &model) || model == NULL) { - LM_ERR("wrong format [%s] for value param!\n", s.s); - return E_CFG; - } - *param = (void*) model; - } - return 0; + if(param_no == 1) { + profile = search_dlg_profile(&s); + if(profile == NULL) { + LM_CRIT("profile <%s> not definited\n", s.s); + return E_CFG; + } + pkg_free(*param); + *param = (void *)profile; + return 0; + } else if(param_no == 2) { + if(pv_parse_format(&s, &model) || model == NULL) { + LM_ERR("wrong format [%s] for value param!\n", s.s); + return E_CFG; + } + *param = (void *)model; + } + return 0; } -static int fixup_get_profile2(void** param, int param_no) { - pv_spec_t *sp; - int ret; - - if (param_no == 1) { - return fixup_profile(param, 1); - } else if (param_no == 2) { - ret = fixup_pvar_null(param, 1); - if (ret < 0) return ret; - sp = (pv_spec_t*) (*param); - if (sp->type != PVT_AVP && sp->type != PVT_SCRIPTVAR) { - LM_ERR("return must be an AVP or SCRIPT VAR!\n"); - return E_SCRIPT; - } - } - return 0; +static int fixup_get_profile2(void **param, int param_no) +{ + pv_spec_t *sp; + int ret; + + if(param_no == 1) { + return fixup_profile(param, 1); + } else if(param_no == 2) { + ret = fixup_pvar_null(param, 1); + if(ret < 0) + return ret; + sp = (pv_spec_t *)(*param); + if(sp->type != PVT_AVP && sp->type != PVT_SCRIPTVAR) { + LM_ERR("return must be an AVP or SCRIPT VAR!\n"); + return E_SCRIPT; + } + } + return 0; } -static int fixup_get_profile3(void** param, int param_no) { - if (param_no == 1) { - return fixup_profile(param, 1); - } else if (param_no == 2) { - return fixup_profile(param, 2); - } else if (param_no == 3) { - return fixup_get_profile2(param, 2); - } - return 0; +static int fixup_get_profile3(void **param, int param_no) +{ + if(param_no == 1) { + return fixup_profile(param, 1); + } else if(param_no == 2) { + return fixup_profile(param, 2); + } else if(param_no == 3) { + return fixup_get_profile2(param, 2); + } + return 0; } -static int fixup_dlg_terminate(void** param, int param_no) { - char *val; - int n = 0; - - if (param_no == 1) { - val = (char*) *param; - if (strcasecmp(val, "all") == 0) { - n = 2; - } else if (strcasecmp(val, "caller") == 0) { - n = 0; - } else if (strcasecmp(val, "callee") == 0) { - n = 1; - } else { - LM_ERR("invalid param \"%s\"\n", val); - return E_CFG; - } - pkg_free(*param); - *param = (void*) (long) n; - } else if (param_no == 2) { - //fixup str - return fixup_str_12(param, param_no); - } else { - LM_ERR("called with parameter != 1\n"); - return E_BUG; - } - return 0; +static int fixup_dlg_terminate(void **param, int param_no) +{ + char *val; + int n = 0; + + if(param_no == 1) { + val = (char *)*param; + if(strcasecmp(val, "all") == 0) { + n = 2; + } else if(strcasecmp(val, "caller") == 0) { + n = 0; + } else if(strcasecmp(val, "callee") == 0) { + n = 1; + } else { + LM_ERR("invalid param \"%s\"\n", val); + return E_CFG; + } + pkg_free(*param); + *param = (void *)(long)n; + } else if(param_no == 2) { + //fixup str + return fixup_str_12(param, param_no); + } else { + LM_ERR("called with parameter != 1\n"); + return E_BUG; + } + return 0; } -static int fixup_dlg_bridge(void** param, int param_no) +static int fixup_dlg_bridge(void **param, int param_no) { - if (param_no>=1 && param_no<=3) { + if(param_no >= 1 && param_no <= 3) { return fixup_spve_null(param, 1); } else { LM_ERR("called with parameter idx %d\n", param_no); @@ -289,564 +291,574 @@ static int fixup_dlg_bridge(void** param, int param_no) static int w_dlg_get(struct sip_msg *msg, char *ci, char *ft, char *tt) { struct dlg_cell *dlg = NULL; - str sc = {0,0}; - str sf = {0,0}; - str st = {0,0}; + str sc = {0, 0}; + str sf = {0, 0}; + str st = {0, 0}; unsigned int dir = 0; - if(ci==0 || ft==0 || tt==0) - { + if(ci == 0 || ft == 0 || tt == 0) { LM_ERR("invalid parameters\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)ci, &sc)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)ci, &sc) != 0) { LM_ERR("unable to get Call-ID\n"); return -1; } - if(sc.s==NULL || sc.len == 0) - { + if(sc.s == NULL || sc.len == 0) { LM_ERR("invalid Call-ID parameter\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)ft, &sf)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)ft, &sf) != 0) { LM_ERR("unable to get From tag\n"); return -1; } - if(sf.s==NULL || sf.len == 0) - { + if(sf.s == NULL || sf.len == 0) { LM_ERR("invalid From tag parameter\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)tt, &st)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)tt, &st) != 0) { LM_ERR("unable to get To Tag\n"); return -1; } - if(st.s==NULL || st.len == 0) - { + if(st.s == NULL || st.len == 0) { LM_ERR("invalid To tag parameter\n"); return -1; } dlg = get_dlg(&sc, &sf, &st, &dir); - if(dlg==NULL) + if(dlg == NULL) return -1; - + /* note: we should unref the dlg here (from get_dlg). BUT, because we are setting the current dialog we can ignore the unref... instead of unreffing and reffing again for the set_current_dialog. NB. this function is generally called from the cfg file. If used via API, remember to unref the dlg afterwards - */ + */ set_current_dialog(msg, dlg); - _dlg_ctx.dlg = dlg; - _dlg_ctx.dir = dir; + _dlg_ctx.dlg = dlg; + _dlg_ctx.dir = dir; return 1; } -int load_ims_dlg(ims_dlg_api_t *dlgb) { +int load_ims_dlg(ims_dlg_api_t *dlgb) +{ - dlgb->register_dlgcb = register_dlgcb; - dlgb->register_dlgcb_nodlg = register_dlgcb_nodlg; - dlgb->set_dlg_var = api_set_dlg_variable; - dlgb->get_dlg_var = api_get_dlg_variable; - dlgb->terminate_dlg = w_api_terminate_dlg; - dlgb->lookup_terminate_dlg = w_api_lookup_terminate_dlg; - dlgb->get_dlg_expires = api_get_dlg_expires; - dlgb->get_dlg = dlg_get_msg_dialog; - dlgb->release_dlg = dlg_release; + dlgb->register_dlgcb = register_dlgcb; + dlgb->register_dlgcb_nodlg = register_dlgcb_nodlg; + dlgb->set_dlg_var = api_set_dlg_variable; + dlgb->get_dlg_var = api_get_dlg_variable; + dlgb->terminate_dlg = w_api_terminate_dlg; + dlgb->lookup_terminate_dlg = w_api_lookup_terminate_dlg; + dlgb->get_dlg_expires = api_get_dlg_expires; + dlgb->get_dlg = dlg_get_msg_dialog; + dlgb->release_dlg = dlg_release; - return 1; + return 1; } -static int pv_get_dlg_count(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res) +static int pv_get_dlg_count( + struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { int n; int l; char *ch; - if(msg==NULL || res==NULL) + if(msg == NULL || res == NULL) return -1; n = counter_get_val(dialog_ng_cnts_h.active); l = 0; - ch = int2str( n, &l); + ch = int2str(n, &l); res->rs.s = ch; res->rs.len = l; res->ri = n; - res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT; + res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT; return 0; } -static int mod_init(void) { - unsigned int n; - - if (rpc_register_array(rpc_methods) != 0) { - LM_ERR("failed to register RPC commands\n"); - return -1; - } - - if (dialog_ng_stats_init() != 0) { - LM_ERR("Failed to register dialog_ng counters\n"); - return -1; - } - - if (faked_msg_init() < 0) - return -1; - - if (timeout_spec.s) - timeout_spec.len = strlen(timeout_spec.s); - - dlg_bridge_controller.len = strlen(dlg_bridge_controller.s); - - - /* param checkings */ - if (dlg_flag == -1) { - LM_ERR("no dlg flag set!!\n"); - return -1; - } else if (dlg_flag > MAX_FLAG) { - LM_ERR("invalid dlg flag %d!!\n", dlg_flag); - return -1; - } - - if (rr_param == 0 || rr_param[0] == 0) { - LM_ERR("empty rr_param!!\n"); - return -1; - } else if (strlen(rr_param) > MAX_DLG_RR_PARAM_NAME) { - LM_ERR("rr_param too long (max=%d)!!\n", MAX_DLG_RR_PARAM_NAME); - return -1; - } - - if (timeout_spec.s) { - if (pv_parse_spec(&timeout_spec, &timeout_avp) == 0 - && (timeout_avp.type != PVT_AVP)) { - LM_ERR("malformed or non AVP timeout " - "AVP definition in '%.*s'\n", timeout_spec.len, timeout_spec.s); - return -1; - } - } - - if (default_timeout <= 0) { - LM_ERR("0 default_timeout not accepted!!\n"); - return -1; - } - - if (ruri_pvar_param.s == NULL || *ruri_pvar_param.s == '\0') { - LM_ERR("invalid r-uri PV string\n"); - return -1; - } - ruri_pvar_param.len = strlen(ruri_pvar_param.s); - if (pv_parse_format(&ruri_pvar_param, &ruri_param_model) < 0 - || ruri_param_model == NULL) { - LM_ERR("malformed r-uri PV string: %s\n", ruri_pvar_param.s); - return -1; - } - - /* update the len of the extra headers */ - if (dlg_extra_hdrs.s) - dlg_extra_hdrs.len = strlen(dlg_extra_hdrs.s); - - if (seq_match_mode != SEQ_MATCH_NO_ID && - seq_match_mode != SEQ_MATCH_FALLBACK && - seq_match_mode != SEQ_MATCH_STRICT_ID) { - LM_ERR("invalid value %d for seq_match_mode param!!\n", seq_match_mode); - return -1; - } - - if (detect_spirals != 0 && detect_spirals != 1) { - LM_ERR("invalid value %d for detect_spirals param!!\n", detect_spirals); - return -1; - } - - /* create profile hashes */ - if (add_profile_definitions(profiles_nv_s, 0) != 0) { - LM_ERR("failed to add profiles without value\n"); - return -1; - } - if (add_profile_definitions(profiles_wv_s, 1) != 0) { - LM_ERR("failed to add profiles with value\n"); - return -1; - } - - /* load the TM API */ - if (load_tm_api(&d_tmb) != 0) { - LM_ERR("can't load TM API\n"); - return -1; - } - - /* load RR API also */ - if (load_rr_api(&d_rrb) != 0) { - LM_ERR("can't load RR API\n"); - return -1; - } - - /* register callbacks*/ - /* listen for all incoming requests */ - if (d_tmb.register_tmcb(0, 0, TMCB_REQUEST_IN, dlg_onreq, 0, 0) <= 0) { - LM_ERR("cannot register TMCB_REQUEST_IN callback\n"); - return -1; - } - - /* listen for all routed requests */ - if (d_rrb.register_rrcb(dlg_onroute, 0) < 0) { - LM_ERR("cannot register RR callback\n"); - return -1; - } - - if (register_script_cb(profile_cleanup, POST_SCRIPT_CB | REQUEST_CB, 0) < 0) { - LM_ERR("cannot register script callback"); - return -1; - } - if (register_script_cb(dlg_cfg_cb, - PRE_SCRIPT_CB | REQUEST_CB, 0) < 0) { - LM_ERR("cannot register pre-script ctx callback\n"); - return -1; - } - if (register_script_cb(dlg_cfg_cb, - POST_SCRIPT_CB | REQUEST_CB, 0) < 0) { - LM_ERR("cannot register post-script ctx callback\n"); - return -1; - } - - if (register_script_cb(spiral_detect_reset, POST_SCRIPT_CB | REQUEST_CB, 0) < 0) { - LM_ERR("cannot register req pre-script spiral detection reset callback\n"); - return -1; - } - - if (register_timer(dlg_timer_routine, 0, 1) < 0) { - LM_ERR("failed to register timer \n"); - return -1; - } - - /*for testing only!!!! setup timer to call print all dlg every 10 seconds!*/ - if (register_timer(print_all_dlgs, 0, 10) < 0) { - LM_ERR("failed to register timer \n"); - return -1; - } - - /* init handlers */ - init_dlg_handlers(rr_param, dlg_flag, - timeout_spec.s ? &timeout_avp : 0, default_timeout, seq_match_mode); - - /* init timer */ - if (init_dlg_timer(dlg_ontimeout) != 0) { - LM_ERR("cannot init timer list\n"); - return -1; - } - - /* sanitize dlg_hash_zie */ - if (dlg_hash_size < 1) { - LM_WARN("hash_size is smaller " - "then 1 -> rounding from %d to 1\n", - dlg_hash_size); - dlg_hash_size = 1; - } - - /* initialized the hash table */ - for (n = 0; n < (8 * sizeof (n)); n++) { - if (dlg_hash_size == (1 << n)) - break; - if (n && dlg_hash_size < (1 << n)) { - LM_WARN("hash_size is not a power " - "of 2 as it should be -> rounding from %d to %d\n", - dlg_hash_size, 1 << (n - 1)); - dlg_hash_size = 1 << (n - 1); - } - } - - if (init_dlg_table(dlg_hash_size) < 0) { - LM_ERR("failed to create hash table\n"); - return -1; - } - - /* if a database should be used to store the dialogs' information */ +static int mod_init(void) +{ + unsigned int n; + + if(rpc_register_array(rpc_methods) != 0) { + LM_ERR("failed to register RPC commands\n"); + return -1; + } + + if(dialog_ng_stats_init() != 0) { + LM_ERR("Failed to register dialog_ng counters\n"); + return -1; + } + + if(faked_msg_init() < 0) + return -1; + + if(timeout_spec.s) + timeout_spec.len = strlen(timeout_spec.s); + + dlg_bridge_controller.len = strlen(dlg_bridge_controller.s); + + + /* param checkings */ + if(dlg_flag == -1) { + LM_ERR("no dlg flag set!!\n"); + return -1; + } else if(dlg_flag > MAX_FLAG) { + LM_ERR("invalid dlg flag %d!!\n", dlg_flag); + return -1; + } + + if(rr_param == 0 || rr_param[0] == 0) { + LM_ERR("empty rr_param!!\n"); + return -1; + } else if(strlen(rr_param) > MAX_DLG_RR_PARAM_NAME) { + LM_ERR("rr_param too long (max=%d)!!\n", MAX_DLG_RR_PARAM_NAME); + return -1; + } + + if(timeout_spec.s) { + if(pv_parse_spec(&timeout_spec, &timeout_avp) == 0 + && (timeout_avp.type != PVT_AVP)) { + LM_ERR("malformed or non AVP timeout " + "AVP definition in '%.*s'\n", + timeout_spec.len, timeout_spec.s); + return -1; + } + } + + if(default_timeout <= 0) { + LM_ERR("0 default_timeout not accepted!!\n"); + return -1; + } + + if(ruri_pvar_param.s == NULL || *ruri_pvar_param.s == '\0') { + LM_ERR("invalid r-uri PV string\n"); + return -1; + } + ruri_pvar_param.len = strlen(ruri_pvar_param.s); + if(pv_parse_format(&ruri_pvar_param, &ruri_param_model) < 0 + || ruri_param_model == NULL) { + LM_ERR("malformed r-uri PV string: %s\n", ruri_pvar_param.s); + return -1; + } + + /* update the len of the extra headers */ + if(dlg_extra_hdrs.s) + dlg_extra_hdrs.len = strlen(dlg_extra_hdrs.s); + + if(seq_match_mode != SEQ_MATCH_NO_ID && seq_match_mode != SEQ_MATCH_FALLBACK + && seq_match_mode != SEQ_MATCH_STRICT_ID) { + LM_ERR("invalid value %d for seq_match_mode param!!\n", seq_match_mode); + return -1; + } + + if(detect_spirals != 0 && detect_spirals != 1) { + LM_ERR("invalid value %d for detect_spirals param!!\n", detect_spirals); + return -1; + } + + /* create profile hashes */ + if(add_profile_definitions(profiles_nv_s, 0) != 0) { + LM_ERR("failed to add profiles without value\n"); + return -1; + } + if(add_profile_definitions(profiles_wv_s, 1) != 0) { + LM_ERR("failed to add profiles with value\n"); + return -1; + } + + /* load the TM API */ + if(load_tm_api(&d_tmb) != 0) { + LM_ERR("can't load TM API\n"); + return -1; + } + + /* load RR API also */ + if(load_rr_api(&d_rrb) != 0) { + LM_ERR("can't load RR API\n"); + return -1; + } + + /* register callbacks*/ + /* listen for all incoming requests */ + if(d_tmb.register_tmcb(0, 0, TMCB_REQUEST_IN, dlg_onreq, 0, 0) <= 0) { + LM_ERR("cannot register TMCB_REQUEST_IN callback\n"); + return -1; + } + + /* listen for all routed requests */ + if(d_rrb.register_rrcb(dlg_onroute, 0) < 0) { + LM_ERR("cannot register RR callback\n"); + return -1; + } + + if(register_script_cb(profile_cleanup, POST_SCRIPT_CB | REQUEST_CB, 0) + < 0) { + LM_ERR("cannot register script callback"); + return -1; + } + if(register_script_cb(dlg_cfg_cb, PRE_SCRIPT_CB | REQUEST_CB, 0) < 0) { + LM_ERR("cannot register pre-script ctx callback\n"); + return -1; + } + if(register_script_cb(dlg_cfg_cb, POST_SCRIPT_CB | REQUEST_CB, 0) < 0) { + LM_ERR("cannot register post-script ctx callback\n"); + return -1; + } + + if(register_script_cb(spiral_detect_reset, POST_SCRIPT_CB | REQUEST_CB, 0) + < 0) { + LM_ERR("cannot register req pre-script spiral detection reset " + "callback\n"); + return -1; + } + + if(register_timer(dlg_timer_routine, 0, 1) < 0) { + LM_ERR("failed to register timer \n"); + return -1; + } + + /*for testing only!!!! setup timer to call print all dlg every 10 seconds!*/ + if(register_timer(print_all_dlgs, 0, 10) < 0) { + LM_ERR("failed to register timer \n"); + return -1; + } + + /* init handlers */ + init_dlg_handlers(rr_param, dlg_flag, timeout_spec.s ? &timeout_avp : 0, + default_timeout, seq_match_mode); + + /* init timer */ + if(init_dlg_timer(dlg_ontimeout) != 0) { + LM_ERR("cannot init timer list\n"); + return -1; + } + + /* sanitize dlg_hash_zie */ + if(dlg_hash_size < 1) { + LM_WARN("hash_size is smaller " + "then 1 -> rounding from %d to 1\n", + dlg_hash_size); + dlg_hash_size = 1; + } + + /* initialized the hash table */ + for(n = 0; n < (8 * sizeof(n)); n++) { + if(dlg_hash_size == (1 << n)) + break; + if(n && dlg_hash_size < (1 << n)) { + LM_WARN("hash_size is not a power " + "of 2 as it should be -> rounding from %d to %d\n", + dlg_hash_size, 1 << (n - 1)); + dlg_hash_size = 1 << (n - 1); + } + } + + if(init_dlg_table(dlg_hash_size) < 0) { + LM_ERR("failed to create hash table\n"); + return -1; + } + + /* if a database should be used to store the dialogs' information */ dlg_db_mode = dlg_db_mode_param; - if (dlg_db_mode==DB_MODE_NONE) { - db_url.s = 0; db_url.len = 0; + if(dlg_db_mode == DB_MODE_NONE) { + db_url.s = 0; + db_url.len = 0; } else { - if (dlg_db_mode!=DB_MODE_REALTIME && - dlg_db_mode!=DB_MODE_DELAYED && dlg_db_mode!=DB_MODE_SHUTDOWN ) { + if(dlg_db_mode != DB_MODE_REALTIME && dlg_db_mode != DB_MODE_DELAYED + && dlg_db_mode != DB_MODE_SHUTDOWN) { LM_ERR("unsupported db_mode %d\n", dlg_db_mode); return -1; } - if ( !db_url.s || db_url.len==0 ) { + if(!db_url.s || db_url.len == 0) { LM_ERR("db_url not configured for db_mode %d\n", dlg_db_mode); return -1; } - if (init_dlg_db(&db_url, dlg_hash_size, db_update_period, db_fetch_rows)!=0) { + if(init_dlg_db(&db_url, dlg_hash_size, db_update_period, db_fetch_rows) + != 0) { LM_ERR("failed to initialize the DB support\n"); return -1; } run_load_callbacks(); } - destroy_dlg_callbacks(DLGCB_LOADED); + destroy_dlg_callbacks(DLGCB_LOADED); - return 0; + return 0; } -static int child_init(int rank) { +static int child_init(int rank) +{ dlg_db_mode = dlg_db_mode_param; - if ( ((dlg_db_mode==DB_MODE_REALTIME || dlg_db_mode==DB_MODE_DELAYED) && - (rank>0 || rank==PROC_TIMER)) || - (dlg_db_mode==DB_MODE_SHUTDOWN && (rank==PROC_MAIN)) ) { - if ( dlg_connect_db(&db_url) ) { - LM_ERR("failed to connect to database (rank=%d)\n",rank); - return -1; - } + if(((dlg_db_mode == DB_MODE_REALTIME || dlg_db_mode == DB_MODE_DELAYED) + && (rank > 0 || rank == PROC_TIMER)) + || (dlg_db_mode == DB_MODE_SHUTDOWN && (rank == PROC_MAIN))) { + if(dlg_connect_db(&db_url)) { + LM_ERR("failed to connect to database (rank=%d)\n", rank); + return -1; + } } /* in DB_MODE_SHUTDOWN only PROC_MAIN will do a DB dump at the end, so * for the rest of the processes will be the same as DB_MODE_NONE */ - if (dlg_db_mode==DB_MODE_SHUTDOWN && rank!=PROC_MAIN) + if(dlg_db_mode == DB_MODE_SHUTDOWN && rank != PROC_MAIN) dlg_db_mode = DB_MODE_NONE; /* in DB_MODE_REALTIME and DB_MODE_DELAYED the PROC_MAIN have no DB handle */ - if ( (dlg_db_mode==DB_MODE_REALTIME || dlg_db_mode==DB_MODE_DELAYED) && - rank==PROC_MAIN) + if((dlg_db_mode == DB_MODE_REALTIME || dlg_db_mode == DB_MODE_DELAYED) + && rank == PROC_MAIN) dlg_db_mode = DB_MODE_NONE; - return 0; + return 0; } -static void mod_destroy(void) { +static void mod_destroy(void) +{ if(dlg_db_mode == DB_MODE_DELAYED || dlg_db_mode == DB_MODE_SHUTDOWN) { dialog_update_db(0, 0); destroy_dlg_db(); } - destroy_dlg_table(); - destroy_dlg_timer(); - destroy_dlg_callbacks(DLGCB_CREATED | DLGCB_LOADED); - destroy_dlg_handlers(); - destroy_dlg_profiles(); - dialog_ng_stats_destroy(); + destroy_dlg_table(); + destroy_dlg_timer(); + destroy_dlg_callbacks(DLGCB_CREATED | DLGCB_LOADED); + destroy_dlg_handlers(); + destroy_dlg_profiles(); + dialog_ng_stats_destroy(); } -static int w_set_dlg_profile(struct sip_msg *msg, char *profile, char *value) { - pv_elem_t *pve; - str val_s; - - pve = (pv_elem_t *) value; - - if (((struct dlg_profile_table*) profile)->has_value) { - if (pve == NULL || pv_printf_s(msg, pve, &val_s) != 0 || - val_s.len == 0 || val_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - return -1; - } - if (set_dlg_profile(msg, &val_s, - (struct dlg_profile_table*) profile) < 0) { - LM_ERR("failed to set profile"); - return -1; - } - } else { - if (set_dlg_profile(msg, NULL, - (struct dlg_profile_table*) profile) < 0) { - LM_ERR("failed to set profile"); - return -1; - } - } - return 1; +static int w_set_dlg_profile(struct sip_msg *msg, char *profile, char *value) +{ + pv_elem_t *pve; + str val_s; + + pve = (pv_elem_t *)value; + + if(((struct dlg_profile_table *)profile)->has_value) { + if(pve == NULL || pv_printf_s(msg, pve, &val_s) != 0 || val_s.len == 0 + || val_s.s == NULL) { + LM_WARN("cannot get string for value\n"); + return -1; + } + if(set_dlg_profile(msg, &val_s, (struct dlg_profile_table *)profile) + < 0) { + LM_ERR("failed to set profile"); + return -1; + } + } else { + if(set_dlg_profile(msg, NULL, (struct dlg_profile_table *)profile) + < 0) { + LM_ERR("failed to set profile"); + return -1; + } + } + return 1; } -static int w_unset_dlg_profile(struct sip_msg *msg, char *profile, char *value) { - pv_elem_t *pve; - str val_s; - - pve = (pv_elem_t *) value; - - if (((struct dlg_profile_table*) profile)->has_value) { - if (pve == NULL || pv_printf_s(msg, pve, &val_s) != 0 || - val_s.len == 0 || val_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - return -1; - } - if (unset_dlg_profile(msg, &val_s, - (struct dlg_profile_table*) profile) < 0) { - LM_ERR("failed to unset profile"); - return -1; - } - } else { - if (unset_dlg_profile(msg, NULL, - (struct dlg_profile_table*) profile) < 0) { - LM_ERR("failed to unset profile"); - return -1; - } - } - return 1; +static int w_unset_dlg_profile(struct sip_msg *msg, char *profile, char *value) +{ + pv_elem_t *pve; + str val_s; + + pve = (pv_elem_t *)value; + + if(((struct dlg_profile_table *)profile)->has_value) { + if(pve == NULL || pv_printf_s(msg, pve, &val_s) != 0 || val_s.len == 0 + || val_s.s == NULL) { + LM_WARN("cannot get string for value\n"); + return -1; + } + if(unset_dlg_profile(msg, &val_s, (struct dlg_profile_table *)profile) + < 0) { + LM_ERR("failed to unset profile"); + return -1; + } + } else { + if(unset_dlg_profile(msg, NULL, (struct dlg_profile_table *)profile) + < 0) { + LM_ERR("failed to unset profile"); + return -1; + } + } + return 1; } -static int w_is_in_profile(struct sip_msg *msg, char *profile, char *value) { - pv_elem_t *pve; - str val_s; - - pve = (pv_elem_t *) value; - - if (pve != NULL && ((struct dlg_profile_table*) profile)->has_value) { - if (pv_printf_s(msg, pve, &val_s) != 0 || - val_s.len == 0 || val_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - return -1; - } - return is_dlg_in_profile(msg, (struct dlg_profile_table*) profile, - &val_s); - } else { - return is_dlg_in_profile(msg, (struct dlg_profile_table*) profile, - NULL); - } +static int w_is_in_profile(struct sip_msg *msg, char *profile, char *value) +{ + pv_elem_t *pve; + str val_s; + + pve = (pv_elem_t *)value; + + if(pve != NULL && ((struct dlg_profile_table *)profile)->has_value) { + if(pv_printf_s(msg, pve, &val_s) != 0 || val_s.len == 0 + || val_s.s == NULL) { + LM_WARN("cannot get string for value\n"); + return -1; + } + return is_dlg_in_profile( + msg, (struct dlg_profile_table *)profile, &val_s); + } else { + return is_dlg_in_profile( + msg, (struct dlg_profile_table *)profile, NULL); + } } /** * get dynamic name profile size */ -static int w_get_profile_size3(struct sip_msg *msg, char *profile, - char *value, char *result) { - pv_elem_t *pve; - str val_s; - pv_spec_t *sp_dest; - unsigned int size; - pv_value_t val; - - if (result != NULL) { - pve = (pv_elem_t *) value; - sp_dest = (pv_spec_t *) result; - } else { - pve = NULL; - sp_dest = (pv_spec_t *) value; - } - if (pve != NULL && ((struct dlg_profile_table*) profile)->has_value) { - if (pv_printf_s(msg, pve, &val_s) != 0 || - val_s.len == 0 || val_s.s == NULL) { - LM_WARN("cannot get string for value\n"); - return -1; - } - size = get_profile_size((struct dlg_profile_table*) profile, &val_s); - } else { - size = get_profile_size((struct dlg_profile_table*) profile, NULL); - } - - memset(&val, 0, sizeof (pv_value_t)); - val.flags = PV_VAL_INT | PV_TYPE_INT; - val.ri = (long) size; - - if (sp_dest->setf(msg, &sp_dest->pvp, (int) EQ_T, &val) < 0) { - LM_ERR("setting profile PV failed\n"); - return -1; - } - - return 1; +static int w_get_profile_size3( + struct sip_msg *msg, char *profile, char *value, char *result) +{ + pv_elem_t *pve; + str val_s; + pv_spec_t *sp_dest; + unsigned int size; + pv_value_t val; + + if(result != NULL) { + pve = (pv_elem_t *)value; + sp_dest = (pv_spec_t *)result; + } else { + pve = NULL; + sp_dest = (pv_spec_t *)value; + } + if(pve != NULL && ((struct dlg_profile_table *)profile)->has_value) { + if(pv_printf_s(msg, pve, &val_s) != 0 || val_s.len == 0 + || val_s.s == NULL) { + LM_WARN("cannot get string for value\n"); + return -1; + } + size = get_profile_size((struct dlg_profile_table *)profile, &val_s); + } else { + size = get_profile_size((struct dlg_profile_table *)profile, NULL); + } + + memset(&val, 0, sizeof(pv_value_t)); + val.flags = PV_VAL_INT | PV_TYPE_INT; + val.ri = (long)size; + + if(sp_dest->setf(msg, &sp_dest->pvp, (int)EQ_T, &val) < 0) { + LM_ERR("setting profile PV failed\n"); + return -1; + } + + return 1; } /** * get static name profile size */ -static int w_get_profile_size2(struct sip_msg *msg, char *profile, char *result) { - return w_get_profile_size3(msg, profile, result, NULL); +static int w_get_profile_size2(struct sip_msg *msg, char *profile, char *result) +{ + return w_get_profile_size3(msg, profile, result, NULL); } -static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2) { - dlg_ctx_t *dctx; - int val; - - if (fixup_get_ivalue(msg, (gparam_p) flag, &val) != 0) { - LM_ERR("no flag value\n"); - return -1; - } - if (val < 0 || val > 31) - return -1; - if ((dctx = dlg_get_dlg_ctx()) == NULL) - return -1; - - dctx->flags |= 1 << val; - if (dctx->dlg) - dctx->dlg->sflags |= 1 << val; - return 1; +static int w_dlg_setflag(struct sip_msg *msg, char *flag, char *s2) +{ + dlg_ctx_t *dctx; + int val; + + if(fixup_get_ivalue(msg, (gparam_p)flag, &val) != 0) { + LM_ERR("no flag value\n"); + return -1; + } + if(val < 0 || val > 31) + return -1; + if((dctx = dlg_get_dlg_ctx()) == NULL) + return -1; + + dctx->flags |= 1 << val; + if(dctx->dlg) + dctx->dlg->sflags |= 1 << val; + return 1; } -static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2) { - dlg_ctx_t *dctx; - int val; +static int w_dlg_resetflag(struct sip_msg *msg, char *flag, str *s2) +{ + dlg_ctx_t *dctx; + int val; - if (fixup_get_ivalue(msg, (gparam_p) flag, &val) != 0) { - LM_ERR("no flag value\n"); - return -1; - } - if (val < 0 || val > 31) - return -1; + if(fixup_get_ivalue(msg, (gparam_p)flag, &val) != 0) { + LM_ERR("no flag value\n"); + return -1; + } + if(val < 0 || val > 31) + return -1; - if ((dctx = dlg_get_dlg_ctx()) == NULL) - return -1; + if((dctx = dlg_get_dlg_ctx()) == NULL) + return -1; - dctx->flags &= ~(1 << val); - if (dctx->dlg) - dctx->dlg->sflags &= ~(1 << val); - return 1; + dctx->flags &= ~(1 << val); + if(dctx->dlg) + dctx->dlg->sflags &= ~(1 << val); + return 1; } -static int w_dlg_isflagset(struct sip_msg *msg, char *flag, str *s2) { - dlg_ctx_t *dctx; - int val; +static int w_dlg_isflagset(struct sip_msg *msg, char *flag, str *s2) +{ + dlg_ctx_t *dctx; + int val; - if (fixup_get_ivalue(msg, (gparam_p) flag, &val) != 0) { - LM_ERR("no flag value\n"); - return -1; - } - if (val < 0 || val > 31) - return -1; + if(fixup_get_ivalue(msg, (gparam_p)flag, &val) != 0) { + LM_ERR("no flag value\n"); + return -1; + } + if(val < 0 || val > 31) + return -1; - if ((dctx = dlg_get_dlg_ctx()) == NULL) - return -1; + if((dctx = dlg_get_dlg_ctx()) == NULL) + return -1; - if (dctx->dlg) - return (dctx->dlg->sflags & (1 << val)) ? 1 : -1; - return (dctx->flags & (1 << val)) ? 1 : -1; + if(dctx->dlg) + return (dctx->dlg->sflags & (1 << val)) ? 1 : -1; + return (dctx->flags & (1 << val)) ? 1 : -1; } -static int w_dlg_terminate(struct sip_msg *msg, char *side, char *r) { - struct dlg_cell *dlg; - str reason = {0, 0}; - - int n = (int) (long) side; - - //check if a reason was given - if (r) { - if (get_str_fparam(&reason, msg, (fparam_t *) r) < 0) { - LM_ERR("failed to recover reason parameter\n"); - return -1; - } - } - - dlg = dlg_get_msg_dialog(msg); - //dlg_get_ctx_dialog(); - if (!dlg) { - LM_DBG("Unable to find dialog for terminate\n"); - return -1; - } - - if (!dlg_terminate(dlg, msg, &reason, n, NULL)) { - LM_DBG("Failed to terminate dialog\n"); - return -1; - } - - return 1; +static int w_dlg_terminate(struct sip_msg *msg, char *side, char *r) +{ + struct dlg_cell *dlg; + str reason = {0, 0}; + + int n = (int)(long)side; + + //check if a reason was given + if(r) { + if(get_str_fparam(&reason, msg, (fparam_t *)r) < 0) { + LM_ERR("failed to recover reason parameter\n"); + return -1; + } + } + + dlg = dlg_get_msg_dialog(msg); + //dlg_get_ctx_dialog(); + if(!dlg) { + LM_DBG("Unable to find dialog for terminate\n"); + return -1; + } + + if(!dlg_terminate(dlg, msg, &reason, n, NULL)) { + LM_DBG("Failed to terminate dialog\n"); + return -1; + } + + return 1; } /* * Wrapper around is_known_dlg(). */ -static int w_is_known_dlg(struct sip_msg *msg) { - return is_known_dlg(msg); +static int w_is_known_dlg(struct sip_msg *msg) +{ + return is_known_dlg(msg); } /**************************** RPC functions ******************************/ @@ -859,42 +871,36 @@ static int w_is_known_dlg(struct sip_msg *msg) { * \param with_context if 1 then the dialog context will be also printed * \return 0 on success, -1 on failure */ -static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, struct dlg_cell *dlg, void *dh) +static inline void internal_rpc_print_dlg( + rpc_t *rpc, void *c, struct dlg_cell *dlg, void *dh) { - void* dlg_outs_h; - void* root; - void* roota; - struct dlg_cell_out* dlg_out; + void *dlg_outs_h; + void *root; + void *roota; + struct dlg_cell_out *dlg_out; - rpc->struct_add(dh, "{", "Dialog", &root); + rpc->struct_add(dh, "{", "Dialog", &root); rpc->struct_add(root, "dd", "Entry", dlg->h_entry, "Id", dlg->h_id); - rpc->struct_add(root, "SSSSSSSsd[", - "RURI", &dlg->req_uri, - "From", &dlg->from_uri, - "Call-ID", &dlg->callid, - "Caller Contact", &dlg->caller_contact, - "Caller Route Set", &dlg->caller_route_set, - "Dialog-ID", &dlg->did, - "From Tag", &dlg->from_tag, - "State", state_to_char(dlg->state), - "Ref", dlg->ref, - "dlg_outs", &roota - ); + rpc->struct_add(root, "SSSSSSSsd[", "RURI", &dlg->req_uri, "From", + &dlg->from_uri, "Call-ID", &dlg->callid, "Caller Contact", + &dlg->caller_contact, "Caller Route Set", &dlg->caller_route_set, + "Dialog-ID", &dlg->did, "From Tag", &dlg->from_tag, "State", + state_to_char(dlg->state), "Ref", dlg->ref, "dlg_outs", &roota); lock_get(dlg->dlg_out_entries_lock); dlg_out = dlg->dlg_entry_out.first; - while (dlg_out) { - - rpc->struct_add(roota, "{", "dlg_out", &dlg_outs_h); - rpc->struct_add(dlg_outs_h, "dd", "Entry", dlg_out->h_entry, "Id", dlg_out->h_id); - dlg_out = dlg_out->next; + while(dlg_out) { + + rpc->struct_add(roota, "{", "dlg_out", &dlg_outs_h); + rpc->struct_add(dlg_outs_h, "dd", "Entry", dlg_out->h_entry, "Id", + dlg_out->h_id); + dlg_out = dlg_out->next; } lock_release(dlg->dlg_out_entries_lock); /*now traverse dlg_outs*/ - } /*! @@ -910,32 +916,32 @@ static void internal_rpc_print_dlgs(rpc_t *rpc, void *c) unsigned int i; void *ah; - void *dh; /*beginning struct holding dialogs*/ + void *dh; /*beginning struct holding dialogs*/ - if (rpc->add(c, "{", &ah) < 0) { + if(rpc->add(c, "{", &ah) < 0) { rpc->fault(c, 500, "Internal error creating top rpc"); return; } - if (rpc->struct_add(ah, "d[", "Size", (int) d_table->size, "Dialogs", &dh) < 0) { + if(rpc->struct_add(ah, "d[", "Size", (int)d_table->size, "Dialogs", &dh) + < 0) { rpc->fault(c, 500, "Internal error creating inner struct"); return; } - for( i=0 ; isize ; i++ ) { - dlg_lock( d_table, &(d_table->entries[i]) ); + for(i = 0; i < d_table->size; i++) { + dlg_lock(d_table, &(d_table->entries[i])); - for( dlg=d_table->entries[i].first ; dlg ; dlg=dlg->next ) { + for(dlg = d_table->entries[i].first; dlg; dlg = dlg->next) { internal_rpc_print_dlg(rpc, c, dlg, dh); } - dlg_unlock( d_table, &(d_table->entries[i]) ); + dlg_unlock(d_table, &(d_table->entries[i])); } } -static const char *rpc_print_dlgs_doc[2] = { - "Print all dialogs", 0 -}; +static const char *rpc_print_dlgs_doc[2] = {"Print all dialogs", 0}; -static void rpc_print_dlgs(rpc_t *rpc, void *c) { +static void rpc_print_dlgs(rpc_t *rpc, void *c) +{ internal_rpc_print_dlgs(rpc, c); } @@ -959,94 +965,87 @@ static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) { }*/ static const char *rpc_end_dlg_entry_id_doc[2] = { - "End a given dialog based on [h_entry] [h_id]", 0 -}; + "End a given dialog based on [h_entry] [h_id]", 0}; static const char *rpc_end_all_active_dlg_doc[2] = { - "End all ACTIVE dialogs", 0 -}; + "End all ACTIVE dialogs", 0}; /* Wrapper for terminating dialog from API - from other modules */ -static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) { - unsigned int h_entry, h_id; - struct dlg_cell * dlg = NULL; - str rpc_extra_hdrs = {0,0}; - str dfl_rpc_extra_hdrs = {"Reason: mi_terminated\r\n",23}; - str reason = {"mi_terminated", 12}; - int n; - - n = rpc->scan(c, "dd", &h_entry, &h_id); - if (n < 2) { - LM_ERR("unable to read the parameters (%d)\n", n); - rpc->fault(c, 500, "Invalid parameters"); - return; - } - if(rpc->scan(c, "*S", &rpc_extra_hdrs)<1) - { - rpc_extra_hdrs = dfl_rpc_extra_hdrs; - } - - dlg = lookup_dlg(h_entry, h_id);//increments ref count! - if(dlg==NULL) { - rpc->fault(c, 404, "Dialog not found"); - return; - } +static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) +{ + unsigned int h_entry, h_id; + struct dlg_cell *dlg = NULL; + str rpc_extra_hdrs = {0, 0}; + str dfl_rpc_extra_hdrs = {"Reason: mi_terminated\r\n", 23}; + str reason = {"mi_terminated", 12}; + int n; - unref_dlg(dlg, 1); - LM_DBG("Setting reason to [%.*s] and extra headers to [%.*s]\n", reason.len, reason.s, rpc_extra_hdrs.len, rpc_extra_hdrs.s); - dlg_terminate(dlg, NULL, &reason/*reason*/, 2, &rpc_extra_hdrs); + n = rpc->scan(c, "dd", &h_entry, &h_id); + if(n < 2) { + LM_ERR("unable to read the parameters (%d)\n", n); + rpc->fault(c, 500, "Invalid parameters"); + return; + } + if(rpc->scan(c, "*S", &rpc_extra_hdrs) < 1) { + rpc_extra_hdrs = dfl_rpc_extra_hdrs; + } + dlg = lookup_dlg(h_entry, h_id); //increments ref count! + if(dlg == NULL) { + rpc->fault(c, 404, "Dialog not found"); + return; + } + + unref_dlg(dlg, 1); + LM_DBG("Setting reason to [%.*s] and extra headers to [%.*s]\n", reason.len, + reason.s, rpc_extra_hdrs.len, rpc_extra_hdrs.s); + dlg_terminate(dlg, NULL, &reason /*reason*/, 2, &rpc_extra_hdrs); } -static void rpc_end_all_active_dlg (rpc_t *rpc, void *c) +static void rpc_end_all_active_dlg(rpc_t *rpc, void *c) { - struct dlg_cell * dlg = NULL, - * dlg_to_term = NULL; - dlg_entry_t entry; - - unsigned int i_count = 0, - h_index = 0; - - str rpc_extra_hdrs = {0,0}; - str dfl_rpc_extra_hdrs = {"Reason: mi_terminated\r\n",23}; - str reason = {"mi_terminated", 12}; - - - if (!d_table) - { - rpc->fault(c, 500, "Dialog hash table not initialized"); - return; - } - if (!d_table->size) return; - - rpc_extra_hdrs = dfl_rpc_extra_hdrs; - LM_DBG("Setting reason to [%.*s] and extra headers to [%.*s]\n", - reason.len, reason.s, rpc_extra_hdrs.len, rpc_extra_hdrs.s); - - for (h_index = 0 ; h_index < d_table->size; h_index++) - { - entry = d_table->entries[h_index]; - dlg_to_term = entry.first; - for (; dlg_to_term;) - { - dlg = dlg_to_term->next ; - if (dlg_to_term->state == DLG_STATE_CONFIRMED) - { - unref_dlg(dlg_to_term, 1); - rpc_extra_hdrs = dfl_rpc_extra_hdrs; - dlg_terminate(dlg_to_term, NULL, &reason/*reason*/, 2, &rpc_extra_hdrs); - i_count++; - } - dlg_to_term = dlg; - } - } - LM_DBG("Terminated %d active dialogs from rpc call",i_count); + struct dlg_cell *dlg = NULL, *dlg_to_term = NULL; + dlg_entry_t entry; + + unsigned int i_count = 0, h_index = 0; + + str rpc_extra_hdrs = {0, 0}; + str dfl_rpc_extra_hdrs = {"Reason: mi_terminated\r\n", 23}; + str reason = {"mi_terminated", 12}; + + + if(!d_table) { + rpc->fault(c, 500, "Dialog hash table not initialized"); + return; + } + if(!d_table->size) + return; + + rpc_extra_hdrs = dfl_rpc_extra_hdrs; + LM_DBG("Setting reason to [%.*s] and extra headers to [%.*s]\n", reason.len, + reason.s, rpc_extra_hdrs.len, rpc_extra_hdrs.s); + + for(h_index = 0; h_index < d_table->size; h_index++) { + entry = d_table->entries[h_index]; + dlg_to_term = entry.first; + for(; dlg_to_term;) { + dlg = dlg_to_term->next; + if(dlg_to_term->state == DLG_STATE_CONFIRMED) { + unref_dlg(dlg_to_term, 1); + rpc_extra_hdrs = dfl_rpc_extra_hdrs; + dlg_terminate(dlg_to_term, NULL, &reason /*reason*/, 2, + &rpc_extra_hdrs); + i_count++; + } + dlg_to_term = dlg; + } + } + LM_DBG("Terminated %d active dialogs from rpc call", i_count); } static rpc_export_t rpc_methods[] = { - {"dlg2.list", rpc_print_dlgs, rpc_print_dlgs_doc, 0}, - {"dlg2.end_dlg", rpc_end_dlg_entry_id, rpc_end_dlg_entry_id_doc, 0}, - {"dlg2.end_all_active_dlg", rpc_end_all_active_dlg, rpc_end_all_active_dlg_doc, 0}, - {0, 0, 0, 0} -}; - + {"dlg2.list", rpc_print_dlgs, rpc_print_dlgs_doc, 0}, + {"dlg2.end_dlg", rpc_end_dlg_entry_id, rpc_end_dlg_entry_id_doc, 0}, + {"dlg2.end_all_active_dlg", rpc_end_all_active_dlg, + rpc_end_all_active_dlg_doc, 0}, + {0, 0, 0, 0}};