On Sun, Jan 12, 2003 at 11:44:21PM +0100, Jan Janak wrote:
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.
Correct.
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.
I see, but IMO this would be not a generic solution, as I'll have to adjust the code for my particular needs. What I am looking for is some way to allow it to be modified by properly constructing config file. Perhaps something like t_on_negative() could be added, i.e. t_on_positive(): the specified routing block will be called when the transaction is completed with positive result but before sending final reply. What do you think?
-Maxim
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.