- added the missing force_send_socket script command
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 30 Nov 2004 16:28:23 +0000 (16:28 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 30 Nov 2004 16:28:23 +0000 (16:28 +0000)
12 files changed:
Makefile.defs
NEWS
action.c
cfg.lex
cfg.y
etc/ser.cfg
ip_addr.h
main.c
route.c
route_struct.c
route_struct.h
socket_info.c

index 4a25272..abb0ed6 100644 (file)
@@ -50,7 +50,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL =   99
-EXTRAVERSION = -dev19
+EXTRAVERSION = -dev20
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
diff --git a/NEWS b/NEWS
index 6342b98..619edd7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -107,6 +107,11 @@ core:
    unix_tx_timeout = 2000
        Timeout (in ms) used when sending replies through unix sockets.
  - new script commands:
+   force_send_socket([proto:]address[:port])
+       sends the message from the specified socket (it _must_ be one of the
+       sockets ser listens on). If the protocol doesn't match (e.g. udp
+       message "forced" to a tcp socket) the closest socket of the same
+       protocol is used.
    force_tcp_alias()
    force_tcp_alias(port)
        adds a tcp port alias for the current connection (if tcp).
index 723b3c8..5a5ab82 100644 (file)
--- a/action.c
+++ b/action.c
@@ -36,6 +36,7 @@
  *  2003-04-22  strip_tail added (jiri)
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
+ *  2004-11-30  added FORCE_SEND_SOCKET_T (andrei)
  */
 
 
@@ -663,6 +664,16 @@ int do_action(struct action* a, struct sip_msg* msg)
 #endif
                        ret=1; /* continue processing */
                        break;
+               case FORCE_SEND_SOCKET_T:
+                       if (a->p1_type!=SOCKETINFO_ST){
+                               LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
+                                               " type: %d\n", a->p1_type);
+                               ret=E_BUG;
+                               break;
+                       }
+                       msg->force_send_socket=(struct socket_info*)a->p1.data;
+                       ret=1; /* continue processing */
+                       break;
                default:
                        LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
        }
diff --git a/cfg.lex b/cfg.lex
index 1fc2e6f..f9c51c9 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -51,6 +51,7 @@
  *              added MCAST_TTL (andrei)
  *  2004-10-08  more escapes: \", \xHH, \nnn and minor optimizations (andrei)
  *  2004-10-19  added FROM_URI and TO_URI (andrei)
+ *  2004-11-30  added force_send_socket
  */
 
 
@@ -129,6 +130,7 @@ IF                          "if"
 ELSE                   "else"
 SET_ADV_ADDRESS        "set_advertised_address"
 SET_ADV_PORT   "set_advertised_port"
+FORCE_SEND_SOCKET      "force_send_socket"
 
 /*ACTION LVALUES*/
 URIHOST                        "uri:host"
@@ -321,6 +323,8 @@ EAT_ABLE    [\ \t\b\r]
                                                                                return SET_ADV_ADDRESS; }
 <INITIAL>{SET_ADV_PORT}        { count(); yylval.strval=yytext;
                                                                                return SET_ADV_PORT; }
+<INITIAL>{FORCE_SEND_SOCKET}   {       count(); yylval.strval=yytext;
+                                                                       return FORCE_SEND_SOCKET; }
 
 <INITIAL>{URIHOST}     { count(); yylval.strval=yytext; return URIHOST; }
 <INITIAL>{URIPORT}     { count(); yylval.strval=yytext; return URIPORT; }
diff --git a/cfg.y b/cfg.y
index c7972c5..c946f06 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -57,6 +57,7 @@
  * 2004-07-05  src_ip & dst_ip will detect ip addresses between quotes
  *              (andrei)
  * 2004-10-19  added FROM_URI, TO_URI (andrei)
+ * 2004-11-30  added force_send_socket (andrei)
  */
 
 
  with no built in alloca, like icc*/
 #undef _ALLOCA_H
 
-struct id_list{
-       char* name;
-       int proto;
-       int port;
-       struct id_list* next;
-};
 
 extern int yylex();
 static void yyerror(char* s);
 static char* tmp;
 static int i_tmp;
 static void* f_tmp;
-static struct id_list* lst_tmp;
+static struct socket_id* lst_tmp;
 static int rt;  /* Type of route block for find_export */
 static str* str_tmp;
 static str s_tmp;
 static struct ip_addr* ip_tmp;
 
 static void warn(char* s);
-static struct id_list* mk_listen_id(char*, int, int);
+static struct socket_id* mk_listen_id(char*, int, int);
  
 
 %}
@@ -129,7 +124,7 @@ static struct id_list* mk_listen_id(char*, int, int);
        struct action* action;
        struct net* ipnet;
        struct ip_addr* ipaddr;
-       struct id_list* idlst;
+       struct socket_id* sockid;
 }
 
 /* terminals */
@@ -166,6 +161,7 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token ELSE
 %token SET_ADV_ADDRESS
 %token SET_ADV_PORT
+%token FORCE_SEND_SOCKET
 %token URIHOST
 %token URIPORT
 %token MAX_LEN
@@ -297,8 +293,8 @@ static struct id_list* mk_listen_id(char*, int, int);
 %type <ipnet> ipnet
 %type <strval> host
 %type <strval> listen_id
-%type <idlst>  id_lst
-%type <idlst>  phostport
+%type <sockid>  id_lst
+%type <sockid>  phostport
 %type <intval> proto port
 %type <intval> equalop strop intop
 %type <strval> host_sep
@@ -1609,6 +1605,13 @@ cmd:             FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                | SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
                                                                                                                "string expected"); }
                | SET_ADV_PORT  error {$$=0; yyerror("missing '(' or ')' ?"); }
+               | FORCE_SEND_SOCKET LPAREN phostport RPAREN {
+                                                                               $$=mk_action(FORCE_SEND_SOCKET_T,
+                                                                                                               SOCKID_ST, 0, $3, 0);
+                                                                                                       }
+               | FORCE_SEND_SOCKET LPAREN error RPAREN { $$=0; yyerror("bad argument,"
+                                                                                       " [proto:]host[:port] expected"); }
+               | FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
                | ID LPAREN RPAREN                      { f_tmp=(void*)find_export($1, 0, rt);
                                                                           if (f_tmp==0){
                                                                                   if (find_export($1, 0, 0)) {
@@ -1690,10 +1693,10 @@ static void yyerror(char* s)
 }
 
 
-static struct id_list* mk_listen_id(char* host, int proto, int port)
+static struct socket_id* mk_listen_id(char* host, int proto, int port)
 {
-       struct id_list* l;
-       l=pkg_malloc(sizeof(struct id_list));
+       struct socket_id* l;
+       l=pkg_malloc(sizeof(struct socket_id));
        if (l==0){
                LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
        }else{
index dda2a5e..69f565c 100644 (file)
@@ -80,6 +80,12 @@ route{
                sl_send_reply("513", "Message too big");
                break;
        };
+       
+       if (src_ip==193.175.135.0/24){
+               force_send_socket(smaug:5080);
+               forward(193.175.135.179);
+               break;
+       }
 
        # we record-route all messages -- to make sure that
        # subsequent messages will go through our proxy; that's
index afe43d0..0b50268 100644 (file)
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -118,6 +118,14 @@ struct dest_info{
 };
 
 
+struct socket_id{
+       char* name;
+       int proto;
+       int port;
+       struct socket_id* next;
+};
+
+
 
 /* len of the sockaddr */
 #ifdef HAVE_SOCKADDR_SA_LEN
diff --git a/main.c b/main.c
index 27c5738..d9d6d4a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1431,7 +1431,7 @@ try_again:
        }
        /* fix routing lists */
        if ( (r=fix_rls())!=0){
-               fprintf(stderr, "ERROR: error %x while trying to fix configuration\n",
+               fprintf(stderr, "ERROR: error %d while trying to fix configuration\n",
                                                r);
                goto error;
        };
diff --git a/route.c b/route.c
index b26a8df..ae8a31b 100644 (file)
--- a/route.c
+++ b/route.c
@@ -61,6 +61,7 @@
 #include "sr_module.h"
 #include "ip_addr.h"
 #include "resolve.h"
+#include "socket_info.h"
 #include "parser/parse_uri.h"
 #include "parser/parse_from.h"
 #include "parser/parse_to.h"
@@ -154,6 +155,9 @@ static int fix_actions(struct action* a)
        cmd_export_t* cmd;
        struct sr_module* mod;
        str s;
+       struct hostent* he;
+       struct ip_addr ip;
+       struct socket_info* si;
        
        if (a==0){
                LOG(L_CRIT,"BUG: fix_actions: null pointer\n");
@@ -242,7 +246,29 @@ static int fix_actions(struct action* a)
                                                }
                                        }
                                }
-                       
+                               break;
+                       case FORCE_SEND_SOCKET_T:
+                               if (t->p1_type!=SOCKID_ST){
+                                       LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
+                                                               "%d for force_send_socket\n",
+                                                               t->p1_type);
+                                       return E_BUG;
+                               }
+                               he=resolvehost(((struct socket_id*)t->p1.data)->name);
+                               if (he==0) return E_BAD_ADDRESS;
+                               hostent2ip_addr(&ip, he, 0);
+                               si=find_si(&ip, ((struct socket_id*)t->p1.data)->port,
+                                                               ((struct socket_id*)t->p1.data)->proto);
+                               if (si==0){
+                                       LOG(L_ERR, "ERROR: fix_actions: bad force_send_socket"
+                                                       " argument: %s:%d (ser doesn't listen on it)\n",
+                                                       ((struct socket_id*)t->p1.data)->name,
+                                                       ((struct socket_id*)t->p1.data)->port);
+                                       return E_BAD_ADDRESS;
+                               }
+                               t->p1.data=si;
+                               t->p1_type=SOCKETINFO_ST;
+                               break;
                }
        }
        return 0;
index 3c2f709..65ec981 100644 (file)
@@ -340,6 +340,9 @@ void print_action(struct action* a)
                        case AVP_TO_URI_T:
                                        DBG("avp_to_attr");
                                        break;
+                       case FORCE_SEND_SOCKET_T:
+                                       DBG("force_send_socket");
+                                       break;
                        default:
                                        DBG("UNKNOWN(");
                }
@@ -362,6 +365,13 @@ void print_action(struct action* a)
                        case CMDF_ST:
                                        DBG("f_ptr<%p>",t->p1.data);
                                        break;
+                       case SOCKID_ST:
+                                       DBG("%d:%s:%d",
+                                                       ((struct socket_id*)t->p1.data)->proto,
+                                                       ((struct socket_id*)t->p1.data)->name,
+                                                       ((struct socket_id*)t->p1.data)->port
+                                                       );
+                                       break;
                        default:
                                        DBG("type<%d>", t->p1_type);
                }
@@ -381,6 +391,13 @@ void print_action(struct action* a)
                        case ACTIONS_ST:
                                        print_action((struct action*)t->p2.data);
                                        break;
+                       case SOCKID_ST:
+                                       DBG("%d:%s:%d",
+                                                       ((struct socket_id*)t->p1.data)->proto,
+                                                       ((struct socket_id*)t->p1.data)->name,
+                                                       ((struct socket_id*)t->p1.data)->port
+                                                       );
+                                       break;
                        default:
                                        DBG(", type<%d>", t->p2_type);
                }
@@ -400,6 +417,13 @@ void print_action(struct action* a)
                        case ACTIONS_ST:
                                        print_action((struct action*)t->p3.data);
                                        break;
+                       case SOCKID_ST:
+                                       DBG("%d:%s:%d",
+                                                       ((struct socket_id*)t->p1.data)->proto,
+                                                       ((struct socket_id*)t->p1.data)->name,
+                                                       ((struct socket_id*)t->p1.data)->port
+                                                       );
+                                       break;
                        default:
                                        DBG(", type<%d>", t->p3_type);
                }
index b3dec0d..de42c21 100644 (file)
@@ -75,11 +75,12 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
                SET_ADV_PORT_T,
                FORCE_TCP_ALIAS_T,
                LOAD_AVP_T,
-               AVP_TO_URI_T
+               AVP_TO_URI_T,
+               FORCE_SEND_SOCKET_T
 };
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
                EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
-               MYSELF_ST, STR_ST };
+               MYSELF_ST, STR_ST, SOCKID_ST, SOCKETINFO_ST };
 
        
 struct expr{
index bb19e26..13be9d5 100644 (file)
@@ -361,6 +361,13 @@ int add_listen_iface(char* name, unsigned short port, unsigned short proto,
                        LOG(L_ERR, "ERROR: add_listen_iface: get_sock_info_list failed\n");
                        goto error;
                }
+               if (port==0){ /* use default port */
+                       port=
+#ifdef USE_TLS
+                               ((c_proto)==PROTO_TLS)?tls_port_no:
+#endif
+                               port_no;
+               }
                if (new_sock2list(name, port, c_proto, flags, list)<0){
                        LOG(L_ERR, "ERROR: add_listen_iface: new_sock2list failed\n");
                        goto error;