Module: sip-router Branch: kamailio_3.0 Commit: fc59de27f87772df40a4408485a34344acbec950 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fc59de27...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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); +} +