Skip to content

Commit

Permalink
tm: add TMCB_LOCAL_{RESPONSE,REQUEST_OUT,TRANS_NEW} callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
razvancrainea committed May 13, 2022
1 parent 513a9e6 commit 197d881
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 66 deletions.
107 changes: 50 additions & 57 deletions modules/tm/t_hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "t_lookup.h"
#include "t_funcs.h"

struct tmcb_head_list* req_in_tmcb_hl = 0;
struct tmcb_head_list* new_tran_tmcb_hl = 0;

struct tmcb_head_list tmcb_pending_hl = {0,0};
unsigned int tmcb_pending_id = (unsigned int)-1;
Expand All @@ -57,29 +57,35 @@ void empty_tmcb_list(struct tmcb_head_list *head)
head->reg_types = 0;
}

static struct tmcb_head_list *new_tmcb_list(void)
{
struct tmcb_head_list *list = (struct tmcb_head_list*)shm_malloc
(sizeof(struct tmcb_head_list));
if (list==0) {
LM_CRIT("no more shared memory\n");
return NULL;
}
list->first = 0;
list->reg_types = 0;
return list;
}

int init_tmcb_lists(void)
{
req_in_tmcb_hl = (struct tmcb_head_list*)shm_malloc
( sizeof(struct tmcb_head_list) );
if (req_in_tmcb_hl==0) {
LM_CRIT("no more shared memory\n");

new_tran_tmcb_hl = new_tmcb_list();
if (!new_tran_tmcb_hl)
return -1;
}
req_in_tmcb_hl->first = 0;
req_in_tmcb_hl->reg_types = 0;
return 1;
}


void destroy_tmcb_lists(void)
{
if (!req_in_tmcb_hl)
return;

empty_tmcb_list(req_in_tmcb_hl);

shm_free(req_in_tmcb_hl);
if (!new_tran_tmcb_hl) {
empty_tmcb_list(new_tran_tmcb_hl);
shm_free(new_tran_tmcb_hl);
}
}


Expand Down Expand Up @@ -134,18 +140,18 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
return E_BUG;
}

if (types&TMCB_REQUEST_IN) {
if (types!=TMCB_REQUEST_IN) {
LM_CRIT("callback type TMCB_REQUEST_IN "
"can't be register along with types\n");
if (types&(TMCB_REQUEST_IN|TMCB_LOCAL_TRANS_NEW)) {
if (types&(~(TMCB_REQUEST_IN|TMCB_LOCAL_TRANS_NEW))) {
LM_CRIT("callback type TMCB_REQUEST_IN and/or TMCB_LOCAL_TRANS_NEW "
"can't be register along with other types\n");
return E_BUG;
}
if (req_in_tmcb_hl==0) {
LM_ERR("callback type TMCB_REQUEST_IN "
if (new_tran_tmcb_hl==0) {
LM_ERR("callback type TMCB_REQUEST_IN and/or TMCB_LOCAL_TRANS_NEW "
"registration attempt before TM module initialization\n");
return E_CFG;
}
cb_list = req_in_tmcb_hl;
cb_list = new_tran_tmcb_hl;
} else {
if (!t) {
if (!p_msg) {
Expand Down Expand Up @@ -182,9 +188,8 @@ void set_extra_tmcb_params(void *extra1, void *extra2)
tmcb_extra2 = extra2;
}


void run_trans_callbacks( int type , struct cell *trans,
struct sip_msg *req, struct sip_msg *rpl, int code )
static void run_any_trans_callbacks(struct tmcb_head_list *list, unsigned int type,
struct cell *trans, struct sip_msg *req, struct sip_msg *rpl, int code)
{
struct tmcb_params params;
struct tm_callback *cbp;
Expand All @@ -197,16 +202,23 @@ void run_trans_callbacks( int type , struct cell *trans,
params.extra1 = tmcb_extra1;
params.extra2 = tmcb_extra2;

if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
if (list->first==0 || ((list->reg_types)&type)==0)
return;

backup = set_avp_list( &trans->user_avps );
for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next) {
if ( (cbp->types)&type ) {
for (cbp=list->first; cbp; cbp=cbp->next) {
if ((cbp->types)&type) {
LM_DBG("trans=%p, callback type %d, id %d entered\n",
trans, type, cbp->id );
params.param = &(cbp->param);
cbp->callback( trans, type, &params );
if ((cbp->types)&(TMCB_REQUEST_IN|TMCB_LOCAL_TRANS_NEW)) {
if (req && req->dst_uri.len==-1) {
LM_CRIT("callback %s id %d entered\n",
(type&TMCB_REQUEST_IN?"REQIN":"LOCAL_NEW"),cbp->id );
req->dst_uri.len = 0;
}
}
}
}
/* env cleanup */
Expand All @@ -215,40 +227,21 @@ void run_trans_callbacks( int type , struct cell *trans,
set_t(trans_backup);
}



void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
void run_trans_callbacks( int type , struct cell *trans,
struct sip_msg *req, struct sip_msg *rpl, int code )
{
struct tmcb_params params;
struct tm_callback *cbp;
struct usr_avp **backup;
struct cell *trans_backup = get_t();

params.req = req;
params.rpl = 0;
params.code = code;
params.extra1 = tmcb_extra1;
params.extra2 = tmcb_extra2;

if (req_in_tmcb_hl->first==0)
return;
run_any_trans_callbacks(&trans->tmcb_hl, type, trans, req, rpl, code);
}

backup = set_avp_list( &trans->user_avps );
for (cbp=req_in_tmcb_hl->first; cbp; cbp=cbp->next) {
LM_DBG("trans=%p, callback type %d, id %d entered\n",
trans, cbp->types, cbp->id );
params.param = &(cbp->param);
cbp->callback( trans, cbp->types, &params );
if (req && req->dst_uri.len==-1) {
LM_CRIT("callback REQIN id %d entered\n", cbp->id );
req->dst_uri.len = 0;
}
}
set_avp_list( backup );
tmcb_extra1 = tmcb_extra2 = 0;
set_t(trans_backup);
void run_new_local_callbacks(struct cell *trans, struct sip_msg *req, int code)
{
run_any_trans_callbacks(new_tran_tmcb_hl, TMCB_LOCAL_TRANS_NEW, trans, req, NULL, code);
}

void run_reqin_callbacks(struct cell *trans, struct sip_msg *req, int code)
{
run_any_trans_callbacks(new_tran_tmcb_hl, TMCB_REQUEST_IN, trans, req, NULL, code);
}

void run_trans_callbacks_locked( int type , struct cell *trans,
struct sip_msg *req, struct sip_msg *rpl, int code )
Expand Down
25 changes: 22 additions & 3 deletions modules/tm/t_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ struct cell;
#define TMCB_PRE_SEND_BUFFER (1<<13)
#define TMCB_MSG_MATCHED_IN (1<<14)
#define TMCB_MSG_SENT_OUT (1<<15)
#define TMCB_MAX ((1<<16)-1)
#define TMCB_LOCAL_TRANS_NEW (1<<16)
#define TMCB_LOCAL_REQUEST_OUT (1<<17)
#define TMCB_LOCAL_RESPONSE (1<<18)
#define TMCB_MAX ((1<<19)-1)

/*
* Caution: most of the callbacks work with shmem-ized messages
Expand Down Expand Up @@ -181,6 +184,18 @@ struct cell;
* 2) 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 if necessary.
*
* TMCB_LOCAL_TRANS_NEW -- triggered when a local transacton is
* created there the transaction
*
* TMCB_LOCAL_REQUEST_OUT -- triggered when a local transaction
* creates a new request and sends it out.
*
* TMCB_LOCAL_RESPONSE -- triggered when a response is generated
* either from script, or through the API. It is run just before
* the response is actually built, so a reply is not available.
* Receives as parameter the body of the reply.
*
*/


Expand Down Expand Up @@ -218,15 +233,17 @@ struct tmcb_head_list {
};


extern struct tmcb_head_list* req_in_tmcb_hl;
extern struct tmcb_head_list* new_tran_tmcb_hl;

extern struct tmcb_head_list tmcb_pending_hl;
extern unsigned int tmcb_pending_id;

#define has_tran_tmcbs(_T_, _types_) \
( ((_T_)->tmcb_hl.reg_types)&(_types_) )
#define has_reqin_tmcbs() \
( req_in_tmcb_hl->first!=0 )
( new_tran_tmcb_hl->first!=0 && (new_tran_tmcb_hl->reg_types&TMCB_REQUEST_IN))
#define has_new_local_tmcbs() \
( new_tran_tmcb_hl->first!=0 && (new_tran_tmcb_hl->reg_types&TMCB_LOCAL_TRANS_NEW))


void empty_tmcb_list(struct tmcb_head_list *head);
Expand Down Expand Up @@ -257,6 +274,8 @@ void run_trans_callbacks_locked( int type , struct cell *trans,
/* run all REQUEST_IN callbacks */
void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );

/* run all NEW LOCAL callbacks */
void run_new_local_callbacks(struct cell *trans, struct sip_msg *req, int code);

typedef int (*ctx_load_register_func)(void*);

Expand Down
10 changes: 10 additions & 0 deletions modules/tm/t_reply.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,11 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
}
}

if (has_tran_tmcbs(trans, TMCB_LOCAL_RESPONSE)) {
run_trans_callbacks(TMCB_LOCAL_RESPONSE,
trans, p_msg, 0, code);
}

/* check if the UAS retranmission port needs to be updated */
if ( (p_msg->msg_flags ^ trans->uas.request->msg_flags) & FL_FORCE_RPORT )
su_setport( &trans->uas.response.dst.to, p_msg->rcv.src_port );
Expand Down Expand Up @@ -1747,6 +1752,11 @@ static int _reply_with_body( struct cell *trans, unsigned int code, str *text,
} else {
body_lump = 0;
}
if (has_tran_tmcbs(trans, TMCB_LOCAL_RESPONSE)) {
set_extra_tmcb_params(body, NULL);
run_trans_callbacks(TMCB_LOCAL_RESPONSE,
trans, p_msg, 0, code);
}

if(to_tag && to_tag->len) {
rpl.s = build_res_buf_from_sip_req(code, text, to_tag, p_msg,
Expand Down
27 changes: 21 additions & 6 deletions modules/tm/uac.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "../../action.h"
#include "../../dset.h"
#include "../../data_lump.h"
#include "../../parser/parse_methods.h"

#include "ut.h"
#include "h_table.h"
Expand Down Expand Up @@ -176,6 +177,12 @@ static int run_local_route( struct cell *new_cell, char **buf, int *buf_len,
int buf_len1, sip_msg_len;
str h_to, h_from, h_cseq, h_callid;

/* do not build buffer if callbacks are not needed and
* there are no local routes */
if (!has_tran_tmcbs(new_cell, TMCB_LOCAL_REQUEST_OUT) &&
!sroutes->local.a)
return 0;

LM_DBG("building sip_msg from buffer\n");
sipmsg_buf = *buf; /* remember the buffer used to get the sip_msg */
req = buf_to_sip_msg( *buf, *buf_len, dialog);
Expand All @@ -192,7 +199,12 @@ static int run_local_route( struct cell *new_cell, char **buf, int *buf_len,

/* run the route */
swap_route_type( backup_route_type, LOCAL_ROUTE);
run_top_route( sroutes->local, req);
if (sroutes && sroutes->local.a)
run_top_route( sroutes->local, req);
if (has_tran_tmcbs(new_cell, TMCB_LOCAL_REQUEST_OUT) ) {
run_trans_callbacks(TMCB_LOCAL_REQUEST_OUT, new_cell,
req, 0, 0);
}
set_route_type( backup_route_type );

/* transfer current message context back to t */
Expand Down Expand Up @@ -393,7 +405,7 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
char *buf;
int buf_len;
int ret, flags;
unsigned int hi;
unsigned int hi, method_id;
struct proxy_l *proxy;

ret=-1;
Expand Down Expand Up @@ -452,6 +464,11 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
* we might need it later for accessing dialog specific info */
if (dialog->dialog_ctx)
new_cell->dialog_ctx = dialog->dialog_ctx;
if (has_new_local_tmcbs()) {
if (parse_method(method->s, method->s + method->len, &method_id) == NULL)
method_id = METHOD_UNDEF;
run_new_local_callbacks(new_cell, NULL, method_id);
}

/* pass the transaction flags from dialog to transaction */
new_cell->flags |= dialog->T_flags;
Expand Down Expand Up @@ -505,11 +522,9 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
}

/* run the local route */
if (sroutes==NULL) {
if (sroutes==NULL)
LM_BUG("running local route/t_uac, but no routes in the process\n");
} else if (sroutes->local.a) {
run_local_route( new_cell, &buf, &buf_len, dialog, &req, &buf_req);
}
run_local_route( new_cell, &buf, &buf_len, dialog, &req, &buf_req);

if (request->buffer.s==NULL) {
request->buffer.s = buf;
Expand Down

0 comments on commit 197d881

Please sign in to comment.