modules/tm/t_hooks.h
3881f12c
 /*
84d8e165
  * Copyright (C) 2001-2003 FhG Fokus
7dd0b342
  *
f1b15228
  * This file is part of Kamailio, a free SIP server.
7dd0b342
  *
f1b15228
  * Kamailio is free software; you can redistribute it and/or modify
7dd0b342
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
f1b15228
  * Kamailio is distributed in the hope that it will be useful,
7dd0b342
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
97625845
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
851f8e6f
  *
3881f12c
  */
 
7dd0b342
 
3881f12c
 #ifndef _HOOKS_H
 #define _HOOKS_H
 
ff979952
 #include "defs.h"
 
3f779a66
 /* TMCB_ONSEND used to enable certain callback-related features when
  * ONSEND was set, these days it's always enabled. For compatibility
  * reasons with modules that check ONSEND, continue to set it
  * unconditionally*/
9217a640
 #define TMCB_ONSEND
 #include "../../ip_addr.h" /* dest_info */
 
caf80ae6
 struct sip_msg;
 struct cell;
3881f12c
 
97625845
 #define TMCB_REQUEST_IN_N       0
 #define TMCB_RESPONSE_IN_N      1
 #define TMCB_E2EACK_IN_N        2
d21983e8
 #define TMCB_REQUEST_PENDING_N  3
 #define TMCB_REQUEST_FWDED_N    4
 #define TMCB_RESPONSE_FWDED_N   5
 #define TMCB_ON_FAILURE_RO_N    6
 #define TMCB_ON_FAILURE_N       7
 #define TMCB_REQUEST_OUT_N      8
 #define TMCB_RESPONSE_OUT_N     9
 #define TMCB_LOCAL_COMPLETED_N  10
 #define TMCB_LOCAL_RESPONSE_OUT_N 11
 #define TMCB_ACK_NEG_IN_N       12
 #define TMCB_REQ_RETR_IN_N      13
 #define TMCB_LOCAL_RESPONSE_IN_N 14
 #define TMCB_LOCAL_REQUEST_IN_N  15
 #define TMCB_DLG_N              16
 #define TMCB_DESTROY_N          17  /* called on transaction destroy */
 #define TMCB_E2ECANCEL_IN_N     18
 #define TMCB_E2EACK_RETR_IN_N   19
 #define TMCB_RESPONSE_READY_N	20
d65cdd3f
 #ifdef WITH_AS_SUPPORT
d21983e8
 #define TMCB_DONT_ACK_N         21 /* TM shoudn't ACK a local UAC  */
d65cdd3f
 #endif
d21983e8
 #define TMCB_REQUEST_SENT_N     22
 #define TMCB_RESPONSE_SENT_N    23
4e0cf550
 #define TMCB_ON_BRANCH_FAILURE_RO_N 24
 #define TMCB_ON_BRANCH_FAILURE_N 25
 #define TMCB_MAX_N              25
a70eb298
 
562b6d06
 
97625845
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
 #define TMCB_RESPONSE_IN      (1<<TMCB_RESPONSE_IN_N)
 #define TMCB_E2EACK_IN        (1<<TMCB_E2EACK_IN_N)
d21983e8
 #define TMCB_REQUEST_PENDING  (1<<TMCB_REQUEST_PENDING_N)
97625845
 #define TMCB_REQUEST_FWDED    (1<<TMCB_REQUEST_FWDED_N)
 #define TMCB_RESPONSE_FWDED   (1<<TMCB_RESPONSE_FWDED_N)
 #define TMCB_ON_FAILURE_RO    (1<<TMCB_ON_FAILURE_RO_N)
 #define TMCB_ON_FAILURE       (1<<TMCB_ON_FAILURE_N)
843cf2f4
 #define TMCB_REQUEST_OUT      (1<<TMCB_REQUEST_OUT_N)
97625845
 #define TMCB_RESPONSE_OUT     (1<<TMCB_RESPONSE_OUT_N)
 #define TMCB_LOCAL_COMPLETED  (1<<TMCB_LOCAL_COMPLETED_N)
 #define TMCB_LOCAL_RESPONSE_OUT (1<<TMCB_LOCAL_RESPONSE_OUT_N)
1b8b2899
 #define TMCB_ACK_NEG_IN       (1<<TMCB_ACK_NEG_IN_N)
 #define TMCB_REQ_RETR_IN      (1<<TMCB_REQ_RETR_IN_N)
 #define TMCB_LOCAL_RESPONSE_IN (1<<TMCB_LOCAL_RESPONSE_IN_N)
5c953757
 #define TMCB_LOCAL_REQUEST_IN (1<<TMCB_LOCAL_REQUEST_IN_N)
0277f618
 #define TMCB_DLG              (1<<TMCB_DLG_N)
562b6d06
 #define TMCB_DESTROY          (1<<TMCB_DESTROY_N)
6776abcd
 #define TMCB_E2ECANCEL_IN     (1<<TMCB_E2ECANCEL_IN_N)
89f03bcf
 #define TMCB_E2EACK_RETR_IN   (1<<TMCB_E2EACK_RETR_IN_N)
f1c35c13
 #define TMCB_RESPONSE_READY   (1<<TMCB_RESPONSE_READY_N)
d65cdd3f
 #ifdef WITH_AS_SUPPORT
 #define TMCB_DONT_ACK         (1<<TMCB_DONT_ACK_N)
 #endif
9217a640
 #define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
 #define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
4e0cf550
 #define TMCB_ON_BRANCH_FAILURE (1<<TMCB_ON_BRANCH_FAILURE_N)
 #define TMCB_ON_BRANCH_FAILURE_RO (1<<TMCB_ON_BRANCH_FAILURE_RO_N)
97625845
 #define TMCB_MAX              ((1<<(TMCB_MAX_N+1))-1)
b5f0a0b6
 
97625845
 
 /*
fde02f64
  *  Caution: most of the callbacks work with shmem-ized messages
  *  which you can no more change (e.g., lumps are fixed). Most
  *  reply-processing callbacks are also called from a mutex,
  *  which may cause deadlock if you are not careful. Also, reply
  *  callbacks may pass the value of FAKED_REPLY messages, which
  *  is a non-dereferencable pointer indicating that no message
  *  was received and a timer hit instead.
  *
a70eb298
  *  All callbacks excepting the TMCB_REQUEST_IN are associates to a
  *  transaction. It means they will be run only when the event will hint
  *  the transaction the callbacks were register for.
  *  TMCB_REQUEST_IN is a global callback - it means it will be run for
  *  all transactions.
  *
  *
fde02f64
  *  Callback description:
  *  ---------------------
  *
  * TMCB_REQUEST_IN -- a brand-new request was received and is
  * about to establish transaction; it is not yet cloned and
  * lives in pkg mem -- your last chance to mangle it before
  * it gets shmem-ized (then, it's read-only); it's called from
  * HASH_LOCK, so be careful. It is guaranteed not to be
b2fcef3c
  * a retransmission. The transactional context is mostly
  * incomplete -- this callback is called in very early stage
  * before the message is shmem-ized (so that you can work
  * with it).
a2e8301b
  * Note: this callback MUST be installed before forking
  * (the req_in_tmcb_hl callback list does not live in shmem and has no access
  * protection), i.e., at best from mod_init functions.
  *
09b7b0b3
  * Note: All the other callbacks can be safely installed when the
  * transaction already exists, it does not need to be locked.
  * 
fde02f64
  * TMCB_RESPONSE_IN -- a brand-new reply was received which matches
a2e8301b
  * an existing non-local transaction. It may or may not be a retransmission.
  * No lock is held here (yet).
66298eb4
  * Note: for an invite transaction this callback will also catch the reply
  *  to local cancels (e.g. branch canceled due to fr_inv_timeout). To
  *  distinguish between the two, one would need to look at the method in
  *  Cseq (look at t_reply.c:1630 (reply_received()) for an example).
fde02f64
  *
89bfe93c
  *  TMCB_RESPONSE_OUT -- a final or provisional reply was sent out
  *  successfully (either a local reply  or a proxied one).
  *  For final replies is called only for the first one (it's not called
  *  for retransmissions).
  *  For non-local replies (proxied) is called also for provisional responses
  *  (NOTE: this might change and in the future it might be called only
  *  for final replies --andrei).
  *  For local replies is called _only_ for the final reply.
  *  There is nothing more you can change from the callback, it is good for 
  *  accounting-like uses. No lock is held.
  *  Known oddities: it's called for provisional replies for relayed replies,
  *  but not for local responses (see NOTE above).
  *  Note: if the send fails or via cannot be resolved, this callback is 
  *  _not_ called.
  *  Note: local reply means locally generated reply (via t_reply() & friends)
  *  and not local transaction.
  *
  *    Note: the message passed to the callback may also have
fde02f64
  *    value FAKED_REPLY (like other reply callbacks) which
89bfe93c
  *    indicates a local reply caused by a timer, calling t_reply() a.s.o.
 *     Check for this value before deferring -- you will cause a segfault
b8933b58
  *    otherwise. Check for t->uas.request validity too if you
  *    need it ... locally initiated UAC transactions set it to 0.
fde02f64
  *
851f8e6f
  *    Also note, that reply callbacks are not called if a transaction
  *    is dropped silently. That's the case when noisy_ctimer is
  *    disabled (by default) and C-timer hits. The proxy server then
  *    drops state silently, doesn't use callbacks and expects the
  *    transaction to complete statelessly.
  *
a70eb298
  *  TMCB_ON_FAILURE_RO -- called on receipt of a reply or timer;
97625845
  *  it means all branches completed with a failure; the callback
a70eb298
  *  function MUST not change anything in the transaction (READONLY)
  *  that's a chance for doing ACC or stuff like this
  *
fde02f64
  *  TMCB_ON_FAILURE -- called on receipt of a reply or timer;
97625845
  *  it means all branches completed with a failure; that's
a2e8301b
  *  a chance for example to add new transaction branches.
  *  WARNING: the REPLY lock is held.
  *  It is safe to add more callbacks from here.
fde02f64
  *
  *  TMCB_RESPONSE_FWDED -- called when a reply is about to be
  *  forwarded; it is called after a message is received but before
97625845
  *  a message is sent out: it is called when the decision is
  *  made to forward a reply; it is parametrized by pkg message
  *  which caused the transaction to complete (which is not
fde02f64
  *  necessarily the same which will be forwarded). As forwarding
84d8e165
  *  has not been executed and may fail, there is no guarantee
  *  a reply will be successfully sent out at this point of time.
fde02f64
  *
a2e8301b
  *     Note: TMCB_ON_FAILURE and TMCB_REPLY_FWDED are
fde02f64
  *     called from reply mutex which is used to deterministically
  *     process multiple replies received in parallel. A failure
  *     to set the mutex again or stay too long in the callback
  *     may result in deadlock.
  *
  *     Note: the reply callbacks will not be evoked if "silent
  *     C-timer hits". That's a feature to clean transactional
  *     state from a proxy quickly -- transactions will then
  *     complete statelessly. If you wish to disable this
  *     feature, either set the global option "noisy_ctimer"
  *     to 1, or set t->noisy_ctimer for selected transaction.
  *
  *  TMCB_E2EACK_IN -- called when an ACK belonging to a proxied
  *  INVITE transaction completed with 200 arrived. Note that
  *  because it can be only dialog-wise matched, only the first
84d8e165
  *  transaction occurrence will be matched with spirals. If
fde02f64
  *  record-routing is not enabled, you will never receive the
a2e8301b
  *  ACK and the callback will be never triggered. In general it's called only
  *   for the first ACK but it can be also called multiple times 
  *   quasi-simultaneously if multiple ACK copies arrive in parallel or if
  *   ACKs with different (never seen before) to-tags are received.
fde02f64
  *
89f03bcf
  *   TMCB_E2EACK_RETR_IN -- like TMCB_E2EACK_IN, but matches retransmissions
  *   and it's called for every retransmission (but not for the "first" ACK).
  *
6aa46ec4
  *  TMCB_E2ECANCEL_IN -- called when a CANCEL for the INVITE transaction
  *  for which the callback was registered arrives.
75adc3ac
  *   The transaction parameter will point to the invite transaction (and 
  *   not the cancel) and the request parameter to the CANCEL sip msg.
6776abcd
  *   Note: the callback should be registered for an INVITE transaction.
32b645a4
  *
97625845
  *  TMCB_REQUEST_FWDED -- request is being forwarded out. It is
a2e8301b
  *  called before a message is forwarded, when the corresponding branch
  *   is created (it's called for each branch) and it is your last
  *  chance to change its shape. It can also be called from the failure
  *   router (via t_relay/t_forward_nonack) and in this case the REPLY lock 
  *   will be held.
  *
843cf2f4
  *  TMCB_REQUEST_OUT -- request was sent out successfully.
  *  There is nothing more you can change from the callback, it is good for
  *  accounting-like uses.
  *  Note: if the send fails or via cannot be resolved, this callback is
  *  _not_ called.
  *
a2e8301b
  *  TMCB_LOCAL_COMPLETED -- final reply for localy initiated
  *  transaction arrived. Message may be FAKED_REPLY. Can be called multiple
  *  times, no lock is held.
  *
89bfe93c
  *  TMCB_LOCAL_RESPONSE_OUT -- provisional reply for localy initiated 
a2e8301b
  *  transaction. The message may be a FAKED_REPLY and the callback might be 
  *  called multiple time quasi-simultaneously. No lock is held.
89bfe93c
  *  Note: depends on tm.pass_provisional_replies.
  *  Note: the name is very unfortunate and it will probably be changed
  *   (e.g. TMCB_LOCAL_PROVISIONAL).
fde02f64
  *
1b8b2899
  *  TMCB_NEG_ACK_IN -- an ACK to a negative reply was received, thus ending
  *  the transaction (this happens only when the final reply sent by tm is 
  *  negative). The callback might be called simultaneously. No lock is held.
  *
  *  TMCB_REQ_RETR_IN -- a retransmitted request was received. This callback
  *   might be called simultaneously. No lock is held.
  *
  * TMCB_LOCAL_RESPONSE_IN -- a brand-new reply was received which matches
  * an existing local transaction (like TMCB_RESPONSE_IN but for local 
  * transactions). It may or may not be a retransmission.
9217a640
  *
5c953757
  * TMCB_LOCAL_REQUEST_IN -- like TMCB_REQUEST_IN but for locally generated 
  * request (e.g. via fifo/rpc):  a brand-new local request was 
  * received/generated and a transaction for it is about to be created.
  * It's called from HASH_LOCK, so be careful. It is guaranteed not to be
  * a retransmission. The transactional context is mostly
  * incomplete -- this callback is called in very early stage
  * before the message is shmem-ized (so that you can work
  * with it).
  * It's safe to install other TMCB callbacks from here.
  * Note: this callback MUST be installed before forking
  * (the local_req_in_tmcb_hl callback list does not live in shmem and has no 
  * access protection), i.e., at best from mod_init functions.
  *
  *
9217a640
  *  All of the following callbacks are called immediately after or before 
  *  sending a message. All of them are read-only (no change can be made to
  * the message). These callbacks use the t_rbuf, send_buf, dst, is_retr
  *  and the code members of the tmcb_params structure.
  *  For a request code is <=0. code values can be TYPE_LOCAL_ACK for an ACK 
  *  generated by ser, TYPE_LOCAL_CANCEL for a CANCEL generated by ser 
  *  and TYPE_REQUEST for all the other requests or requests generated via 
  *  t_uac.
  *   For a reply the code is the response status (which is always >0, e.g. 200,
  *   408, a.s.o).
  *        - the callbacks will be called sometimes with the REPLY lock held
  *          and sometimes without it, so trying to acquire the REPLY lock
  *          from these callbacks could lead to deadlocks (avoid it unless
  *           you really know what you're doing).
  *
3f779a66
  *  TMCB_REQUEST_SENT -- called each time a request was sent (even for
68017b5d
  *  retransmissions), it includes local and forwarded request, ser generated
3f779a66
  *  CANCELs and ACKs. The tmcb_params structure will have the t_rbuf, dst,
  *  send_buf and is_retr members filled.
9217a640
  *  This callback is "read-only", the message was already sent and no changes
  *  are allowed.
  *  Note: send_buf can be different from t_rbuf->buffer for ACKs (in this
  *   case t_rbuf->buf will contain the last request sent on the branch and
  *   its destination). The same goes for t_rbuf->dst and tmcb->dst for local 
  *   transactions ACKs to 2xxs.
  *
3f779a66
  *  TMCB_RESPONSE_SENT -- called each time a response was sent (even for
  *  retransmissions). The tmcb_params structure will have t_rbuf set to the
  *  reply retransmission buffer and send_buf set to the data sent (in this case
  *  it will always be the same with t_rbuf->buf). is_retr will also be set if
  *  the reply is retransmitted
9217a640
  *   by ser.
  *  This callback is "read-only", the message was already sent and no changes
  *  are allowed.
fde02f64
  *
562b6d06
  *  TMCB_DESTROY -- called when the transaction is destroyed. Everything but
  *  the cell* parameter (t) and the tmcb are set to 0. Only the param is
  *  is filled inside TMCB. For dialogs callbacks t is also 0.
  *
f1c35c13
  * TMCB_RESPONSE_READY -- a reply is ready to be sent out. Callback is
  *  is executed just before writing the reply content to network.
d65cdd3f
  *
  * TMCB_DONT_ACK (requires AS support) -- for localy generated INVITEs, TM 
  * automatically generates an ACK for the received 2xx replies. But, if this 
  * flag is passed to TM when creating the initial UAC request, this won't
  * happen anymore: the ACK generation must be triggered from outside, using
  * TM's interface.
  * While this isn't exactly a callback type, it is used as part of the flags
  * mask when registering callbacks.
caf80ae6
 
a70eb298
 	the callback's param MUST be in shared memory and will
 	NOT be freed by TM; you must do it yourself from the
562b6d06
 	callback function if necessary (for example register it also for 
 	 TMCB_DESTROY and when called with TMCB_DESTROY just free the param
 	).
b5f0a0b6
 */
3881f12c
 
ad997592
 #define TMCB_RETR_F 1
 #define TMCB_LOCAL_F 2
3881f12c
 
84d8e165
 /* pack structure with all params passed to callback function */
a70eb298
 struct tmcb_params {
 	struct sip_msg* req;
 	struct sip_msg* rpl;
3c6c6f9c
 	void **param;
07766395
 	int code;
 	unsigned short flags; /* set to a combination of:
 							 TMCB_RETR_F if this is a _ser_ retransmission
 							 (but not if if it's a "forwarded" retr., like a 
 							 retr. 200 Ok for example)
 							 TMCB_LOCAL_F if this is a local generated message
 							  (and not forwarded) */
 	unsigned short branch;
 	/* could also be: send_buf, dst, branch */
9217a640
 	struct retr_buf* t_rbuf; /* transaction retr. buf., all the information
 								 regarding destination, data that is/was
 								 actually sent on the net, branch a.s.o is
 								 inside */
 	struct dest_info* dst; /* destination */
 	str send_buf; /* what was/will be sent on the net, used for ACKs
 					(which don't have a retr_buf). */
3881f12c
 };
 
6aa46ec4
 #define INIT_TMCB_PARAMS(tmcb, request, reply, r_code)\
 do{\
 	memset(&(tmcb), 0, sizeof((tmcb))); \
 	(tmcb).req=(request); (tmcb).rpl=(reply);  \
 	(tmcb).code=(r_code); \
 }while(0)
 
 #define INIT_TMCB_ONSEND_PARAMS(tmcb, req, repl, rbuf, dest, buf, buf_len, \
 								onsend_flags, t_branch, code) \
 do{ \
 	INIT_TMCB_PARAMS(tmcb, req, repl, code); \
 	tmcb.t_rbuf=(rbuf); tmcb.dst=(dest); \
 	tmcb.send_buf.s=(buf); tmcb.send_buf.len=(buf_len); \
 	tmcb.flags=(onsend_flags); tmcb.branch=(t_branch); \
 }while(0)
 
a70eb298
 /* callback function prototype */
 typedef void (transaction_cb) (struct cell* t, int type, struct tmcb_params*);
657f117b
 /*! \brief function to release the callback param */
 typedef void (release_tmcb_param) (void* param);
a70eb298
 /* register callback function prototype */
cb0a8be5
 typedef int (*register_tmcb_f)(struct sip_msg* p_msg, struct cell *t,
657f117b
 							   int cb_types, transaction_cb f, void *param,
 							   release_tmcb_param func);
a70eb298
 
 
 struct tm_callback {
 	int id;                      /* id of this callback - useless */
 	int types;                   /* types of events that trigger the callback*/
 	transaction_cb* callback;    /* callback function */
 	void *param;                 /* param to be passed to callback function */
657f117b
 	release_tmcb_param* release; /**< Function to release the callback param
 								  * when the callback is deleted */
a70eb298
 	struct tm_callback* next;
 };
 
 struct tmcb_head_list {
6884496e
 	struct tm_callback volatile *first;
a70eb298
 	int reg_types;
 };
 
 
 extern struct tmcb_head_list*  req_in_tmcb_hl;
5c953757
 extern struct tmcb_head_list*  local_req_in_tmcb_hl;
a70eb298
 
94942cba
 void set_early_tmcb_list(struct sip_msg *msg,
 		struct cell *t);
a70eb298
 
 #define has_tran_tmcbs(_T_, _types_) \
32b645a4
 	( ((_T_)->tmcb_hl.reg_types)&(_types_) )
a70eb298
 #define has_reqin_tmcbs() \
 	( req_in_tmcb_hl->first!=0 )
5c953757
 #define has_local_reqin_tmcbs() \
 	( local_req_in_tmcb_hl->first!=0 )
a70eb298
 
 
5b9c3547
 int init_tmcb_lists(void);
a70eb298
 
5b9c3547
 void destroy_tmcb_lists(void);
a70eb298
 
 
 /* register a callback for several types of events */
cb0a8be5
 int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
657f117b
 				   transaction_cb f, void *param,
 				   release_tmcb_param rel_func);
3881f12c
 
a70eb298
 /* inserts a callback into the a callback list */
 int insert_tmcb(struct tmcb_head_list *cb_list, int types,
657f117b
 				transaction_cb f, void *param,
 				release_tmcb_param rel_func);
3881f12c
 
a70eb298
 /* run all transaction callbacks for an event type */
 void run_trans_callbacks( int type , struct cell *trans,
 						struct sip_msg *req, struct sip_msg *rpl, int code );
0277f618
 /* helper function */
 void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
 									struct cell *trans, 
 									struct tmcb_params *params);
a70eb298
 /* run all REQUEST_IN callbacks */
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
5c953757
 void run_local_reqin_callbacks( struct cell *trans, struct sip_msg *req, 
 		int code );
3881f12c
 
68017b5d
 /* like run_trans_callbacks but provide outgoing buffer (i.e., the
  * processed message) to callback */
 void run_trans_callbacks_with_buf(int type, struct retr_buf* rbuf, struct sip_msg* req,
 								  struct sip_msg* repl, short flags);
 
 /* like run_trans_callbacks but tmcb_params assumed to contain data already */
 void run_trans_callbacks_off_params(int type, struct cell* t, struct tmcb_params* p);
9217a640
 
3881f12c
 #endif