Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00049 #ifndef _H_TABLE_H
00050 #define _H_TABLE_H
00051
00052 #include "defs.h"
00053 #include "t_stats.h"
00054
00055 #define TM_DEL_UNREF
00056
00057
00058
00059
00060
00061 #ifdef EXTRA_DEBUG
00062 #ifndef TM_HASH_STATS
00063 #define TM_HASH_STATS
00064 #endif
00065 #endif
00066
00067
00068 #include "../../clist.h"
00069 #include "../../parser/msg_parser.h"
00070 #include "../../types.h"
00071 #include "../../md5utils.h"
00072 #include "../../usr_avp.h"
00073 #ifdef WITH_XAVP
00074 #include "../../xavp.h"
00075 #endif
00076 #include "../../timer.h"
00077 #include "../../flags.h"
00078 #include "../../atomic_ops.h"
00079 #include "../../hash_func.h"
00080 #include "config.h"
00081
00082
00083
00084
00085 #define TM_DIFF_RT_TIMEOUT
00086
00087
00088 struct s_table;
00089 struct entry;
00090 struct cell;
00091 struct timer;
00092 struct retr_buf;
00093 struct ua_client;
00094
00095 #include "../../mem/shm_mem.h"
00096 #include "lock.h"
00097 #include "sip_msg.h"
00098 #include "t_reply.h"
00099 #include "t_hooks.h"
00100 #ifdef USE_DNS_FAILOVER
00101 #include "../../dns_cache.h"
00102 #endif
00103
00104
00105 #define LOCK_HASH(_h) lock_hash((_h))
00106 #define UNLOCK_HASH(_h) unlock_hash((_h))
00107
00108 void lock_hash(int i);
00109 void unlock_hash(int i);
00110
00111
00112 #define NO_CANCEL ( (char*) 0 )
00113 #define EXTERNAL_CANCEL ( (char*) -1)
00114
00115 #define TYPE_LOCAL_ACK -2
00116 #define TYPE_LOCAL_CANCEL -1
00117 #define TYPE_REQUEST 0
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 enum kill_reason { REQ_FWDED=1, REQ_RPLD=2, REQ_RLSD=4, REQ_EXIST=8,
00142 REQ_ERR_DELAYED=16 };
00143
00144
00145
00146 #define F_RB_T2 0x02
00147 #define F_RB_RETR_DISABLED 0x04
00148 #define F_RB_FR_INV 0x08
00149 #define F_RB_TIMEOUT 0x10
00150 #define F_RB_REPLIED 0x20
00151 #define F_RB_CANCELED 0x40
00152 #define F_RB_DEL_TIMER 0x80
00153 #define F_RB_NH_LOOSE 0x100
00154 #define F_RB_NH_STRICT 0x200
00155
00156
00157
00158
00159
00160 #define uac_dont_fork(uac) ((uac)->local_cancel.buffer)
00161
00162
00163 typedef struct retr_buf
00164 {
00165 short activ_type;
00166
00167
00168 volatile unsigned short flags;
00169 volatile unsigned char t_active;
00170 unsigned short branch;
00171 int buffer_len;
00172 char *buffer;
00173
00174 struct cell* my_T;
00175 struct timer_ln timer;
00176 struct dest_info dst;
00177 ticks_t retr_expire;
00178 ticks_t fr_expire;
00179 }retr_buf_type;
00180
00181
00182
00183
00184
00185 typedef struct ua_server
00186 {
00187 struct sip_msg *request;
00188 char *end_request;
00189 struct retr_buf response;
00190
00191
00192
00193 str local_totag;
00194 #ifdef CANCEL_REASON_SUPPORT
00195 struct cancel_reason* cancel_reas;
00196
00197 #endif
00198 unsigned int status;
00199 }ua_server_type;
00200
00201
00202
00203
00204
00205 #define TM_UAC_FLAGS
00206 #ifdef TM_UAC_FLAGS
00207
00208 #define TM_UAC_FLAG_RR 1
00209 #define TM_UAC_FLAG_R2 2
00210 #define TM_UAC_FLAG_FB 4
00211 #endif
00212
00213 typedef struct ua_client
00214 {
00215
00216 struct sip_msg *reply;
00217 struct retr_buf request;
00218
00219
00220
00221
00222
00223
00224 struct retr_buf local_cancel;
00225
00226
00227 #ifdef USE_DNS_FAILOVER
00228 struct dns_srv_handle dns_h;
00229 #endif
00230 str uri;
00231 str path;
00232
00233 int last_received;
00234
00235 #ifdef TM_UAC_FLAGS
00236
00237 unsigned int flags;
00238 #endif
00239 flag_t branch_flags;
00240 #ifdef WITH_AS_SUPPORT
00241
00248 struct retr_buf *local_ack;
00249 #endif
00250 }ua_client_type;
00251
00252
00253 struct totag_elem {
00254 struct totag_elem *next;
00255 str tag;
00256 volatile int acked;
00257 };
00258
00259
00260
00261
00262
00263 #define T_IS_INVITE_FLAG (1<<0)
00264
00265 #define T_IS_LOCAL_FLAG (1<<1)
00266
00267
00268 #define T_NOISY_CTIMER_FLAG (1<<2)
00269
00270
00271
00272
00273 #define T_CANCELED (1<<3)
00274
00275 #define T_6xx (1<<4)
00276
00277 #define T_IN_AGONY (1<<5)
00278
00279 #define T_AUTO_INV_100 (1<<6)
00280 #ifdef WITH_AS_SUPPORT
00281
00282 # define T_NO_AUTO_ACK (1<<7)
00283 #endif
00284
00285 #define T_DISABLE_6xx (1<<8)
00286 #define T_DISABLE_FAILOVER (1<<9)
00287 #ifdef CANCEL_REASON_SUPPORT
00288 #define T_NO_E2E_CANCEL_REASON (1<<10)
00289 #endif
00290 #define T_DONT_FORK (T_CANCELED|T_6xx)
00291
00292 #ifdef WITH_AS_SUPPORT
00293
00294 # define T_PASS_PROVISIONAL_FLAG (1<<11)
00295 # define pass_provisional(_t_) ((_t_)->flags&T_PASS_PROVISIONAL_FLAG)
00296 #endif
00297
00298
00299
00300 typedef unsigned short retr_timeout_t;
00301
00305 typedef struct tm_xdata
00306 {
00307
00308 struct usr_avp *uri_avps_from;
00309 struct usr_avp *uri_avps_to;
00310 struct usr_avp *user_avps_from;
00311 struct usr_avp *user_avps_to;
00312 struct usr_avp *domain_avps_from;
00313 struct usr_avp *domain_avps_to;
00314 #ifdef WITH_XAVP
00315 sr_xavp_t *xavps_list;
00316 #endif
00317 } tm_xdata_t;
00318
00319
00323 typedef struct tm_xlinks
00324 {
00325
00326 struct usr_avp **uri_avps_from;
00327 struct usr_avp **uri_avps_to;
00328 struct usr_avp **user_avps_from;
00329 struct usr_avp **user_avps_to;
00330 struct usr_avp **domain_avps_from;
00331 struct usr_avp **domain_avps_to;
00332 #ifdef WITH_XAVP
00333 sr_xavp_t **xavps_list;
00334 #endif
00335 } tm_xlinks_t;
00336
00337
00338
00339
00340 typedef struct cell
00341 {
00342
00343
00344
00345 struct cell* next_c;
00346 struct cell* prev_c;
00347
00348 unsigned int hash_index;
00349
00350 unsigned int label;
00351
00352 unsigned short flags;
00353
00354 short nr_of_outgoings;
00355
00356 #ifdef TM_DEL_UNREF
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 atomic_t ref_count;
00368 #else
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 volatile unsigned int ref_count;
00379 #endif
00380
00381
00382
00383
00384
00385
00386 str from, callid, cseq_n, to;
00387
00388
00389
00390 str method;
00391
00392
00393 struct tmcb_head_list tmcb_hl;
00394
00395
00396 struct timer_ln wait_timer;
00397
00398
00399 struct ua_server uas;
00400
00401 struct ua_client uac[ MAX_BRANCHES ];
00402
00403
00404
00405
00406 struct totag_elem *fwded_totags;
00407
00408
00409 struct usr_avp *uri_avps_from;
00410 struct usr_avp *uri_avps_to;
00411 struct usr_avp *user_avps_from;
00412 struct usr_avp *user_avps_to;
00413 struct usr_avp *domain_avps_from;
00414 struct usr_avp *domain_avps_to;
00415 #ifdef WITH_XAVP
00416 sr_xavp_t *xavps_list;
00417 #endif
00418
00419
00420 ser_lock_t reply_mutex;
00421
00422 ticks_t fr_timeout;
00423 ticks_t fr_inv_timeout;
00424 #ifdef TM_DIFF_RT_TIMEOUT
00425 retr_timeout_t rt_t1_timeout_ms;
00426 retr_timeout_t rt_t2_timeout_ms;
00427 #endif
00428 ticks_t end_of_life;
00429
00430
00431
00432 short relayed_reply_branch;
00433
00434
00435 unsigned short on_negative;
00436
00437 unsigned short on_reply;
00438
00439 unsigned short on_branch;
00440
00441
00442 char md5[0];
00443
00444 } tm_cell_t;
00445
00446
00447 #if 0
00448
00449 #define ENTRY_PAD_TO 128
00450
00451 #define ENTRY_PAD_BYTES \
00452 (ENTRY_PAD_TO-2*sizeof(struct cell*)+sizeof(ser_lock_t)+sizeof(int)+ \
00453 2*sizeof(long))
00454 #else
00455 #define ENTRY_PAD_BYTES 0
00456 #endif
00457
00458
00459 typedef struct entry
00460 {
00461
00462
00463 struct cell* next_c;
00464 struct cell* prev_c;
00465
00466 ser_lock_t mutex;
00467 atomic_t locker_pid;
00468 int rec_lock_level;
00469
00470 unsigned int next_label;
00471 #ifdef TM_HASH_STATS
00472 unsigned long acc_entries;
00473 unsigned long cur_entries;
00474 #endif
00475 char _pad[ENTRY_PAD_BYTES];
00476 }entry_type;
00477
00478
00479
00480
00481 struct s_table
00482 {
00483
00484 struct entry entries[ TABLE_ENTRIES ];
00485 };
00486
00487
00488
00489 extern struct s_table* _tm_table;
00490
00491
00492 #define list_entry(ptr, type, member) \
00493 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
00494
00495 #define get_retr_timer_payload(_tl_) \
00496 list_entry( _tl_, struct retr_buf, retr_timer)
00497 #define get_fr_timer_payload(_tl_) \
00498 list_entry( _tl_, struct retr_buf, fr_timer)
00499 #define get_wait_timer_payload(_tl_) \
00500 list_entry( _tl_, struct cell, wait_tl)
00501 #define get_dele_timer_payload(_tl_) \
00502 list_entry( _tl_, struct cell, dele_tl)
00503
00504 #define get_T_from_reply_rb(_rb_) \
00505 list_entry( list_entry( _rb_, (struct ua_server), response),\
00506 struct cell, uas)
00507 #define get_T_from_request_rb(_rb_, _br_) \
00508 list_entry( list_entry( (rb_, (struct ua_client), request) - \
00509 (_br_)*sizeof(struct retr_buf), struct cell, uas)
00510 #define get_T_from_cancel_rb(_rb_, _br_) \
00511 list_entry( list_entry( (rb_, (struct ua_client), local_cancel) - \
00512 (_br_)*sizeof(struct retr_buf), struct cell, uas)
00513
00514 #define is_invite(_t_) ((_t_)->flags&T_IS_INVITE_FLAG)
00515 #define is_local(_t_) ((_t_)->flags&T_IS_LOCAL_FLAG)
00516 #define has_noisy_ctimer(_t_) ((_t_)->flags&T_NOISY_CTIMER_FLAG)
00517 #define was_cancelled(_t_) ((_t_)->flags&T_CANCELED)
00518 #define no_new_branches(_t_) ((_t_)->flags&T_6xx)
00519
00520
00521 void reset_kr(void);
00522 void set_kr( enum kill_reason kr );
00523 enum kill_reason get_kr(void);
00524
00525 #define get_tm_table() (_tm_table)
00526
00527 typedef struct s_table* (*tm_get_table_f)(void);
00528 struct s_table* tm_get_table(void);
00529
00530 struct s_table* init_hash_table(void);
00531 void free_hash_table(void);
00532 void free_cell( struct cell* dead_cell );
00533 struct cell* build_cell( struct sip_msg* p_msg );
00534
00535 #ifdef TM_HASH_STATS
00536 unsigned int transaction_count( void );
00537 #endif
00538
00539
00540
00541
00542 inline static void insert_into_hash_table_unsafe( struct cell * p_cell,
00543 unsigned int hash )
00544 {
00545 p_cell->label = _tm_table->entries[hash].next_label++;
00546 #ifdef EXTRA_DEBUG
00547 DEBUG("cell label: %u\n", p_cell->label);
00548 #endif
00549 p_cell->hash_index=hash;
00550
00551 clist_insert(&_tm_table->entries[hash], p_cell, next_c, prev_c);
00552
00553
00554 #ifdef TM_HASH_STATS
00555 _tm_table->entries[hash].cur_entries++;
00556 _tm_table->entries[hash].acc_entries++;
00557 #endif
00558 t_stats_new( is_local(p_cell) );
00559 }
00560
00561
00562
00563
00564 inline static void remove_from_hash_table_unsafe( struct cell * p_cell)
00565 {
00566 clist_rm(p_cell, next_c, prev_c);
00567 # ifdef EXTRA_DEBUG
00568 #ifdef TM_HASH_STATS
00569 if (_tm_table->entries[p_cell->hash_index].cur_entries==0){
00570 LOG(L_CRIT, "BUG: bad things happened: cur_entries=0\n");
00571 abort();
00572 }
00573 #endif
00574 # endif
00575 #ifdef TM_HASH_STATS
00576 _tm_table->entries[p_cell->hash_index].cur_entries--;
00577 #endif
00578 t_stats_deleted( is_local(p_cell) );
00579 }
00580
00584 void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode);
00585
00586 void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd);
00587
00588 #endif
00589
00590