On 12-01 23:25, Maxim Sobolev wrote:
Everything works just fine when I'm calling from
UA1 to UA2, i.e.
from behind the NAT to the "outside world", however there are
some problems when I'm doing it in reverse direction. The problem
is that OK INVITE that the UA1 sends in reply to UA2's INVITE when
the user picks up the phone is not passed to my helper functions
and hence UA2 makes a wrong conclusion about where to send ACK and
BYE to.
Do you have any ideas on how to overcome this problem?
If I get you right, you need to rewrite Contact in 200 OK response to INVITE
comming from the NATed user agent.
You can do this using TM and it's callbacks. TM is transaction module and
you can register callbacks with the module. Among others, there is a callback
that will be called upon reception of the final response (200 OK in your
case). In the callback, you can modify the response and rewrite the contact.
First, you need to include t_hooks.h and tm_load.h from the tm module.
Then, you need to register a callback function. The following code snippet
shows how to do it:
static int mod_init( void )
{
load_tm_f load_tm;
/* import the TM auto-loading function */
if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT))) {
LOG(L_ERR, "radius_acc: mod_init: can't import load_tm\n");
return -1;
}
/* let the auto-loading function load all TM stuff */
if (load_tm( &tmb )==-1) return -1;
/* register callback */
if (tmb.rngister_tmcb( TMCB_REPLY, rad_acc_onreply, 0) <= 0)
return -1;
}
return 0;
}
The mod_init function registers rad_acc_onreply function, the function will
be called when the tm module receives a response.
The callback follows. Note that radius_acc module (from which the code
snippets were taken) registers TMCB_REPLY callback. This type of callback
will be called _AFTER_ the response was sent out - that means there is no way
how to modify it. Because of that, your module will have to register another
type of callback - TMCB_REPLY_IN. Such callback will be called before the
reply gets forwarded which means that you can modify it before it will be
sent out.
See modules/tm/t_hooks.h file for more details ! There is a description of
the callbacks.
/*
* Function that gets called on reply
* params: struct cell* t The callback structure
* struct sip_msg *msg The sip message.
* int code The status code
* void* param Passed parameter
* returns: nothing
*/
static void rad_acc_onreply( struct cell* t, struct sip_msg *reply, int code,
void *param )
{
struct sip_msg *rq;
rq = t->uas.request;
if (t->is_invite && missed_flag && isflagset( rq,
missed_flag)==1
&& ((code>=400 && code<500) ||
code>=600))
rad_acc_missed_report( t, reply, code);
/* if acc enabled for flagged transaction, check if flag matches */
if (acc_flag && isflagset( rq, acc_flag )==-1) return;
/* early media is reported only if explicitely demanded,
other provisional responses are always dropped */
if (code < 200 && ! (early_media && code==183))
return;
/* negative transactions reported only if explicitely demanded */
if (!failed_transactions && code >=300) return;
/* anything else, i.e., 2xx, always reported */
radius_log_reply(t, reply);
}
regards, Jan.