Module: sip-router
Branch: oej/routeblocks
Commit: 9135bf2470d64ccbfdddf0fe3c2f7c97dd0e7bd6
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9135bf2…
Author: Olle E. Johansson <oej(a)edvina.net>
Committer: Olle E. Johansson <oej(a)edvina.net>
Date: Sat Jan 12 08:30:08 2013 +0100
Trying to implement route_if_exists(ROUTE) and route_exists(route) functions
---
action.c | 23 +++++++++++++++++++++++
cfg.lex | 2 ++
cfg.y | 12 ++++++++++++
modules_k/cfgutils/cfgutils.c | 12 ++++++++++++
route_struct.h | 2 +-
5 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/action.c b/action.c
index e64cf81..c2b5bdd 100644
--- a/action.c
+++ b/action.c
@@ -646,6 +646,29 @@ int do_action(struct run_act_ctx* h, struct action* a, struct
sip_msg* msg)
"not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
ret=1;
break;
+ case ROUTE_IF_T:
+ rv = rval_expr_eval(h, msg, a->val[0].u.data);
+ rval_cache_init(&c1);
+ if (unlikely(rv == 0 || rval_get_tmp_str(h, msg, &s, rv, 0, &c1) < 0)) {
+ rval_destroy(rv);
+ rval_cache_clean(&c1);
+ ERR("failed to convert RVE to string\n");
+ ret = E_UNSPEC;
+ goto error;
+ }
+ i = route_lookup(&main_rt, s.s);
+ rval_destroy(rv);
+ rval_cache_clean(&c1);
+ s.s = 0;
+ if (unlikely(i < 0)) {
+ /* Give up silently */
+ break;
+ }
+ ret=run_actions(h, main_rt.rlist[i], msg);
+ h->last_retcode=ret;
+ _last_returned_code = h->last_retcode;
+ h->run_flags&=~(RETURN_R_F|BREAK_R_F); /* absorb return & break */
+ break;
case ROUTE_T:
if (likely(a->val[0].type == NUMBER_ST))
i = a->val[0].u.number;
diff --git a/cfg.lex b/cfg.lex
index 7bc6e68..810a700 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -198,6 +198,7 @@ BREAK "break"
LOG log
ERROR error
ROUTE route
+ROUTE_IF route_if_exist
ROUTE_REQUEST request_route
ROUTE_FAILURE failure_route
ROUTE_REPLY reply_route
@@ -617,6 +618,7 @@ IMPORTFILE "import_file"
<INITIAL>{AVPFLAGS_DECL} { count(); yylval.strval=yytext; return AVPFLAGS_DECL; }
<INITIAL>{MSGLEN} { count(); yylval.strval=yytext; return MSGLEN; }
<INITIAL>{ROUTE} { count(); yylval.strval=yytext; return ROUTE; }
+<INITIAL>{ROUTE_IF} { count(); yylval.strval=yytext; return ROUTE_IF; }
<INITIAL>{ROUTE_REQUEST} { count(); yylval.strval=yytext; return ROUTE_REQUEST; }
<INITIAL>{ROUTE_ONREPLY} { count(); yylval.strval=yytext;
return ROUTE_ONREPLY; }
diff --git a/cfg.y b/cfg.y
index 0c4fb5d..f573b31 100644
--- a/cfg.y
+++ b/cfg.y
@@ -300,6 +300,7 @@ extern char *finame;
/* keywords */
+%token ROUTE_IF
%token FORWARD
%token FORWARD_TCP
%token FORWARD_TLS
@@ -3242,6 +3243,17 @@ cmd:
}
| ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
| ERROR LPAREN error RPAREN { $$=0; yyerror("bad error argument"); }
+ | ROUTE_IF LPAREN ID RPAREN {
+ if ($3) {
+ $$ = mk_action(ROUTE_IF_T, 1, STRING_ST, (void*)$3);
+ set_cfg_pos($$);
+ } else {
+ $$ = 0;
+ YYERROR;
+ }
+ }
+ | ROUTE_IF error { $$=0; yyerror("missing '(' or ')' ?"); }
+ | ROUTE_IF LPAREN error RPAREN { $$=0; yyerror("bad route_if_exist argument");
}
| ROUTE LPAREN rval_expr RPAREN {
if ($3) {
$$ = mk_action(ROUTE_T, 1, RVE_ST, (void*)$3);
diff --git a/modules_k/cfgutils/cfgutils.c b/modules_k/cfgutils/cfgutils.c
index 37c106a..de775af 100644
--- a/modules_k/cfgutils/cfgutils.c
+++ b/modules_k/cfgutils/cfgutils.c
@@ -1,6 +1,7 @@
/*
* $Id$
*
+ * Copyright (C) 2012 Edvina AB
* Copyright (C) 2007 1&1 Internet AG
* Copyright (C) 2007 BASIS AudioNet GmbH
* Copyright (C) 2004 FhG
@@ -70,6 +71,7 @@
#include "../../globals.h"
#include "../../hashes.h"
#include "../../locking.h"
+#include "../../route.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -91,6 +93,7 @@ static int dbg_pkg_status(struct sip_msg*, char*,char*);
static int dbg_shm_status(struct sip_msg*, char*,char*);
static int dbg_pkg_summary(struct sip_msg*, char*,char*);
static int dbg_shm_summary(struct sip_msg*, char*,char*);
+static int route_exists(struct sip_msg*, char*);
static int set_gflag(struct sip_msg*, char *, char *);
static int reset_gflag(struct sip_msg*, char *, char *);
@@ -178,6 +181,8 @@ static cmd_export_t cmds[]={
ANY_ROUTE},
{"core_hash", (cmd_function)w_core_hash, 3, fixup_core_hash, 0,
ANY_ROUTE},
+ {"route_exists", (cmd_function)route_exists, 1, 0, 0,
+ ANY_ROUTE},
{"bind_cfgutils", (cmd_function)bind_cfgutils, 0,
0, 0, 0},
{0, 0, 0, 0, 0, 0}
@@ -737,6 +742,13 @@ static int cfg_unlock(struct sip_msg *msg, char *key, char *s2)
return cfg_lock_wrapper(msg, (gparam_p)key, 1);
}
+static int route_exists(struct sip_msg *msg, char *route)
+{
+ if (route_lookup(&main_rt, route))
+ return 1;
+ return 0;
+}
+
static int mod_init(void)
{
diff --git a/route_struct.h b/route_struct.h
index e56f4c0..faa9006 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -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, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
+ FORWARD_T=1, DROP_T, LOG_T, ERROR_T, ROUTE_T, ROUTE_IF_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,