[Serusers] Rewriting URI in the Contact field

Maxim Sobolev sobomax at FreeBSD.org
Mon Jan 13 21:53:45 CET 2003


Maxim Sobolev wrote:
> 
> On Mon, Jan 13, 2003 at 02:38:37PM +0100, Jan Janak wrote:
> > On 13-01 14:46, Maxim Sobolev wrote:
> > > 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?
> > >
> >
> >   Why is the callback not generic solution ?
> 
> Because as far as I understand then it will be called on each transaction,
> or I am missing something? What if I need to apply my function only if the
> reply match some pre-defined conditions (i.e. "Server: ATA.*")?

Attached please find the patch, which implements t_on_positive()
approach. Now my config looks like the following and everything now
works as expected:

route {
        if (search("User-Agent: Cisco ATA.*")) {
                add_rport();
                fix_nated_contact();
        };
        rewriteFromRoute();

        [REGISTRATION STUFF STRIPPED]

        if (method=="INVITE") {
                addRecordRoute();
        };

	t_on_positive("1")
        # forward to current uri now
        if (!t_relay()) {
                sl_reply_error();
        };
}

reply_route[1] {
	if (search("Server: Cisco ATA.*") {
                fix_nated_contact();
	}
}

Please let me know what do you think about my patches.

Thank you for your help!

-Maxim

> >   regards, Jan.
> >
> > > >   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.
> > >
> > >
> > > _______________________________________________
> > > Serusers mailing list
> > > serusers at lists.iptel.org
> > > http://lists.iptel.org/mailman/listinfo/serusers
> > >
> 
> _______________________________________________
> Serusers mailing list
> serusers at lists.iptel.org
> http://lists.iptel.org/mailman/listinfo/serusers
-------------- next part --------------
--- modules/tm/h_table.h	2003/01/13 18:36:18	1.1
+++ modules/tm/h_table.h	2003/01/13 18:36:55
@@ -202,6 +202,8 @@
 
 	/* the route to take if no final positive reply arrived */
 	unsigned int on_negative;
+	/* the route to take if final positive reply arrived */
+	unsigned int on_positive;
 	/* set to one if you want to disallow silent transaction
 	   dropping when C timer hits
 	*/
--- modules/tm/t_fwd.c	2003/01/13 18:35:29	1.1
+++ modules/tm/t_fwd.c	2003/01/13 18:36:09
@@ -415,6 +415,8 @@
 
 	/* if someone set on_negative, store in in T-context */
 	t->on_negative=get_on_negative();
+	/* if someone set on_positive, store in in T-context */
+	t->on_positive=get_on_positive();
 
 	/* send them out now */
 	for (i=first_branch; i<t->nr_of_outgoings; i++) {
--- modules/tm/t_reply.c.orig	Tue Oct 22 00:24:43 2002
+++ modules/tm/t_reply.c	Mon Jan 13 22:36:44 2003
@@ -56,6 +56,8 @@
 
 /* where to go if there is no positive reply */
 static int goto_on_negative=0;
+/* where to go if is a positive reply */
+static int goto_on_positive=0;
 
 /* we store the reply_route # in private memory which is
    then processed during t_relay; we cannot set this value
@@ -73,12 +75,23 @@
 	return 1;
 }
 
+int t_on_positive( unsigned int go_to )
+{
+	goto_on_positive=go_to;
+	return 1;
+}
+
 
 unsigned int get_on_negative()
 {
 	return goto_on_negative;
 }
 
+unsigned int get_on_positive()
+{
+	return goto_on_positive;
+}
+
 void tm_init_tags()
 {
 	init_tags(tm_tags, &tm_tag_suffix, 
@@ -916,4 +929,26 @@
 	if (faked_msg.new_uri.s) pkg_free(faked_msg.new_uri.s);
 }
 
+void on_positive_reply( struct cell* t, struct sip_msg* msg,
+	int code, void *param )
+{
+	int act_ret;
+	struct lump* tmp;
 
+	/* nobody cares about a positive transaction -- ok, return */
+	if (!t->on_positive) {
+		DBG("DBG: on_positive_reply: no on_positive\n");
+		return;
+	}
+
+	tmp = msg->add_rm;
+	msg->add_rm = msg->repl_add_rm;
+	act_ret=run_actions(reply_rlist[t->on_positive], msg);
+	msg->repl_add_rm = msg->add_rm;
+	msg->add_rm = tmp;
+	if (act_ret<0) {
+		LOG(L_ERR, "on_positive_reply: Error in do_action\n");
+	}
+
+	return;
+}
--- modules/tm/t_reply.h	2003/01/13 18:40:07	1.1
+++ modules/tm/t_reply.h	2003/01/13 18:41:53
@@ -101,11 +101,16 @@
 void on_negative_reply( struct cell* t, struct sip_msg* msg,
 	int code, void *param  );
 
+void on_positive_reply( struct cell* t, struct sip_msg* msg,
+	int code, void *param  );
+
 /* set which 'reply' structure to take if only negative
    replies arrive 
 */
 int t_on_negative( unsigned int go_to );
 unsigned int get_on_negative();
+int t_on_positive( unsigned int go_to );
+unsigned int get_on_positive();
 
 int t_retransmit_reply( struct cell *t );
 
--- modules/tm/tm.c	2003/01/13 18:15:44	1.1
+++ modules/tm/tm.c	2003/01/13 18:43:19
@@ -95,6 +95,7 @@
 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
 inline static int fixup_hostport2proxy(void** param, int param_no);
 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo );
+inline static int w_t_on_positive( struct sip_msg* msg, char *go_to, char *foo );
 
 
 static int mod_init(void);
@@ -121,6 +122,7 @@
 				T_RELAY,
 				T_FORWARD_NONACK,
 				"t_on_negative",
+				"t_on_positive",
 
 				/* not applicable from script ... */
 
@@ -141,6 +143,7 @@
 					w_t_relay,
 					w_t_forward_nonack,
 					w_t_on_negative,
+					w_t_on_positive,
 
 					(cmd_function) register_tmcb,
 					(cmd_function) t_uac,
@@ -159,6 +162,7 @@
 				0, /* t_relay */
 				2, /* t_forward_nonack */
 				1, /* t_on_negative */
+				1, /* t_on_positive */
 				NO_SCRIPT /* register_tmcb */,
 				NO_SCRIPT /* t_uac */,
 				NO_SCRIPT /* load_tm */,
@@ -176,13 +180,14 @@
 				0,						/* t_relay */
 				fixup_hostport2proxy,	/* t_forward_nonack */
 				fixup_str2int,			/* t_on_negative */
+				fixup_str2int,			/* t_on_positive */
 				0,						/* register_tmcb */
 				0,						/* t_uac */
 				0,						/* load_tm */
 				0						/* t_newdlg */
 	
 		},
-	15,
+	16,
 
 	/* ------------ exported variables ---------- */
 	(char *[]) { /* Module parameter names */
@@ -266,6 +271,7 @@
 	   message's t_on_negative value
 	*/
 	t_on_negative( 0 );
+	t_on_positive( 0 );
 
 	return 1;
 }
@@ -332,6 +338,8 @@
 	}
 	register_tmcb( TMCB_ON_NEGATIVE, on_negative_reply, 
 			0 /* empty param */);
+	register_tmcb( TMCB_REPLY_IN, on_positive_reply,
+			0 /* empty param */);
 	/* register post-script clean-up function */
 	register_script_cb( w_t_unref, POST_SCRIPT_CB, 
 			0 /* empty param */ );
@@ -533,6 +541,11 @@
 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo )
 {
 	return t_on_negative( (unsigned int ) go_to );
+}
+
+inline static int w_t_on_positive( struct sip_msg* msg, char *go_to, char *foo )
+{
+	return t_on_positive( (unsigned int ) go_to );
 }
 
 inline static int w_t_relay_to( struct sip_msg  *p_msg , 


More information about the sr-users mailing list