00001 /* 00002 * $Id: h_table.h,v 1.102 2009/01/05 21:26:44 bpintea Exp $ 00003 * 00004 * Copyright (C) 2001-2003 FhG Fokus 00005 * 00006 * This file is part of ser, a free SIP server. 00007 * 00008 * ser is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version 00012 * 00013 * For a license to use the ser software under conditions 00014 * other than those described here, or to purchase support for this 00015 * software, please contact iptel.org by e-mail at the following addresses: 00016 * info@iptel.org 00017 * 00018 * ser is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * You should have received a copy of the GNU General Public License 00024 * along with this program; if not, write to the Free Software 00025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00026 * 00027 * History: 00028 * -------- 00029 * 2003-03-16 removed _TOTAG (jiri) 00030 * 2003-03-06 we keep a list of 200/INV to-tags now (jiri) 00031 * 2003-03-01 kr set through a function now (jiri) 00032 * 2003-12-04 callbacks per transaction added; completion callback 00033 * merge into them as LOCAL_COMPETED (bogdan) 00034 * 2004-02-11 FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri) 00035 * 2004-02-13 t->is_invite, t->local, t->noisy_ctimer replaced 00036 * with flags (bogdan) 00037 * 2004-08-23 avp support added - avp list linked in transaction (bogdan) 00038 * 2005-11-03 updated to the new timer interface (dropped tm timers) (andrei) 00039 * 2006-08-11 dns failover support (andrei) 00040 * 2007-05-29 switch ref_count to atomic and delete a cell automatically on 00041 * UNREF if the ref_count reaches 0 (andrei) 00042 * 2007-06-01 support for different retransmissions intervals per transaction; 00043 * added maximum inv. and non-inv. transaction life time (andrei) 00044 * 2007-06-06 switched tm bucket list to a simpler and faster clist; 00045 * inlined often used functions (andrei) 00046 */ 00047 00048 #ifndef _H_TABLE_H 00049 #define _H_TABLE_H 00050 00051 #include "defs.h" 00052 #include "t_stats.h" 00053 00054 #define TM_DEL_UNREF 00055 /* uncomment the next define if you wish to keep hash statistics*/ 00056 /* 00057 #define TM_HASH_STATS 00058 */ 00059 /* use hash stats always in debug mode */ 00060 #ifdef EXTRA_DEBUG 00061 #ifndef TM_HASH_STATS 00062 #define TM_HASH_STATS 00063 #endif 00064 #endif 00065 00066 00067 #include "../../clist.h" 00068 #include "../../parser/msg_parser.h" 00069 #include "../../types.h" 00070 #include "../../md5utils.h" 00071 #include "../../usr_avp.h" 00072 #include "../../timer.h" 00073 #include "../../atomic_ops.h" 00074 #include "config.h" 00075 00076 /* if TM_DIFF_RT_TIMEOUT is defined, different retransmissions timeouts 00077 * can be used for each transaction, at a small memory cost 00078 * (extra 4 bytes/transaction) */ 00079 #define TM_DIFF_RT_TIMEOUT 00080 00081 00082 struct s_table; 00083 struct entry; 00084 struct cell; 00085 struct timer; 00086 struct retr_buf; 00087 00088 #include "../../mem/shm_mem.h" 00089 #include "lock.h" 00090 #include "sip_msg.h" 00091 #include "t_reply.h" 00092 #include "t_hooks.h" 00093 #ifdef USE_DNS_FAILOVER 00094 #include "../../dns_cache.h" 00095 #endif 00096 00097 00098 #define LOCK_HASH(_h) lock_hash((_h)) 00099 #define UNLOCK_HASH(_h) unlock_hash((_h)) 00100 00101 void lock_hash(int i); 00102 void unlock_hash(int i); 00103 00104 00105 #define NO_CANCEL ( (char*) 0 ) 00106 #define EXTERNAL_CANCEL ( (char*) -1) 00107 00108 #define TYPE_LOCAL_ACK -2 00109 #define TYPE_LOCAL_CANCEL -1 00110 #define TYPE_REQUEST 0 00111 00112 /* to be able to assess whether a script writer forgot to 00113 release a transaction and leave it for ever in memory, 00114 we mark it with operations done over it; if none of these 00115 flags is set and script is being left, it is a sign of 00116 script error and we need to release on writer's 00117 behalf 00118 00119 REQ_FWDED means there is a UAC with final response timer 00120 ticking. If it hits, transaction will be completed. 00121 REQ_RPLD means that a transaction has been replied -- either 00122 it implies going to wait state, or for invite transactions 00123 FR timer is ticking until ACK arrives 00124 REQ_RLSD means that a transaction was put on wait explicitly 00125 from t_release_transaction 00126 REQ_EXIST means that this request is a retransmission which does not 00127 affect transactional state 00128 REQ_ERR_DELAYED mean that tm wants to send reply(ser_error) but it 00129 delayed it to end-of-script to allow it to be overriden. 00130 If this is set and all of the above flag are not => send reply 00131 on end of script. If any of the above flags is set, do not 00132 send (especially REQ_RPLD and REQ_RLSD). 00133 */ 00134 enum kill_reason { REQ_FWDED=1, REQ_RPLD=2, REQ_RLSD=4, REQ_EXIST=8, 00135 REQ_ERR_DELAYED=16 }; 00136 00137 00138 /* #define F_RB_T_ACTIVE 0x01 (obsolete) fr or retr active */ 00139 #define F_RB_T2 0x02 00140 #define F_RB_RETR_DISABLED 0x04 /* retransmission disabled */ 00141 #define F_RB_FR_INV 0x08 /* timer switched to FR_INV */ 00142 #define F_RB_TIMEOUT 0x10 /* timeout */ 00143 #define F_RB_REPLIED 0x20 /* reply received */ 00144 #define F_RB_CANCELED 0x40 /* rb/branch canceled */ 00145 #define F_RB_DEL_TIMER 0x80 /* timer should be deleted if active */ 00146 #define F_RB_NH_LOOSE 0x100 /* next hop is a loose router */ 00147 #define F_RB_NH_STRICT 0x200 /* next hop is a strict router */ 00148 /* must detect when neither loose nor strict flag is set -> two flags. 00149 * alternatively, 1x flag for strict/loose and 1x for loose|strict set/not */ 00150 00151 00152 /* if canceled or intended to be canceled, return true */ 00153 #define uac_dont_fork(uac) ((uac)->local_cancel.buffer) 00154 00155 00156 typedef struct retr_buf 00157 { 00158 short activ_type; 00159 /* set to status code if the buffer is a reply, 00160 0 if request or -1 if local CANCEL */ 00161 volatile unsigned short flags; /* DISABLED, T2 */ 00162 volatile unsigned char t_active; /* timer active */ 00163 unsigned short branch; /* no more then 65k branches :-) */ 00164 short buffer_len; 00165 char *buffer; 00166 /*the cell that contains this retrans_buff*/ 00167 struct cell* my_T; 00168 struct timer_ln timer; 00169 struct dest_info dst; 00170 ticks_t retr_expire; 00171 ticks_t fr_expire; /* ticks value after which fr. will fire */ 00172 }retr_buf_type; 00173 00174 00175 00176 /* User Agent Server content */ 00177 00178 typedef struct ua_server 00179 { 00180 struct sip_msg *request; 00181 char *end_request; 00182 struct retr_buf response; 00183 /* keep to-tags for local 200 replies for INVITE -- 00184 * we need them for dialog-wise matching of ACKs; 00185 * the pointer shows to shmem-ed reply */ 00186 str local_totag; 00187 unsigned int status; 00188 }ua_server_type; 00189 00190 00191 00192 /* User Agent Client content */ 00193 00194 typedef struct ua_client 00195 { 00196 /* if we store a reply (branch picking), this is where it is */ 00197 struct sip_msg *reply; 00198 struct retr_buf request; 00199 /* we maintain a separate copy of cancel rather than 00200 reuse the structure for original request; the 00201 original request is no longer needed but its delayed 00202 timer may fire and interfere with whoever tries to 00203 rewrite it 00204 */ 00205 struct retr_buf local_cancel; 00206 /* pointer to retransmission buffer where uri is printed; 00207 good for generating ACK/CANCEL */ 00208 #ifdef USE_DNS_FAILOVER 00209 struct dns_srv_handle dns_h; 00210 #endif 00211 str uri; 00212 /* if we don't store, we at least want to know the status */ 00213 int last_received; 00214 #ifdef WITH_AS_SUPPORT 00215 00222 struct retr_buf *local_ack; 00223 #endif 00224 }ua_client_type; 00225 00226 00227 struct totag_elem { 00228 struct totag_elem *next; 00229 str tag; 00230 volatile int acked; 00231 }; 00232 00233 00234 00235 /* transaction's flags */ 00236 /* is the transaction's request an INVITE? */ 00237 #define T_IS_INVITE_FLAG (1<<0) 00238 /* is this a transaction generated by local request? */ 00239 #define T_IS_LOCAL_FLAG (1<<1) 00240 /* set to one if you want to disallow silent transaction 00241 dropping when C timer hits */ 00242 #define T_NOISY_CTIMER_FLAG (1<<2) 00243 /* transaction canceled 00244 * WARNING: this flag can be set outside reply lock from e2e_cancel(). 00245 * If a future flag could be affected by a race w/ e2e_cancel() the code 00246 * should be changed.*/ 00247 #define T_CANCELED (1<<3) 00248 /* 6xx received => stop forking */ 00249 #define T_6xx (1<<4) 00250 00251 #define T_IN_AGONY (1<<5) /* set if waiting to die (delete timer) 00252 TODO: replace it with del on unref */ 00253 #define T_AUTO_INV_100 (1<<6) /* send an 100 reply automatically to inv. */ 00254 #ifdef WITH_AS_SUPPORT 00255 /* don't generate automatically an ACK for local transaction */ 00256 # define T_NO_AUTO_ACK (1<<7) 00257 #endif 00258 #define T_DONT_FORK (T_CANCELED|T_6xx) 00259 00260 /* unsigned short should be enough for a retr. timer: max. 65535 ticks => 00261 * max retr. = 1023 s for tick = 15 ms, which should be more then enough and 00262 * saves us 2*2 bytes */ 00263 typedef unsigned short retr_timeout_t; 00264 00265 /* transaction context */ 00266 00267 typedef struct cell 00268 { 00269 /* linking data */ 00270 /* WARNING: don't move or change order of next_c or prev_c 00271 * or breakage will occur */ 00272 struct cell* next_c; 00273 struct cell* prev_c; 00274 /* tells in which hash table entry the cell lives */ 00275 unsigned int hash_index; 00276 /* sequence number within hash collision slot */ 00277 unsigned int label; 00278 /* different information about the transaction */ 00279 unsigned short flags; 00280 /* number of forks */ 00281 short nr_of_outgoings; 00282 00283 #ifdef TM_DEL_UNREF 00284 /* every time the transaction/cell is referenced from somewhere this 00285 * ref_count should be increased (via REF()) and every time the reference 00286 * is removed the ref_count should be decreased (via UNREF()). 00287 * This includes adding the cell to the hash table (REF() before adding) 00288 * and removing it from the hash table (UNREF_FREE() after unlinking). 00289 * Exception: it does not include starting/stopping timers (timers are 00290 * forced-stopped every time when ref_count reaches 0) 00291 * If the cell is no longer referenced (ref_count==0 after an UNREF), 00292 * it will be automatically deleted by the UNREF() operation. 00293 */ 00294 atomic_t ref_count; 00295 #else 00296 /* how many processes are currently processing this transaction ; 00297 note that only processes working on a request/reply belonging 00298 to a transaction increase ref_count -- timers don't, since we 00299 rely on transaction state machine to clean-up all but wait timer 00300 when entering WAIT state and the wait timer is the only place 00301 from which a transaction can be deleted (if ref_count==0); good 00302 for protecting from conditions in which wait_timer hits and 00303 tries to delete a transaction whereas at the same time 00304 a delayed message belonging to the transaction is received */ 00305 volatile unsigned int ref_count; 00306 #endif 00307 00308 /* needed for generating local ACK/CANCEL for local 00309 transactions; all but cseq_n include the entire 00310 header field value, cseq_n only Cseq number; with 00311 local transactions, pointers point to outbound buffer, 00312 with proxied transactions to inbound request */ 00313 str from, callid, cseq_n, to; 00314 /* method shortcut -- for local transactions, pointer to 00315 outbound buffer, for proxies transactions pointer to 00316 original message; needed for reply matching */ 00317 str method; 00318 00319 /* head of callback list */ 00320 struct tmcb_head_list tmcb_hl; 00321 00322 /* bindings to wait and delete timer */ 00323 struct timer_ln wait_timer; /* used also for delete */ 00324 00325 /* UA Server */ 00326 struct ua_server uas; 00327 /* UA Clients */ 00328 struct ua_client uac[ MAX_BRANCHES ]; 00329 00330 /* to-tags of 200/INVITEs which were received from downstream and 00331 * forwarded or passed to UAC; note that there can be arbitrarily 00332 * many due to downstream forking; */ 00333 struct totag_elem *fwded_totags; 00334 00335 /* list with avp */ 00336 struct usr_avp *uri_avps_from; 00337 struct usr_avp *uri_avps_to; 00338 struct usr_avp *user_avps_from; 00339 struct usr_avp *user_avps_to; 00340 struct usr_avp *domain_avps_from; 00341 struct usr_avp *domain_avps_to; 00342 00343 /* protection against concurrent reply processing */ 00344 ser_lock_t reply_mutex; 00345 00346 ticks_t fr_timeout; /* final response interval for retr_bufs */ 00347 ticks_t fr_inv_timeout; /* final inv. response interval for retr_bufs */ 00348 #ifdef TM_DIFF_RT_TIMEOUT 00349 retr_timeout_t rt_t1_timeout; /* start retr. interval for retr_bufs */ 00350 retr_timeout_t rt_t2_timeout; /* maximum retr. interval for retr_bufs */ 00351 #endif 00352 ticks_t end_of_life; /* maximum lifetime */ 00353 00354 /* nr of replied branch; 0..MAX_BRANCHES=branch value, 00355 * -1 no reply, -2 local reply */ 00356 short relayed_reply_branch; 00357 00358 /* the route to take if no final positive reply arrived */ 00359 unsigned short on_negative; 00360 /* the onreply_route to be processed if registered to do so */ 00361 unsigned short on_reply; 00362 /* The route to take for each downstream branch separately */ 00363 unsigned short on_branch; 00364 00365 /* place holder for MD5checksum (meaningful only if syn_branch=0) */ 00366 char md5[0]; /* if syn_branch==0 then MD5_LEN bytes are extra alloc'ed*/ 00367 00368 }cell_type; 00369 00370 00371 #if 0 00372 /* warning: padding too much => big size increase */ 00373 #define ENTRY_PAD_TO 128 /* should be a multiple of cacheline size for 00374 best performance*/ 00375 #define ENTRY_PAD_BYTES \ 00376 (ENTRY_PAD_TO-2*sizeof(struct cell*)+sizeof(ser_lock_t)+sizeof(int)+ \ 00377 2*sizeof(long)) 00378 #else 00379 #define ENTRY_PAD_BYTES 0 00380 #endif 00381 00382 /* double-linked list of cells with hash synonyms */ 00383 typedef struct entry 00384 { 00385 /* WARNING: don't move or change order of next_c or prev_c 00386 * or breakage will occur */ 00387 struct cell* next_c; 00388 struct cell* prev_c; 00389 /* sync mutex */ 00390 ser_lock_t mutex; 00391 /* currently highest sequence number in a synonym list */ 00392 unsigned int next_label; 00393 #ifdef TM_HASH_STATS 00394 unsigned long acc_entries; 00395 unsigned long cur_entries; 00396 #endif 00397 char _pad[ENTRY_PAD_BYTES]; 00398 }entry_type; 00399 00400 00401 00402 /* transaction table */ 00403 struct s_table 00404 { 00405 /* table of hash entries; each of them is a list of synonyms */ 00406 struct entry entries[ TABLE_ENTRIES ]; 00407 }; 00408 00409 /* pointer to the big table where all the transaction data 00410 lives */ 00411 struct s_table* _tm_table; /* private internal stuff, don't touch directly */ 00412 00413 #define list_entry(ptr, type, member) \ 00414 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 00415 00416 #define get_retr_timer_payload(_tl_) \ 00417 list_entry( _tl_, struct retr_buf, retr_timer) 00418 #define get_fr_timer_payload(_tl_) \ 00419 list_entry( _tl_, struct retr_buf, fr_timer) 00420 #define get_wait_timer_payload(_tl_) \ 00421 list_entry( _tl_, struct cell, wait_tl) 00422 #define get_dele_timer_payload(_tl_) \ 00423 list_entry( _tl_, struct cell, dele_tl) 00424 00425 #define get_T_from_reply_rb(_rb_) \ 00426 list_entry( list_entry( _rb_, (struct ua_server), response),\ 00427 struct cell, uas) 00428 #define get_T_from_request_rb(_rb_, _br_) \ 00429 list_entry( list_entry( (rb_, (struct ua_client), request) - \ 00430 (_br_)*sizeof(struct retr_buf), struct cell, uas) 00431 #define get_T_from_cancel_rb(_rb_, _br_) \ 00432 list_entry( list_entry( (rb_, (struct ua_client), local_cancel) - \ 00433 (_br_)*sizeof(struct retr_buf), struct cell, uas) 00434 00435 #define is_invite(_t_) ((_t_)->flags&T_IS_INVITE_FLAG) 00436 #define is_local(_t_) ((_t_)->flags&T_IS_LOCAL_FLAG) 00437 #define has_noisy_ctimer(_t_) ((_t_)->flags&T_NOISY_CTIMER_FLAG) 00438 00439 00440 void reset_kr(); 00441 void set_kr( enum kill_reason kr ); 00442 enum kill_reason get_kr(); 00443 00444 #define get_tm_table() (_tm_table) 00445 00446 struct s_table* init_hash_table(); 00447 void free_hash_table( ); 00448 void free_cell( struct cell* dead_cell ); 00449 struct cell* build_cell( struct sip_msg* p_msg ); 00450 00451 #ifdef TM_HASH_STATS 00452 unsigned int transaction_count( void ); 00453 #endif 00454 00455 00456 /* Takes an already created cell and links it into hash table on the 00457 * appropriate entry. */ 00458 inline static void insert_into_hash_table_unsafe( struct cell * p_cell, 00459 unsigned int hash ) 00460 { 00461 p_cell->label = _tm_table->entries[hash].next_label++; 00462 #ifdef EXTRA_DEBUG 00463 DEBUG("cell label: %u\n", p_cell->label); 00464 #endif 00465 p_cell->hash_index=hash; 00466 /* insert at the beginning */ 00467 clist_insert(&_tm_table->entries[hash], p_cell, next_c, prev_c); 00468 00469 /* update stats */ 00470 #ifdef TM_HASH_STATS 00471 _tm_table->entries[hash].cur_entries++; 00472 _tm_table->entries[hash].acc_entries++; 00473 #endif 00474 t_stats_new( is_local(p_cell) ); 00475 } 00476 00477 00478 00479 /* Un-link a cell from hash_table, but the cell itself is not released */ 00480 inline static void remove_from_hash_table_unsafe( struct cell * p_cell) 00481 { 00482 clist_rm(p_cell, next_c, prev_c); 00483 # ifdef EXTRA_DEBUG 00484 #ifdef TM_HASH_STATS 00485 if (_tm_table->entries[p_cell->hash_index].cur_entries==0){ 00486 LOG(L_CRIT, "BUG: bad things happened: cur_entries=0\n"); 00487 abort(); 00488 } 00489 #endif 00490 # endif 00491 #ifdef TM_HASH_STATS 00492 _tm_table->entries[p_cell->hash_index].cur_entries--; 00493 #endif 00494 t_stats_deleted( is_local(p_cell) ); 00495 } 00496 00497 #endif 00498 00499
1.3.9.1