core/corex: move send()/send_tcp() to corex module
authorRichard Fuchs <rfuchs@sipwise.com>
Fri, 30 Nov 2012 19:00:09 +0000 (14:00 -0500)
committerRichard Fuchs <rfuchs@sipwise.com>
Fri, 30 Nov 2012 19:00:09 +0000 (14:00 -0500)
As suggested by miconda on sr-dev, move send() and send_tcp() out of core
and into the new corex module in order to make them support pseudo variables.
This changes:

- drops SEND and SEND_TCP tokens from config parser
- remove related config parser code relying on SEND_T and SEND_TCP_T
- augment corex module to provide the functions removed from core
- update corex docs

12 files changed:
action.c
cfg.lex
cfg.y
modules/corex/README
modules/corex/corex_lib.c
modules/corex/corex_lib.h
modules/corex/corex_mod.c
modules/corex/doc/corex_admin.xml
modules/debugger/debugger_act.c
route.c
route_struct.c
route_struct.h

index dbd528c..a4a8e0b 100644 (file)
--- a/action.c
+++ b/action.c
@@ -485,80 +485,6 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
                                goto error;
                        }
                        break;
-               case SEND_T:
-               case SEND_TCP_T:
-                       if (a->val[0].type==URIHOST_ST){
-                               /*get next hop uri uri*/
-                               if (msg->dst_uri.len) {
-                                       ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
-                                                                       &next_hop);
-                                       u = &next_hop;
-                               } else {
-                                       ret = parse_sip_msg_uri(msg);
-                                       u = &msg->parsed_uri;
-                               }
-
-                               if (ret<0) {
-                                       LM_ERR("send() - bad_uri dropping packet\n");
-                                       ret=E_BUG;
-                                       goto error;
-                               }
-                               /* init dst */
-                               init_dest_info(&dst);
-                               ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
-                                                       &dst.proto);
-                               if(ret!=0) {
-                                       LM_ERR("failed to resolve [%.*s]\n", u->host.len,
-                                               ZSW(u->host.s));
-                                       ret=E_BUG;
-                                       goto error;
-                               }
-                       } else {
-                               if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
-                                       LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
-                                                       a->val[0].type, a->val[1].type);
-                                       ret=E_BUG;
-                                       goto error;
-                               }
-                               /* init dst */
-                               init_dest_info(&dst);
-                               ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
-                               if(ret==0)
-                                       proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
-                       }
-                       if (ret==0){
-                               if (p_onsend){
-                                       tmp=p_onsend->buf;
-                                       len=p_onsend->len;
-                               }else{
-                                       tmp=msg->buf;
-                                       len=msg->len;
-                               }
-                               if (a->type==SEND_T){
-                                       /*udp*/
-                                       dst.proto=PROTO_UDP; /* not really needed for udp_send */
-                                       dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
-                                       if (dst.send_sock!=0){
-                                               ret=udp_send(&dst, tmp, len);
-                                       }else{
-                                               ret=-1;
-                                       }
-                               }
-#ifdef USE_TCP
-                                       else{
-                                               /*tcp*/
-                                               dst.proto=PROTO_TCP;
-                                               dst.id=0;
-                                               ret=tcp_send(&dst, 0, tmp, len);
-                               }
-#endif
-                       }else{
-                               ret=E_BUG;
-                               goto error;
-                       }
-                       if (ret>=0) ret=1;
-
-                       break;
                case LOG_T:
                        if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
                                LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
diff --git a/cfg.lex b/cfg.lex
index d864d42..153e7b6 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -195,8 +195,6 @@ DROP        "drop"
 EXIT   "exit"
 RETURN "return"
 BREAK  "break"
-SEND   send
-SEND_TCP       send_tcp
 LOG            log
 ERROR  error
 ROUTE  route
@@ -606,8 +604,6 @@ IMPORTFILE      "import_file"
 <INITIAL>{EXIT}        { count(); yylval.strval=yytext; return EXIT; }
 <INITIAL>{RETURN}      { count(); yylval.strval=yytext; return RETURN; }
 <INITIAL>{BREAK}       { count(); yylval.strval=yytext; return BREAK; }
-<INITIAL>{SEND}        { count(); yylval.strval=yytext; return SEND; }
-<INITIAL>{SEND_TCP}    { count(); yylval.strval=yytext; return SEND_TCP; }
 <INITIAL>{LOG} { count(); yylval.strval=yytext; return LOG_TOK; }
 <INITIAL>{ERROR}       { count(); yylval.strval=yytext; return ERROR; }
 <INITIAL>{SETFLAG}     { count(); yylval.strval=yytext; return SETFLAG; }
diff --git a/cfg.y b/cfg.y
index 8fdfcb5..cad5e30 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -305,8 +305,6 @@ extern char *finame;
 %token FORWARD_TLS
 %token FORWARD_SCTP
 %token FORWARD_UDP
-%token SEND
-%token SEND_TCP
 %token EXIT
 %token DROP
 %token RETURN
@@ -2412,8 +2410,6 @@ fcmd:
                if ($1 && rt==ONSEND_ROUTE) {
                        switch($1->type) {
                                case DROP_T:
-                               case SEND_T:
-                               case SEND_TCP_T:
                                case LOG_T:
                                case SETFLAG_T:
                                case RESETFLAG_T:
@@ -3173,24 +3169,6 @@ cmd:
        | FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
        | FORWARD_SCTP LPAREN error RPAREN { $$=0; 
                                                                        yyerror("bad forward_tls argument"); }
-       | SEND LPAREN RPAREN { $$=mk_action(SEND_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
-       | SEND LPAREN host RPAREN       { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND LPAREN ip RPAREN         { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND LPAREN host COMMA NUMBER RPAREN  { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
-       | SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
-       | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
-       | SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
-       | SEND LPAREN error RPAREN { $$=0; yyerror("bad send argument"); }
-       | SEND_TCP LPAREN RPAREN { $$=mk_action(SEND_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
-       | SEND_TCP LPAREN host RPAREN   { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND_TCP LPAREN STRING RPAREN { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND_TCP LPAREN ip RPAREN     { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
-       | SEND_TCP LPAREN host COMMA NUMBER RPAREN      { $$=mk_action( SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);}
-       | SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
-       | SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
-       | SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
-       | SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp argument"); }
        | LOG_TOK LPAREN STRING RPAREN  {$$=mk_action(LOG_T, 2, NUMBER_ST,
                                                                                (void*)(L_DBG+1), STRING_ST, $3);
                                                                        set_cfg_pos($$); }
index 19681c7..402089a 100644 (file)
@@ -10,7 +10,7 @@ Daniel-Constantin Mierla
 
    <miconda@gmail.com>
 
-   Copyright © 2012 asipto.com
+   Copyright Â© 2012 asipto.com
      __________________________________________________________________
 
    Table of Contents
@@ -30,6 +30,8 @@ Daniel-Constantin Mierla
         4. Functions
 
               4.1. append_branch([ uri, [ q ] ])
+              4.2. send([ host [ :port ] ])
+              4.3. send_tcp([ host [ :port ] ])
 
         5. RPC Commands
 
@@ -40,6 +42,7 @@ Daniel-Constantin Mierla
 
    1.1. Set alias_subdomains parameter
    1.2. append_branch usage
+   1.3. send usage
 
 Chapter 1. Admin Guide
 
@@ -58,6 +61,8 @@ Chapter 1. Admin Guide
    4. Functions
 
         4.1. append_branch([ uri, [ q ] ])
+        4.2. send([ host [ :port ] ])
+        4.3. send_tcp([ host [ :port ] ])
 
    5. RPC Commands
 
@@ -104,7 +109,7 @@ Chapter 1. Admin Guide
    'proto:domain:port', allowing to set restrictions on protocol and port
    as well. Protocol and port are optional.
 
-   Default value is "NULL".
+   Default value is “NULL”.
 
    Example 1.1. Set alias_subdomains parameter
 ...
@@ -115,8 +120,10 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
 4. Functions
 
    4.1. append_branch([ uri, [ q ] ])
+   4.2. send([ host [ :port ] ])
+   4.3. send_tcp([ host [ :port ] ])
 
-4.1. append_branch([ uri, [ q ] ])
+4.1.  append_branch([ uri, [ q ] ])
 
    Append a new branch to the destination set, useful to build the
    addresses for parallel forking or redirect replies.
@@ -138,19 +145,46 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
     append_branch("$avp(uri)", "0.5");
 ...
 
+4.2.  send([ host [ :port ] ])
+
+   Send the original SIP message to a specific destination in stateless
+   mode. No changes are applied to received message, no Via header is
+   added. Host can be an IP address or hostname. Port is optional and
+   defaults to 5060. Used protocol: UDP.
+
+   The parameter is optional and defaults to the destination URI from the
+   SIP message if left out. Otherwise it's a string parameter (supporting
+   pseudo-variables) in format "hostname" or "hostname:port", where
+   hostname" can also be a numeric IP address.
+
+   This function can be used from REQUEST_ROUTE or FAILURE_ROUTE.
+
+   Example 1.3. send usage
+...
+        send();
+        send("10.20.15.10");
+        send("sip.example.com:5070");
+        send("$var(res)");
+...
+
+4.3.  send_tcp([ host [ :port ] ])
+
+   This function is identical to send() described above, except that it
+   sends the SIP message using the TCP protocol instead of UDP.
+
 5. RPC Commands
 
    5.1. corex.list_sockets
    5.2. corex.list_aliases
 
-5.1. corex.list_sockets
+5.1.  corex.list_sockets
 
    Print the list of sockets the application is listening on.
 
    Example:
                 sercmd corex.list_sockets
 
-5.2. corex.list_aliases
+5.2.  corex.list_aliases
 
    Print the list of hostname aliases used to match myself condition.
 
index 1f69847..cfe49fd 100644 (file)
@@ -27,6 +27,8 @@
 #include "../../dprint.h"
 #include "../../dset.h"
 #include "../../forward.h"
+#include "../../parser/parse_uri.h"
+#include "../../resolve.h"
 
 #include "corex_lib.h"
 
@@ -211,3 +213,88 @@ int corex_register_check_self(void)
        }
        return 0;
 }
+
+int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
+{
+       str dest = {0};
+       int ret = 0;
+       struct sip_uri next_hop, *u;
+       struct dest_info dst;
+       char *p;
+
+       if (pu)
+       {
+               if (fixup_get_svalue(msg, pu, &dest))
+               {
+                       LM_ERR("cannot get the destination parameter\n");
+                       return -1;
+               }
+       }
+
+       init_dest_info(&dst);
+
+       if (dest.len <= 0)
+       {
+               /*get next hop uri uri*/
+               if (msg->dst_uri.len) {
+                       ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
+                                                       &next_hop);
+                       u = &next_hop;
+               } else {
+                       ret = parse_sip_msg_uri(msg);
+                       u = &msg->parsed_uri;
+               }
+
+               if (ret<0) {
+                       LM_ERR("send() - bad_uri dropping packet\n");
+                       ret=E_BUG;
+                       goto error;
+               }
+       }
+       else
+       {
+               u = &next_hop;
+               u->port_no = 5060;
+               u->host = dest;
+               p = memchr(dest.s, ':', dest.len);
+               if (p)
+               {
+                       u->host.len = p - dest.s;
+                       p++;
+                       u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
+               }
+       }
+
+       ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
+                               &dst.proto);
+       if(ret!=0) {
+               LM_ERR("failed to resolve [%.*s]\n", u->host.len,
+                       ZSW(u->host.s));
+               ret=E_BUG;
+               goto error;
+       }
+
+       dst.proto = proto;
+       if (proto == PROTO_UDP)
+       {
+               dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
+               if (dst.send_sock!=0){
+                       ret=udp_send(&dst, msg->buf, msg->len);
+               }else{
+                       ret=-1;
+               }
+       }
+#ifdef USE_TCP
+       else{
+               /*tcp*/
+               dst.id=0;
+               ret=tcp_send(&dst, 0, msg->buf, msg->len);
+       }
+#endif
+
+       if (ret>=0) ret=1;
+
+
+error:
+       return ret;
+}
index 49fa712..433e28a 100644 (file)
@@ -25,6 +25,7 @@
 #include "../../mod_fix.h"
 
 int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq);
+int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto);
 
 int corex_add_alias_subdomains(char* aliasval);
 
index 5b4690c..bddba03 100644 (file)
@@ -34,6 +34,8 @@
 MODULE_VERSION
 
 static int w_append_branch(sip_msg_t *msg, char *su, char *sq);
+static int w_send(sip_msg_t *msg, char *su, char *sq);
+static int w_send_tcp(sip_msg_t *msg, char *su, char *sq);
 
 int corex_alias_subdomains_param(modparam_t type, void *val);
 
@@ -48,6 +50,14 @@ static cmd_export_t cmds[]={
                        0, REQUEST_ROUTE | FAILURE_ROUTE },
        {"append_branch", (cmd_function)w_append_branch, 2, fixup_spve_spve,
                        0, REQUEST_ROUTE | FAILURE_ROUTE },
+       {"send", (cmd_function)w_send, 0, 0,
+                       0, REQUEST_ROUTE | FAILURE_ROUTE },
+       {"send", (cmd_function)w_send, 1, fixup_spve_spve,
+                       0, REQUEST_ROUTE | FAILURE_ROUTE },
+       {"send_tcp", (cmd_function)w_send_tcp, 0, 0,
+                       0, REQUEST_ROUTE | FAILURE_ROUTE },
+       {"send_tcp", (cmd_function)w_send_tcp, 1, fixup_spve_null,
+                       0, REQUEST_ROUTE | FAILURE_ROUTE },
 
 
        {0, 0, 0, 0, 0, 0}
@@ -123,6 +133,22 @@ static int w_append_branch(sip_msg_t *msg, char *su, char *sq)
        return 1;
 }
 
+/**
+ * config wrapper for send() and send_tcp()
+ */
+static int w_send(sip_msg_t *msg, char *su, char *sq)
+{
+       if(corex_send(msg, (gparam_t*)su, PROTO_UDP) < 0)
+               return -1;
+       return 1;
+}
+static int w_send_tcp(sip_msg_t *msg, char *su, char *sq)
+{
+       if(corex_send(msg, (gparam_t*)su, PROTO_TCP) < 0)
+               return -1;
+       return 1;
+}
+
 
 int corex_alias_subdomains_param(modparam_t type, void *val)
 {
index 69e687c..5dd72e7 100644 (file)
@@ -132,6 +132,52 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
 </programlisting>
            </example>
        </section>
+
+       <section>
+               <title>
+                       <function moreinfo="none">send([ host [ :port ] ])</function>
+               </title>
+               <para>
+                       Send the original SIP message to a specific destination in stateless
+                       mode. No changes are applied to received message, no Via header is
+                       added. Host can be an IP address or hostname. Port is optional and
+                       defaults to 5060. Used protocol: UDP.
+               </para>
+               <para>
+                       The parameter is optional and defaults to the destination URI from
+                       the SIP message if left out. Otherwise it's a string parameter
+                       (supporting pseudo-variables) in format
+                       "<emphasis>hostname</emphasis>" or
+                       "<emphasis>hostname</emphasis>:<emphasis>port</emphasis>",
+                       where <emphasis>hostname</emphasis>" can also be a numeric IP
+                       address.
+               </para>
+               <para>
+                       This function can be used from REQUEST_ROUTE or FAILURE_ROUTE.
+               </para>
+               <example>
+               <title><function>send</function> usage</title>
+               <programlisting format="linespecific">
+...
+       send();
+       send("10.20.15.10");
+       send("sip.example.com:5070");
+       send("$var(res)");
+...
+</programlisting>
+               </example>
+       </section>
+
+       <section>
+               <title>
+                       <function moreinfo="none">send_tcp([ host [ :port ] ])</function>
+               </title>
+               <para>
+                       This function is identical to <emphasis>send()</emphasis>
+                       described above, except that it sends the SIP message using the
+                       TCP protocol instead of UDP.
+               </para>
+       </section>
        </section>
 
        <section>
index e9372fa..e825054 100644 (file)
@@ -46,7 +46,6 @@ static str _dbg_action_special[] = {
 
 static dbg_action_t _dbg_action_list[] = {
        { FORWARD_T, str_init("forward") },
-       { SEND_T, str_init("send") },
        { LOG_T, str_init("log") },
        { ERROR_T, str_init("error") },
        { ROUTE_T, str_init("route") },
@@ -82,7 +81,6 @@ static dbg_action_t _dbg_action_list[] = {
        { FORWARD_UDP_T, str_init("forward_udp") },
        { FORWARD_TLS_T, str_init("forward_tls") },
        { FORWARD_SCTP_T, str_init("forward_sctp") },
-       { SEND_TCP_T, str_init("send_tcp") },
        { FORCE_RPORT_T, str_init("force_rport") },
        { ADD_LOCAL_RPORT_T, str_init("add_local_rport") },
        { SET_ADV_ADDR_T, str_init("set_adv_addr") },
diff --git a/route.c b/route.c
index 7990cfd..17c1b56 100644 (file)
--- a/route.c
+++ b/route.c
@@ -663,8 +663,6 @@ int fix_actions(struct action* a)
                        case FORWARD_TCP_T:
                        case FORWARD_SCTP_T:
                        case FORWARD_UDP_T:
-                       case SEND_T:
-                       case SEND_TCP_T:
                                        switch(t->val[0].type){
                                                case IP_ST:
                                                        tmp=strdup(ip_addr2a(
index d2dee05..b46b1b7 100644 (file)
@@ -371,12 +371,6 @@ void print_action(struct action* t)
                case FORWARD_UDP_T:
                        DBG("forward_udp(");
                        break;
-               case SEND_T:
-                       DBG("send(");
-                       break;
-               case SEND_TCP_T:
-                       DBG("send_tcp(");
-                       break;
                case DROP_T:
                        DBG("drop(");
                        break;
index b176b9c..e56f4c0 100644 (file)
@@ -79,7 +79,7 @@ enum _expr_l_type{
           SNDAF_O, RETCODE_O, SELECT_O, PVAR_O, RVEXP_O, SELECT_UNFIXED_O};
 /* action types */
 enum action_type{
-               FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
+               FORWARD_T=1, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
                SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
                SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T, SET_HOSTALL_T,
                SET_USERPHONE_T,
@@ -100,7 +100,6 @@ enum action_type{
                FORWARD_UDP_T,
                FORWARD_TLS_T,
                FORWARD_SCTP_T,
-               SEND_TCP_T,
                FORCE_RPORT_T,
                ADD_LOCAL_RPORT_T,
                SET_ADV_ADDR_T,