/*
* $Id: t_hooks.h,v 1.18 2004/08/24 09:00:42 janakj Exp $
*
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of ser, a free SIP server.
*
* ser is free software; you can redistribute it and/or modify
* 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
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* ser is distributed in the hope that it will be useful,
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* --------
* 2003-03-16 : backwards-compatibility callback names introduced (jiri)
* 2003-03-06 : old callbacks renamed, new one introduced (jiri)
* 2003-12-04 : global callbacks moved into transaction callbacks;
* multiple events per callback added; single list per
* transaction for all its callbacks (bogdan)
*/
#ifndef _HOOKS_H
#define _HOOKS_H
#include "defs.h"
struct sip_msg;
struct cell;
#define TMCB_REQUEST_IN (1<<0)
#define TMCB_RESPONSE_IN (1<<1)
#define TMCB_E2EACK_IN (1<<2)
#define TMCB_REQUEST_FWDED (1<<3)
#define TMCB_RESPONSE_FWDED (1<<4)
#define TMCB_ON_FAILURE_RO (1<<5)
#define TMCB_ON_FAILURE (1<<6)
#define TMCB_RESPONSE_OUT (1<<7)
#define TMCB_LOCAL_COMPLETED (1<<8)
#define TMCB_MAX ((1<<9)-1)
/*
* 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.
*
* 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.
*
*
* 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
* 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).
*
* TMCB_RESPONSE_IN -- a brand-new reply was received which matches
* an existing transaction. It may or may not be a retransmission.
*
* TMCB_RESPONSE_OUT -- a final reply was sent out (either local
* or proxied) -- there is nothing more you can change from
* the callback, it is good for accounting-like uses.
*
* Note: the message passed to callback may also have
* value FAKED_REPLY (like other reply callbacks) which
* indicates a pseudo_reply caused by a timer. Check for
* this value before deferring -- you will cause a segfault
* otherwise. Check for t->uas.request validity too if you
* need it ... locally initiated UAC transactions set it to 0.
*
* 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.
*
* TMCB_ON_FAILURE_RO -- called on receipt of a reply or timer;
* it means all branches completed with a failure; the callback
* function MUST not change anything in the transaction (READONLY)
* that's a chance for doing ACC or stuff like this
*
* TMCB_ON_FAILURE -- called on receipt of a reply or timer;
* it means all branches completed with a failure; that's
* a chance for example to add new transaction branches
*
* TMCB_RESPONSE_FWDED -- called when a reply is about to be
* forwarded; it is called after a message is received but before
* 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
* necessarily the same which will be forwarded). As forwarding
* has not been executed and may fail, there is no guarantee
* a reply will be successfully sent out at this point of time.
*
* Note: TMCB_REPLY_ON_FAILURE and TMCB_REPLY_FWDED are
* 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
* transaction occurrence will be matched with spirals. If
* record-routing is not enabled, you will never receive the
* ACK and the callback will be never triggered.
*
*
* TMCB_REQUEST_FWDED -- request is being forwarded out. It is
* called before a message is forwarded and it is your last
* chance to change its shape.
*
* TMCB_LOCAL COMPLETED -- final reply for localy initiated
* transaction arrived. Message may be FAKED_REPLY.
*
note that callbacks MUST be installed before forking
(callback lists do not live in shmem and have no access
protection), i.e., at best from mod_init functions.
the callback's param MUST be in shared memory and will
NOT be freed by TM; you must do it yourself from the
callback function id necessary.
*/
/* pack structure with all params passed to callback function */
struct tmcb_params {
struct sip_msg* req;
struct sip_msg* rpl;
int code;
void **param;
};
/* callback function prototype */
typedef void (transaction_cb) (struct cell* t, int type, struct tmcb_params*);
/* register callback function prototype */
typedef int (*register_tmcb_f)(struct sip_msg* p_msg, struct cell *t,
int cb_types, transaction_cb f, void *param);
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 */
struct tm_callback* next;
};
struct tmcb_head_list {
struct tm_callback *first;
int reg_types;
};
extern struct tmcb_head_list* req_in_tmcb_hl;
#define has_tran_tmcbs(_T_, _types_) \
( ((_T_)->tmcb_hl.reg_types)|(_types_) )
#define has_reqin_tmcbs() \
( req_in_tmcb_hl->first!=0 )
int init_tmcb_lists();
void destroy_tmcb_lists();
/* register a callback for several types of events */
int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
transaction_cb f, void *param );
//int register_tmcb( struct sip_msg* p_msg, int types, transaction_cb f,
// void *param );
/* inserts a callback into the a callback list */
int insert_tmcb(struct tmcb_head_list *cb_list, int types,
transaction_cb f, void *param );
/* 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 );
/* run all REQUEST_IN callbacks */
void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
#endif
syntax highlighted by Code2HTML, v. 0.9.1