Module: sip-router
Branch: kamailio_3.0
Commit: fc59de27f87772df40a4408485a34344acbec950
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fc59de2…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Wed Jan 6 14:36:55 2010 +0100
tm: added t_relay_to(proxy, flags)
- parameters compatible with t_relay() in K old version
- proxy value can be: [proto:]host[:port]
- flgas can be 0x01, 0x04 or 0x05, 0x02 flag not supported
- all or any of the parameters can be omitted
---
modules/tm/tm.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 168 insertions(+), 0 deletions(-)
diff --git a/modules/tm/tm.c b/modules/tm/tm.c
index dcd9f83..a935755 100644
--- a/modules/tm/tm.c
+++ b/modules/tm/tm.c
@@ -146,6 +146,7 @@ static int fixup_on_reply(void** param, int param_no);
static int fixup_on_branch(void** param, int param_no);
static int fixup_t_reply(void** param, int param_no);
static int fixup_on_sl_reply(modparam_t type, void* val);
+static int fixup_t_relay_to(void** param, int param_no);
/* init functions */
static int mod_init(void);
@@ -181,6 +182,7 @@ inline static int w_t_relay_to_sctp( struct sip_msg *p_msg , char
*proxy,
inline static int w_t_relay_to_sctp_uri( struct sip_msg*, char*, char*);
#endif
inline static int w_t_relay_to_avp(struct sip_msg* msg, char* str,char*);
+inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*);
inline static int w_t_replicate_uri( struct sip_msg *p_msg ,
char *uri, /* sip uri as string or variable */
char *_foo /* nothing expected */ );
@@ -319,6 +321,12 @@ static cmd_export_t cmds[]={
REQUEST_ROUTE | FAILURE_ROUTE },
{"t_relay_to_avp", w_t_relay_to_avp, 2, fixup_proto_hostport2proxy,
REQUEST_ROUTE},
+ {"t_relay_to", w_t_relay_to, 0, 0,
+ REQUEST_ROUTE | FAILURE_ROUTE },
+ {"t_relay_to", w_t_relay_to, 1, fixup_t_relay_to,
+ REQUEST_ROUTE | FAILURE_ROUTE },
+ {"t_relay_to", w_t_relay_to, 2, fixup_t_relay_to,
+ REQUEST_ROUTE | FAILURE_ROUTE },
{T_FORWARD_NONACK, w_t_forward_nonack, 2, fixup_hostport2proxy,
REQUEST_ROUTE},
{T_FORWARD_NONACK_URI, w_t_forward_nonack_uri, 0, 0,
@@ -1880,3 +1888,163 @@ static int t_check_trans(struct sip_msg* msg, char* foo, char*
bar)
}
return -1;
}
+
+static int hexatoi(str *s, unsigned int* result)
+{
+ int i, xv, fact;
+
+ /* more than 32bit hexa? */
+ if (s->len>8)
+ return -1;
+
+ *result = 0;
+ fact = 1;
+
+ for(i=s->len-1; i>=0 ;i--)
+ {
+ xv = hex2int(s->s[i]);
+ if(xv<0)
+ return -1;
+
+ *result += (xv * fact);
+ fact *= 16;
+ }
+ return 0;
+}
+
+static int fixup_t_relay_to(void** param, int param_no)
+{
+
+ int port;
+ int proto;
+ unsigned int flags;
+ struct proxy_l *proxy;
+ action_u_t *a;
+ str s;
+ str host;
+
+ s.s = (char*)*param;
+ s.len = strlen(s.s);
+ LM_DBG("fixing (%s, %d)\n", s.s, param_no);
+ if (param_no==1){
+ a = fixup_get_param(param, param_no, 2);
+ if(a==NULL)
+ {
+ LM_CRIT("server error for parameter <%s>\n",s.s);
+ return E_UNSPEC;
+ }
+ if(a->u.string!=NULL) {
+ /* second parameter set, first should be proxy addr */
+ if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
+ LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
+ return E_UNSPEC;
+ }
+
+ proxy = mk_proxy(&host, port, proto);
+ if (proxy==0) {
+ LM_ERR("failed to build proxy structure for <%.*s>\n", host.len,
host.s );
+ return E_UNSPEC;
+ }
+ *(param)=proxy;
+ return 0;
+ } else {
+ /* no second parameter, then is proxy addr or flags */
+ flags = 0;
+ if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
+ s.s += 2;
+ s.len -= 2;
+ if(hexatoi(&s, &flags)<0)
+ {
+ LM_CRIT("invalid hexa flags <%s>\n", s.s);
+ return E_UNSPEC;
+ }
+ a->u.data = (void*)(unsigned long int)flags;
+ *(param)= 0;
+ return 0;
+ } else {
+ if(str2int(&s, &flags)==0)
+ {
+ a->u.data = (void*)(unsigned long int)flags;
+ *(param)= 0;
+ return 0;
+ } else {
+ /* try proxy */
+ if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
+ LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
+ return E_UNSPEC;
+ }
+
+ proxy = mk_proxy(&host, port, proto);
+ if (proxy==0) {
+ LM_ERR("failed to build proxy structure for <%.*s>\n", host.len,
host.s );
+ return E_UNSPEC;
+ }
+ *(param)=proxy;
+ return 0;
+ }
+ }
+ }
+ } else if (param_no==2) {
+ /* flags */
+ flags = 0;
+ if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
+ s.s += 2;
+ s.len -= 2;
+ if(hexatoi(&s, &flags)<0)
+ {
+ LM_CRIT("invalid hexa flags <%s>\n", s.s);
+ return E_UNSPEC;
+ }
+ *(param) = (void*)(unsigned long int)flags;
+ return 0;
+ } else {
+ if(str2int(&s, &flags)==0)
+ {
+ *(param) = (void*)(unsigned long int)flags;
+ return 0;
+ } else {
+ LM_CRIT("invalid flags <%s>\n", s.s);
+ return E_UNSPEC;
+ }
+ }
+ } else {
+ LM_ERR("invalid parameter number %d\n", param_no);
+ return E_BUG;
+ }
+}
+
+
+inline static int w_t_relay_to(struct sip_msg *msg, char *proxy, char *flags)
+{
+ unsigned int fl;
+ struct proxy_l *px;
+ fparam_t param;
+
+ fl = (unsigned int)(long)(void*)flags;
+ px = (struct proxy_l*)proxy;
+
+ if(flags!=0)
+ {
+ memset(¶m, 0, sizeof(fparam_t));
+ param.type = FPARAM_INT;
+ /* no auto 100 trying */
+ if(fl&1) {
+ param.v.i = 0;
+ t_set_auto_inv_100(msg, (char*)(¶m), 0);
+ }
+ /* no auto negative reply - not implemented */
+ /*
+ if(fl&2) {
+ param.v.i = 1;
+ t_set_disable_internal_reply(msg, (char*)param, 0);
+ }
+ */
+ /* no dns failover */
+ if(fl&4) {
+ param.v.i = 1;
+ t_set_disable_failover(msg, (char*)(¶m), 0);
+ }
+ }
+ return _w_t_relay_to(msg, px, PROTO_NONE);
+}
+