TM callbacks, acc, flags
authorJiri Kuthan <jiri@iptel.org>
Mon, 13 May 2002 01:15:40 +0000 (01:15 +0000)
committerJiri Kuthan <jiri@iptel.org>
Mon, 13 May 2002 01:15:40 +0000 (01:15 +0000)
44 files changed:
Makefile.defs
Makefile.sources
action.c
action.h
cfg.lex
cfg.y
data_lump_rpl.h
etc/iptel.cfg
flags.c [new file with mode: 0644]
flags.h [new file with mode: 0644]
forward.c
forward.h
main.c
modules/tm/config.h
modules/tm/h_table.h
modules/tm/sip_msg.h
modules/tm/t_flags.c [deleted file]
modules/tm/t_flags.h [deleted file]
modules/tm/t_funcs.c
modules/tm/t_funcs.h
modules/tm/t_fwd.c
modules/tm/t_hooks.c [new file with mode: 0644]
modules/tm/t_hooks.h [new file with mode: 0644]
modules/tm/t_lookup.c
modules/tm/t_reply.c
modules/tm/timer.c
modules/tm/timer.h
modules/tm/tm.c
modules/tm/tm_load.c [new file with mode: 0644]
modules/tm/tm_load.h [new file with mode: 0644]
msg_translator.h
parser/msg_parser.c [moved from msg_parser.c with 99% similarity]
parser/msg_parser.h [moved from msg_parser.h with 96% similarity]
parser/parse_fline.c [moved from parse_fline.c with 99% similarity]
parser/parse_hname.c [moved from parse_hname.c with 99% similarity]
parser/parse_hname2.c [new file with mode: 0644]
parser/parse_to.c [moved from parse_to.c with 99% similarity]
parser/parse_via.c [moved from parse_via.c with 99% similarity]
parser/parser_f.c [moved from parser_f.c with 96% similarity]
parser/parser_f.h [moved from parser_f.h with 100% similarity]
receive.c
route.h
route_struct.h
sr_module.h

index 0c10b6a..624da37 100644 (file)
@@ -8,7 +8,7 @@
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL = 7
-EXTRAVERSION = -9
+EXTRAVERSION = -7-ipaq-viadbg
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s)
@@ -81,15 +81,15 @@ ARCH = $(shell uname -m |sed -e s/i.86/i386/ -e s/sun4u/sparc64/ )
 DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
         -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"'\
         -DDNS_IP_HACK  -DPKG_MALLOC \
-        -DF_MALLOC -DUSE_SYNONIM\
+        -DF_MALLOC \
         -DSHM_MEM  -DSHM_MMAP \
         -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
         -DWAIT -DNEW_HNAME \
+        -DVERY_NOISY_REPLIES\
         #-DSILENT_FR \
-        #-DUSE_SYNONIM\
         #-DNO_DEBUG \
+        #-DUSE_SYNONIM\
         #-DNOISY_REPLIES \
-        #-DBOGDAN_TRIFLE \
         #-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \
         #-DNOSMP \
         #-DEXTRA_DEBUG 
@@ -102,8 +102,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 
 
 #PROFILE=  -pg #set this if you want profiling
-#mode = debug
-mode = release
+mode = debug
+#mode = release
 
 # platform dependent settings
 
@@ -374,7 +374,7 @@ ifeq  ($(OS), SunOS)
 ifeq ($(CC_NAME), suncc)
        LIBS=-lfast
 endif
-       LIBS+=-ldl -L/usr/local/lib -lfl -lxnet -lrt
+       LIBS+=-ldl -L/usr/local/lib -L/usr/lib/mysql -lfl -lxnet -lrt
        # -lrt needed for sched_yield
 endif
 
index ff16dbd..3f5d46b 100644 (file)
@@ -11,7 +11,7 @@
 # defines: sources, objs, depends
 #
 
-sources=$(filter-out $(auto_gen), $(wildcard *.c) $(wildcard mem/*.c) ) $(auto_gen)
+sources=$(filter-out $(auto_gen), $(wildcard *.c) $(wildcard mem/*.c) $(wildcard parser/*.c) ) $(auto_gen)
 objs=$(sources:.c=.o)
 extra_objs=
 depends=$(sources:.c=.d)
index 98aec07..dbaa6d0 100644 (file)
--- a/action.c
+++ b/action.c
@@ -12,7 +12,7 @@
 #include "forward.h"
 #include "udp_server.h"
 #include "route.h"
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 #include "ut.h"
 #include "sr_module.h"
 #include "mem/mem.h"
@@ -167,6 +167,54 @@ int do_action(struct action* a, struct sip_msg* msg)
                        LOG(a->p1.number, a->p2.string);
                        ret=1;
                        break;
+
+               /* jku - begin : flag processing */
+
+               case SETFLAG_T:
+                       if (a->p1_type!=NUMBER_ST) {
+                               LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
+                                       a->p1_type );
+                               ret=E_BUG;
+                               break;
+                       }
+                       if (!flag_in_range( a->p1.number )) {
+                               ret=E_CFG;
+                               break;
+                       }
+                       setflag( msg, a->p1.number );
+                       ret=1;
+                       break;
+
+               case RESETFLAG_T:
+                       if (a->p1_type!=NUMBER_ST) {
+                               LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
+                                       a->p1_type );
+                               ret=E_BUG;
+                               break;
+                       }
+                       if (!flag_in_range( a->p1.number )) {
+                               ret=E_CFG;
+                               break;
+                       }
+                       resetflag( msg, a->p1.number );
+                       ret=1;
+                       break;
+                       
+               case ISFLAGSET_T:
+                       if (a->p1_type!=NUMBER_ST) {
+                               LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
+                                       a->p1_type );
+                               ret=E_BUG;
+                               break;
+                       }
+                       if (!flag_in_range( a->p1.number )) {
+                               ret=E_CFG;
+                               break;
+                       }
+                       ret=isflagset( msg, a->p1.number );
+                       break;
+               /* jku - end : flag processing */
+
                case ERROR_T:
                        if ((a->p1_type!=STRING_ST)|(a->p2_type!=STRING_ST)){
                                LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
index 64ba10d..5b55d9d 100644 (file)
--- a/action.h
+++ b/action.h
@@ -6,7 +6,7 @@
 #ifndef action_h
 #define action_h
 
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 #include "route_struct.h"
 
 int do_action(struct action* a, struct sip_msg* msg);
diff --git a/cfg.lex b/cfg.lex
index 432fd53..ecae237 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -46,6 +46,9 @@ LOG           log
 ERROR  error
 ROUTE  route
 EXEC   exec
+SETFLAG                setflag
+RESETFLAG      resetflag
+ISFLAGSET      isflagset
 SET_HOST               "rewritehost"|"sethost"|"seth"
 SET_HOSTPORT   "rewritehostport"|"sethostport"|"sethp"
 SET_USER               "rewriteuser"|"setuser"|"setu"
@@ -131,6 +134,9 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{SEND}        { count(); yylval.strval=yytext; return SEND; }
 <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; }
+<INITIAL>{RESETFLAG}   { count(); yylval.strval=yytext; return RESETFLAG; }
+<INITIAL>{ISFLAGSET}   { count(); yylval.strval=yytext; return ISFLAGSET; }
 <INITIAL>{ROUTE}       { count(); yylval.strval=yytext; return ROUTE; }
 <INITIAL>{EXEC}        { count(); yylval.strval=yytext; return EXEC; }
 <INITIAL>{SET_HOST}    { count(); yylval.strval=yytext; return SET_HOST; }
diff --git a/cfg.y b/cfg.y
index ad426f3..50e3ac3 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -62,7 +62,9 @@ void* f_tmp;
 %token ELSE
 %token URIHOST
 %token URIPORT
-
+%token SETFLAG
+%token RESETFLAG
+%token ISFLAGSET
 %token METHOD
 %token URI
 %token SRCIP
@@ -557,13 +559,21 @@ cmd:              FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                | LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
                | LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
                                                                        "argument"); }
+               | SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
+                                                                                                       (void *)$3, 0 ); }
+               | SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
+               | RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action( RESETFLAG_T, NUMBER_ST, 0,
+                                                                                                       (void *)$3, 0 ); }
+               | RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
+               | ISFLAGSET LPAREN NUMBER RPAREN {$$=mk_action( ISFLAGSET_T, NUMBER_ST, 0,
+                                                                                                       (void *)$3, 0 ); }
+               | ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
                | ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
                                                                                                                                STRING_ST, 
                                                                                                                                STRING_ST,
                                                                                                                                $3,
                                                                                                                                $5);
                                                                                                  }
-                                                                                               
                | ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
                | ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
                                                                                                                "argument"); }
index 93f680e..b5b2c97 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef data_lump_rpl_h
 #define data_lump_rpl_h
 
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 
 
 struct lump_rpl
index 6bf24c5..0c9d178 100644 (file)
@@ -1,17 +1,21 @@
 #
-# iptel.org real world configuration
-#
 # $Id$
 #
+# iptel.org real world configuration
+#
+
+# ----------- global configuration parameters ------------------------
 
 debug=3          # debug level (cmd line: -dddddddddd)
-fork=yes
-log_stderror=no        # (cmd line: -E)
-#log_stderror=yes      # (cmd line: -E)
+#fork=yes
+fork=no
+#log_stderror=no       # (cmd line: -E)
+log_stderror=yes       # (cmd line: -E)
 check_via=yes     # (cmd. line: -v)
 dns=on           # (cmd. line: -r)
 rev_dns=yes      # (cmd. line: -R)
-port=5060
+#port=5060
+port=8060
 children=1
 
 # advertise IP address in Via (as opposed to advertising DNS name
@@ -19,9 +23,12 @@ children=1
 # not handle DNS at all)
 listen=195.37.77.101
 
+# ------------------ module loading ----------------------------------
+
 loadmodule "../sip_router/modules/sl/sl.so"
 loadmodule "../sip_router/modules/print/print.so"
 loadmodule "../sip_router/modules/tm/tm.so"
+loadmodule "../sip_router/modules/acc/acc.so"
 loadmodule "../sip_router/modules/rr/rr.so"
 loadmodule "../sip_router/modules/maxfwd/maxfwd.so"
 loadmodule "../sip_router/modules/mysql/mysql.so"
@@ -29,6 +36,10 @@ loadmodule "../sip_router/modules/usrloc/usrloc.so"
 loadmodule "../sip_router/modules/auth/auth.so"
 loadmodule "../sip_router/modules/cpl/cpl.so"
 
+# ----------------- setting module-specific parameters ---------------
+
+# -- usrloc params --
+
 modparam("usrloc", "use_database",   1)
 modparam("usrloc", "table",          "location")
 modparam("usrloc", "user_column",    "user")
@@ -40,16 +51,51 @@ modparam("usrloc", "cseq_column",    "cseq")
 modparam("usrloc", "flush_interval", 60)
 modparam("usrloc", "db_url",         "sql://csps:47csps11@dbhost/csps107")
 
+# -- auth params --
+
 modparam("auth", "db_url",        "sql://csps:47csps11@dbhost/csps107")
 modparam("auth", "user_column",   "user_id")
+# nonce generation secret; particularly useful if multiple servers
+# in a proxy farm are configured to authenticate
 modparam("auth", "secret",        "439tg8h349g8hq349t9384hg")
+# calculate_ha1=false means password column includes ha1 strings;
+# if it was false, plain-text passwords would be assumed
 modparam("auth", "calculate_ha1", false)
 modparam("auth", "nonce_expire",  300)
 modparam("auth", "retry_count",   5)
+# password_column, realm_column, group_table, group_user_column,
+#   group_group_column are set to their default values
+# password_column_2 allows to deal with clients who put domain name
+#   in authentication credentials when calculate_ha1=false (if true,
+#   it works); if set to a value and USER_DOMAIN_HACK was enabled
+#   in defs.h, authentication will still work
 
+# -- acc params --
+# report ACKs too for sake of completeness -- as we account PSTN
+# destinations which are RR, ACKs should show up
+modparam("acc", "report_ack", 1)
+# don't bother me with early media reports (I don't like 183 
+# too much anyway...ever thought of timer C hitting after
+# listening to music-on-hold for five minutes?)
+modparam("acc", "early_media", 0)
+modparam("acc", "log_level", 1)
+# that is the flag for which we will account -- don't forget to
+# set the same one :-)
+modparam("acc", "acc_flag", 1 )
+# we are interested only in succesful transactions
+modparam("acc", "failed_transactions", 0 )
+
+# -- tm params --
+modparam("tm", "fr_timer", 10 )
+modparam("tm", "fr_inv_timer", 30 )
+
+# -------------------------  request routing logic -------------------
+
+# main routing logic
 
 route{
-       # filter local stateless ACK generated by authentication and other replies
+
+       # filter local stateless ACK generated by authentication of mf replies
        sl_filter_ACK();
 
        # filter too old messages
@@ -71,163 +117,215 @@ route{
                break;
        };
 
+       # if this request is not for our domain, fall over to
+       # outbound request processing; include gateway's address
+       # in matching too -- we RR requests to it, so that
+       # its address may show up in subsequent requests
+       # after rewriteFromRoute
+       
+       if (!(uri=~"[@:]iptel\.org([;:].*)*" 
+               | uri=~"[@:]195\.37\.77\.101([;:].*)*" |
+               uri=~"@195\.37\.77\.110([;:].*)*" )) {
+               route(2);
+       };
+       # here we continue with requests for our domain...
+
        # various aliases (might use a database in future)
-       if (uri=~"sip:9040@.*") {
-               setuser("jiri");
+       if (uri=~"sip:9040@") {
+               seturi("jiri@iptel.org");
        };
-       # special measure for our US friends
        if (uri=~"sip:17@") {
                seturi("sip:henry@siptest.wcom.com");
        };
+       # check again, if it is still for our domain after aliases
+       if ( !(uri=~"[@:]iptel\.org([;:].*)*" | 
+               uri=~"[@:]195\.37\.77\.101([;:].*)*" |
+               uri=~"@195\.37\.77\.110([;:].*)*" )) {
+               route(2);
+       };
+       log("Request is for iptel.org\n");      
 
-       # process requests for iptel.org (note the wildcard in
-       # the regex end -- that captures URIs which have port
-       # numbers or parameters in them); also include gateway
-       # here too -- we RR to the gateway which means that its
-       # address shows up in d-uri of subsequent requests after
-       # having called rewriteFromRoute and we want the requests
-       # to go through our PSTN authorization code 
-       if (uri=~"[@:]iptel\.org([;:].*)*" | uri=~"[@:]195\.37\.77\.101([;:].*)*" |
-               uri=~"@195\.37\.77\.110([;:].*)*" ) {
-               log("Request is for iptel.org\n");      
-
-               # registers always MUST be authenticated to
-               # avoid stealing incoming calls 
-               if (method=="REGISTER") {
-                       log("Request is REGISTER\n");
-                       if (!www_authorize("iptel.org", "subscriber")) {
-                               log("REGISTER has no credentials, sending challenge\n");
-                               www_challenge("iptel.org", "0");
-                               break;
-                       };
-                       # prohibit attempts to grab someone else's address 
-                       # using someone else's valid credentials
-                       if (!check_to()) {
-                               log("Cheating attempt\n");
-                               sl_send_reply("403", "What a nasty guy you are");
-                               break;
-                       };
-                               
-                       # update Contact database
-               log("REGISTER is authorized, saving location\n");
-                       save_contact("location");
+       # registers always MUST be authenticated to
+       # avoid stealing incoming calls 
+       if (method=="REGISTER") {
+               log("Request is REGISTER\n");
+               if (!www_authorize(     "iptel.org" /* realm */, 
+                                                       "subscriber" /* table name */ )) {
+                       log("REGISTER has no credentials, sending challenge\n");
+                       www_challenge(  "iptel.org" /* realm */, 
+                                                       "0" /* no qop -- M$ can't deal with it */);
+                       break;
+               };
+               # prohibit attempts to grab someone else's To address 
+               # using  valid credentials
+               if (!check_to()) {
+                       log("To Cheating attempt\n");
+                       sl_send_reply("403", "That is ugly -- use To=id next time");
                        break;
                };
+                       
+               # update Contact database
+               log("REGISTER is authorized, saving location\n");
+               save_contact("location");
+               break;
+       };
 
+       # now check if it's about PSTN destinations through our gateway;
+       # note that 8.... is exempted for numerical destinations
+       if (uri=~"sip:[0-79][0-9]*@.*") {
+               route(3);
+       }; 
 
-               # now it's about PSTN destinations through our gateway;
-               # note that 8.... is exempted for numerical destinations
-               if (uri=~"sip:[0-79][0-9]*@.*") {
-                       # free call destinations ... no authentication needed
-                       if (uri=~"sip:001795061546@.*" | uri=~"sip:0016097265544.*" | uri=~"sip:[79][0-9][0-9][0-9]@.*") {
-                               log("Free PSTN\n");
-                       } else {
-                               # all other PSTN destinations only for authenticated users
-                               # (Cisco GW, which has no digest support, is authenticated
-                               # by its IP address -- that's for sure not very strong;
-                               # wth confirmed that we filter packets coming from outside
-                               # and bearing SRC IP address of a Fokus network)
-                               if (!(src_ip==195.37.77.110) & !(proxy_authorize("iptel.org", "subscriber"))) {
-                                       proxy_challenge("iptel.org", "0");
-                                       break;
-                               };
-                       
-                               # authorize only for INVITEs -- RR/Contact may result in weird
-                               # things showing up in d-uri that would break our logic; our
-                               # major concern is INVITE which causes PSTN costs anyway
+       # ---------- demo - begin --------------
+       /* added by Bogdan for cpl demo - Dorgham request*/
+       if (uri=~"sip:test@.*" && method=="INVITE")
+       {
+               log("SER : runing CPL!! :)\n");
+               if ( !cpl_run_script() )
+               {
+                       log("SER : Error during running CPL script!\n");
+               }else{
+                       if ( cpl_is_response_reject() ) {
+                               log("SER: reject");
+                               sl_send_reply("603","I am not available!");
+                               break;
+                       }else if ( cpl_is_response_redirect() ) {
+                               log("SER : redirect\n");
+                               cpl_update_contact();
+                               sl_send_reply("302","Moved temporarily");
+                               break;
+                       };
+               };
+       };
+       # -------------- demo - end -------------
 
-                               if (method=="INVITE") {
-       
-                                       # does the authenticated user have a permission for local
-                                       # calls? (i.e., is he in the "local" group?)
-                                       if (uri=~"sip:0[1-9][0-9]+@.*") {
-                                               if (!is_in_group("local")) {
-                                                       sl_send_reply("403", "Local Toodle Noodle...");
-                                                       break;
-                                               };
-                                       # the same for long-distance
-                                       } else if (uri=~"sip:00[1-9][0-9]+@.*") {
-                                               if (uri=~"sip:001[089]" | uri=~"sip:00900.*" ) {
-                                                               sl_send_reply("403", "Added Value Destinations not permitted...");
-                                                       break;
-                                               };
-                                               if (!is_in_group("ld")) {
-                                                       sl_send_reply("403", "LD Toodle Noodle...");
-                                                       break;
-                                               };
-                                       # the same for international calls
-                                       } else if (uri=~"sip:000[1-9][0-9]+@.*") {
-                                               if (!is_in_group("int")) {
-                                                       sl_send_reply("403", "International Toodle Noodle...");
-                                                       break;
-                                               };
-                                       # everything else (e.g., interplanetary calls) is denied
-                                       } else {
-                                               sl_send_reply("403", "interplanetary Toodle Noodle...");
-                                               break;
-                                       };
+       # native SIP destinations are handled using our USRLOC DB
+       if (!lookup_contact("location")) {
+               log("Unable to lookup contact, sending 404\n");
+               sl_send_reply("404", "Not Found");
+               break;
+       };
+       # check whether some inventive user has uploaded  gateway 
+       # contacts to UsrLoc to bypass our authorization logic
+       if (uri=~"@195\.37\.77\.110([;:].*)*" ) {
+               log("Weird! Gateway address in UsrLoc!\n");
+               route(3);
+       };
 
-                               };
-                       };
+       # requests from gateway should be RR-ed too
+       if (src_ip==195.37.77.110 && method=="INVITE")  {
+               addRecordRoute();
+       };
 
-                       # requests to gateway must be record-route because the GW accepts
-                       # only reqeusts coming from our proxy
-                       if (method=="INVITE") addRecordRoute();
-                       # if you have passed through all the checks, let your call go to GW!
-                       rewritehostport("195.37.77.110:5060");
-               } else {
-
-                       # non-nummerical destnations now
-
-                       # demo stuff *******************************************
-                       /* added by Bogdan for cpl demo - Dorgham request*/
-                       if (uri=~"sip:test@.*" && method=="INVITE")
-                       {
-                               log("SER : runing CPL!! :)\n");
-                               if ( !cpl_run_script() )
-                               {
-                               log("SER : Error during running CPL script!\n");
-                               }else{
-                               if ( cpl_is_response_reject() ) {
-                                               log("SER: reject");
-                                       sl_send_reply("603","I am not available!");
-                                       break;
-                               }else if ( cpl_is_response_redirect() ) {
-                                       log("SER : redirect\n");
-                                       cpl_update_contact();
-                                       sl_send_reply("302","Moved temporarily");
-                                       break;
-                               };
-                               };
-                       };
-                       # End of demo stuff *******************************************
+       # we now know we may, we know where, let it go out now!
+       t_relay();
+}
 
-                       # native SIP destinations are handled using our USRLOC DB
-                       if (!lookup_contact("location")) {
-                               log("Unable to lookup contact, sending 404\n");
-                               sl_send_reply("404", "Not Found");
-                               break;
-                       };
-                       # requests from gateway should be RR-ed too
-                       # (numerical destinations are all RR-ed above)
-                       if (src_ip==195.37.77.110 && method=="INVITE")  {
-                               addRecordRoute();
-                       };
+# routing logic for outbound requests targeted out of our domain
+route[2] {
+               # outbound requests are allowed only for our users -- we don't
+               # support relaying and don't like strangers bothering us
+               # with resolving DNS
+               log("that's a request to outside");
+               if (!(src_ip==195.37.77.110) & 
+                       !(proxy_authorize(      "iptel.org" /* realm */,
+                                                       "subscriber" /* table name */ ))) {
+                       # see comments bellow on these ACK/CANCEL exceptions
+                       if (method=="ACK" ) {
+                               log("failed outbound authentication for ACK granted");
+                       } else if (method=="CANCEL") {
+                               log("failed outbound authentication for ACK granted");
+                       } else proxy_challenge("iptel.org" /* realm */, "0" /* no-qop */);
+                       break;
                };
-       } else {
-                       # outbound requests are allowed only for our users -- we don't
-                       # support relaying and don't like strangers bothering us
-                       # with resolving DNS
-                       log("that's a request to outside");
-                       if (!(src_ip==195.37.77.110) & !(proxy_authorize("iptel.org", "subscriber"))) {
-                               proxy_challenge("iptel.org", "0");
-                               break;
-                       };
-                       # there should be check_from here too -- but I'm to tired
-                       # to test it tonight
+               # to maintain credibility of our proxy, we check From to be
+               # equal of credential id -- all outbound request leaving our
+               # proxy are guaranteed to be generated by persons in "From"
+               if (!check_from()) {
+                       log("From Cheating attempt\n");
+                       sl_send_reply("403", "That is ugly -- use From=id next time");
+                       break;
                };
 
-               # we now know we may, we now where, let it go out now!
                t_relay();
 }
 
+# logic for calls through our PSTN gateway
+route[3] {
+       # free call destinations ... no authentication needed
+       if (uri=~"sip:001795061546@.*" | uri=~"sip:0016097265544.*" 
+               | uri=~"sip:[79][0-9][0-9][0-9]@.*") {
+               log("Free PSTN\n");
+       } else {
+               # all other PSTN destinations only for authenticated users
+               # (Cisco GW, which has no digest support, is authenticated
+               # by its IP address -- that's for sure not very strong;
+               # wth confirmed that we filter packets coming from outside
+               # and bearing SRC IP address of our network)
+               if (!(src_ip==195.37.77.110) & 
+                       !(proxy_authorize(      "iptel.org" /* realm */,
+                                                               "subscriber" /* table name */)))  {
+                       # we are forgiving and ignore improper credentials
+                       # for ACK/CANCEL as bis-09 is somewhat cryptic about
+                       # its use and many UACs have not gotten it right
+                       if (method=="ACK" ) {
+                               log("failed gw authentication for ACK granted");
+                       } else if (method=="CANCEL") {
+                               log("failed gw authentication for ACK granted");
+                       } else proxy_challenge( "iptel.org" /* realm */, 
+                                                                       "0" /* no qop */ );
+                       break;
+               };
+               
+               # authorize only for INVITEs -- RR/Contact may result in weird
+               # things showing up in d-uri that would break our logic; our
+               # major concern is INVITE which causes PSTN costs anyway
+
+               if (method=="INVITE") {
+
+                       # does the authenticated user have a permission for local
+                       # calls? (i.e., is he in the "local" group?)
+                       if (uri=~"sip:0[1-9][0-9]+@.*") {
+                               if (!is_in_group("local")) {
+                                       sl_send_reply("403", "Local Toodle Noodle...");
+                                       break;
+                               };
+                       # the same for long-distance
+                       } else if (uri=~"sip:00[1-9][0-9]+@.*") {
+                               if (uri=~"sip:001[089]" | uri=~"sip:00900.*" ) {
+                                       sl_send_reply("403", "Added Value Destinations not permitted...");
+                                       break;
+                               };
+                               if (!is_in_group("ld")) {
+                                       sl_send_reply("403", "LD Toodle Noodle...");
+                                       break;
+                               };
+                       # the same for international calls
+                       } else if (uri=~"sip:000[1-9][0-9]+@.*") {
+                               if (!is_in_group("int")) {
+                                       sl_send_reply("403", "International Toodle Noodle...");
+                                       break;
+                               };
+                       # everything else (e.g., interplanetary calls) is denied
+                       } else {
+                               sl_send_reply("403", "interplanetary Toodle Noodle...");
+                               break;
+                       };
+
+               }; # INVITE to authorized PSTN
+
+       }; # authorized PSTN
+
+       # requests to gateway must be record-route because the GW accepts
+       # only reqeusts coming from our proxy
+       if (method=="INVITE")
+               addRecordRoute();
+
+       # if you have passed through all the checks, let your call go to GW!
+       rewritehostport("195.37.77.110:5060");
+
+       # tag this transaction for accounting
+       setflag(1);
+
+       t_relay();
+}
diff --git a/flags.c b/flags.c
new file mode 100644 (file)
index 0000000..96bbc12
--- /dev/null
+++ b/flags.c
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ */
+
+#include <limits.h>
+#include "sr_module.h"
+#include "dprint.h"
+#include "parser/msg_parser.h"
+#include "flags.h"
+#include "error.h"
+#include "stdlib.h"
+
+int setflag( struct sip_msg* msg, flag_t flag ) {
+       msg->flags |= 1 << flag;
+       return 1;
+}
+
+int resetflag( struct sip_msg* msg, flag_t flag ) {
+       msg->flags &= ~ flag;
+       return 1;
+}
+
+int isflagset( struct sip_msg* msg, flag_t flag ) {
+       return msg->flags & (1<<flag) ? 1 : -1;
+}
+
+int flag_in_range( flag_t flag ) {
+       if (flag > MAX_FLAG ) {
+               LOG(L_ERR, "ERROR: message flag %d too high; MAX=%d\n",
+                       flag, MAX_FLAG );
+               return 0;
+       }
+       if (flag<=0) {
+               LOG(L_ERR, "ERROR: message flag (%d) must be in range %d..%d\n",
+                       flag, 1, MAX_FLAG );
+               return 0;
+       }
+       return 1;
+}
+
+
+#ifdef _GET_AWAY
+
+/* wrapping functions for flag processing  */
+static int fixup_t_flag(void** param, int param_no)
+{
+    unsigned int *code;
+       char *c;
+       int token;
+
+       DBG("DEBUG: fixing flag: %s\n", (char *) (*param));
+
+       if (param_no!=1) {
+               LOG(L_ERR, "ERROR: TM module: only parameter #1 for flags can be fixed\n");
+               return E_BUG;
+       };
+
+       if ( !(code = malloc( sizeof( unsigned int) )) ) return E_OUT_OF_MEM;
+
+       *code = 0;
+       c = *param;
+       while ( *c && (*c==' ' || *c=='\t')) c++; /* intial whitespaces */
+
+       token=1;
+       if (strcasecmp(c, "white")==0) *code=FL_WHITE;
+       else if (strcasecmp(c, "yellow")==0) *code=FL_YELLOW;
+       else if (strcasecmp(c, "green")==0) *code=FL_GREEN;
+       else if (strcasecmp(c, "red")==0) *code=FL_RED;
+       else if (strcasecmp(c, "blue")==0) *code=FL_BLUE;
+       else if (strcasecmp(c, "magenta")==0) *code=FL_MAGENTA;
+       else if (strcasecmp(c, "brown")==0) *code=FL_BROWN;
+       else if (strcasecmp(c, "black")==0) *code=FL_BLACK;
+       else if (strcasecmp(c, "acc")==0) *code=FL_ACC;
+       else {
+               token=0;
+               while ( *c && *c>='0' && *c<='9' ) {
+                       *code = *code*10+ *c-'0';
+                       if (*code > (sizeof( flag_t ) * CHAR_BIT - 1 )) {
+                               LOG(L_ERR, "ERROR: TM module: too big flag number: %s; MAX=%d\n",
+                                       (char *) (*param), sizeof( flag_t ) * CHAR_BIT - 1 );
+                               goto error;
+                       }
+                       c++;
+               }
+       }
+       while ( *c && (*c==' ' || *c=='\t')) c++; /* terminating whitespaces */
+
+       if ( *code == 0 ) {
+               LOG(L_ERR, "ERROR: TM module: bad flag number: %s\n", (char *) (*param));
+               goto error;
+       }
+
+       if (*code < FL_MAX && token==0) {
+               LOG(L_ERR, "ERROR: TM module: too high flag number: %s (%d)\n; lower number"
+                       " bellow %d reserved\n", (char *) (*param), *code, FL_MAX );
+               goto error;
+       }
+
+       /* free string */
+       free( *param );
+       /* fix now */
+       *param = code;
+       
+       return 0;
+
+error:
+       free( code );
+       return E_CFG;
+}
+
+
+#endif
diff --git a/flags.h b/flags.h
new file mode 100644 (file)
index 0000000..5975c28
--- /dev/null
+++ b/flags.h
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ */
+
+
+#ifndef _FLAGS_H
+#define _FLAGS_H
+
+enum { FL_WHITE=1, FL_YELLOW, FL_GREEN, FL_RED, FL_BLUE, FL_MAGENTA,
+          FL_BROWN, FL_BLACK, FL_ACC, FL_MAX };
+
+typedef unsigned long flag_t;
+
+#define MAX_FLAG  ( sizeof(flag_t) * CHAR_BIT - 1 )
+
+struct sip_msg;
+
+int setflag( struct sip_msg* msg, flag_t flag );
+int resetflag( struct sip_msg* msg, flag_t flag );
+int isflagset( struct sip_msg* msg, flag_t flag );
+
+int flag_in_range( flag_t flag );
+
+#endif
index 0360b73..86d5ed5 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -14,7 +14,7 @@
 
 #include "forward.h"
 #include "config.h"
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 #include "route.h"
 #include "dprint.h"
 #include "udp_server.h"
index f64b059..ec1e390 100644 (file)
--- a/forward.h
+++ b/forward.h
@@ -6,7 +6,7 @@
 #ifndef forward_h
 #define forward_h
 
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 #include "route.h"
 #include "proxy.h"
 
diff --git a/main.c b/main.c
index 741a4e7..adb1a2f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -30,7 +30,7 @@
 #endif
 #include "sr_module.h"
 #include "timer.h"
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 
 
 #include <signal.h>
index 2881893..39368d4 100644 (file)
@@ -20,7 +20,7 @@ enum fork_type { DEFAULT, NO_RESPONSE };
 /* FINAL_RESPONSE_TIMER ... tells how long should the transaction engine
    wait if no final response comes back*/
 #define FR_TIME_OUT       30
-#define INV_FR_TIME_OUT   60
+#define INV_FR_TIME_OUT   120
 
 /* WAIT timer ... tells how long state should persist in memory after
    a transaction was finalized*/
index 62feea2..fc8d81c 100644 (file)
 #include <pthread.h>
 #include <arpa/inet.h>
 
-#include "../../msg_parser.h"
+#include "../../parser/msg_parser.h"
 #include "../../types.h"
 #include "config.h"
-#include "t_flags.h"
+/*#include "t_flags.h"*/
 
 struct s_table;
 struct entry;
@@ -132,7 +132,7 @@ typedef struct cell
        /* protection against concurrent ACK processing */
        ser_lock_t      ack_mutex;
 
-       tflags_t        flags;
+/*     tflags_t        flags; */
 
 #ifdef WAIT
        /* protection against reentering WAIT state */
index 804e740..c3a102d 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef _SIP_MSG_H
 #define _SIP_MSG_H
 
-#include "../../msg_parser.h"
+#include "../../parser/msg_parser.h"
 
 #include "sh_malloc.h"
 
diff --git a/modules/tm/t_flags.c b/modules/tm/t_flags.c
deleted file mode 100644 (file)
index 30bef70..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * $Id$
- */
-
-
-#include "t_funcs.h"
-
-int t_setflag( unsigned int flag ) {
-       T->flags |= 1 << flag;
-       return 1;
-}
-
-int t_resetflag( unsigned int flag ) {
-       T->flags &= ~ flag;
-       return 1;
-}
-
-int t_isflagset( unsigned int flag ) {
-       return T->flags & (1<<flag) ? 1 : -1;
-}
diff --git a/modules/tm/t_flags.h b/modules/tm/t_flags.h
deleted file mode 100644 (file)
index d5a87d8..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * $Id$
- */
-
-
-#ifndef _FLAGS_H
-#define _FLAGS_H
-
-#define FL_WHITE       1
-#define FL_YELLOW      2
-#define FL_GREEN       3
-#define FL_RED         4
-#define FL_BLUE                5
-#define FL_MAGENTA     6
-#define FL_BROWN       7
-#define FL_BLACK       8
-
-
-
-typedef unsigned long tflags_t;
-
-int t_setflag( unsigned int flag );
-int t_resetflag( unsigned int flag );
-int t_isflagset( unsigned int flag );
-
-#endif
index 1ab0073..b11a060 100644 (file)
@@ -7,7 +7,7 @@
 #include "t_funcs.h"
 #include "../../dprint.h"
 #include "../../config.h"
-#include "../../parser_f.h"
+#include "../../parser/parser_f.h"
 #include "../../ut.h"
 //#include "../../timer.h"
 
index ac216d5..f9846f2 100644 (file)
@@ -10,7 +10,7 @@
 #include <netinet/in.h>
 #include <netdb.h>
 
-#include "../../msg_parser.h"
+#include "../../parser/msg_parser.h"
 #include "../../globals.h"
 #include "../../udp_server.h"
 #include "../../msg_translator.h"
@@ -313,9 +313,7 @@ static inline void set_timer( struct s_table *hash_table,
 {
        unsigned int timeout;
        struct timer* list;
-       static enum lists to_table[NR_OF_TIMER_LISTS] = {
-               FR_TIME_OUT, INV_FR_TIME_OUT, WT_TIME_OUT, DEL_TIME_OUT,
-               RETR_T1, RETR_T1 << 1, RETR_T1 << 2, RETR_T2 };
+
 
        if (list_id<FR_TIMER_LIST || list_id>=NR_OF_TIMER_LISTS) {
                LOG(L_CRIT, "ERROR: set_timer: unkown list: %d\n", list_id);
@@ -324,7 +322,7 @@ static inline void set_timer( struct s_table *hash_table,
 #endif
                return;
        }
-       timeout = to_table[ list_id ];
+       timeout = timer_id2timeout[ list_id ];
        list= &(hash_table->timers[ list_id ]);
 
        lock(list->mutex);
index 365843f..e8e9db2 100644 (file)
@@ -7,10 +7,12 @@
 #include "t_funcs.h"
 #include "../../dprint.h"
 #include "../../config.h"
-#include "../../parser_f.h"
+#include "../../parser/parser_f.h"
 #include "../../ut.h"
 #include "../../timer.h"
 
+#include "t_hooks.h"
+
 
 #define shm_free_lump( _lmp) \
        do{\
@@ -172,7 +174,8 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
                        get_ticks() );
                /*sets and starts the FINAL RESPONSE timer */
                set_timer( hash_table, &(T->uac[branch].request.fr_timer),
-                       FR_TIMER_LIST );
+                       /* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
+                       FR_TIMER_LIST ); 
                /* sets and starts the RETRANS timer */
                T->uac[branch].request.retr_list = RT_T1_TO_1;
                set_timer( hash_table, &(T->uac[branch].request.retr_timer),
@@ -269,6 +272,7 @@ int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
 
        T->uas.isACKed = 1;
        SEND_PR_BUFFER( &(T->uac[branch].request), ack, len );
+       callback_event( TMCB_E2EACK, p_msg );
        return attach_ack( T, branch, ack , len );
 
 #ifdef _DON_USE
@@ -354,7 +358,9 @@ int forward_serial_branch(struct cell* Trans,int branch)
        DBG("DEBUG: t_forward_serial_branch:starting timers (retrans and FR) %d\n",
                get_ticks() );
        /*sets and starts the FINAL RESPONSE timer */
-       set_timer( hash_table, &(T->uac[branch].request.fr_timer), FR_TIMER_LIST );
+       set_timer( hash_table, &(T->uac[branch].request.fr_timer), 
+                       FR_TIMER_LIST ); 
+                       /* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
        /* sets and starts the RETRANS timer */
        T->uac[branch].request.retr_list = RT_T1_TO_1;
        set_timer( hash_table, &(T->uac[branch].request.retr_timer), RT_T1_TO_1 );
diff --git a/modules/tm/t_hooks.c b/modules/tm/t_hooks.c
new file mode 100644 (file)
index 0000000..35a24c8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ */
+
+
+#include "t_hooks.h"
+
+static struct tm_callback_s* callback_array[ TMCB_END ] = { NULL, NULL } ;
+static int callback_id=0;
+
+/* register a callback function 'f' of type 'cbt'; will be called
+   back whenever the event 'cbt' occurs in transaction module
+*/
+int register_tmcb( tmcb_type cbt, transaction_cb f )
+{
+       struct tm_callback_s *cbs;
+
+       if (cbt<0 || cbt>=TMCB_END ) {
+               LOG(L_ERR, "ERROR: register_tmcb: invalid callback type: %d\n",
+                       cbt );
+               return E_BUG;
+       }
+
+       if (!(cbs=malloc( sizeof( struct tm_callback_s)))) {
+               LOG(L_ERR, "ERROR: register_tmcb: out of mem\n");
+               return E_OUT_OF_MEM;
+       }
+
+       callback_id++;
+       cbs->id=callback_id;
+       cbs->callback=f;
+       cbs->next=callback_array[ cbt ];
+       callback_array[ cbt ]=cbs;
+
+       return callback_id;
+}
+
+void callback_event( tmcb_type cbt , struct sip_msg *msg )
+{
+       struct tm_callback_s *cbs;
+
+       DBG("DBG: callback type %d entered\n", cbt );
+       for (cbs=callback_array[ cbt ]; cbs; cbs=cbs->next)  {
+               DBG("DBG: callback id %d entered\n", cbs->id );
+               cbs->callback( T, msg );
+       }
+}
diff --git a/modules/tm/t_hooks.h b/modules/tm/t_hooks.h
new file mode 100644 (file)
index 0000000..4fe6f95
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * $Id$
+ */
+
+#ifndef _HOOKS_H
+#define _HOOKS_H
+
+#include "h_table.h"
+#include "t_funcs.h"
+
+typedef enum { TMCB_REPLY,  TMCB_E2EACK, TMCB_END } tmcb_type;
+
+typedef void (transaction_cb) ( struct cell* t, struct sip_msg* msg );
+
+struct tm_callback_s {
+       int id;
+       transaction_cb* callback;
+       struct tm_callback_s* next;
+};
+
+
+extern struct tm_callback_s* callback_array[ TMCB_END ];
+
+typedef int (*register_tmcb_f)(tmcb_type cbt, transaction_cb f);
+
+int register_tmcb( tmcb_type cbt, transaction_cb f );
+void callback_event( tmcb_type cbt, struct sip_msg *msg );
+
+#endif
index d4d27f8..b6a81d4 100644 (file)
@@ -6,7 +6,7 @@
 #include <assert.h>
 #include "../../dprint.h"
 #include "../../config.h"
-#include "../../parser_f.h"
+#include "../../parser/parser_f.h"
 #include "../../ut.h"
 #include "../../timer.h"
 #include "hash_func.h"
@@ -131,55 +131,55 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
                { /* it's a ACK request*/
                        /* first only the length are checked */
                        if ( t_msg->first_line.u.request.method_value==METHOD_INVITE
-                       && (fprintf(stderr,"------Method name OK->testing callid len...\n"))
+                       /* && (fprintf(stderr,"------Method name OK->testing callid len...\n")) */
                        && /*callid length*/ EQ_LEN(callid)
-                       && (fprintf(stderr,"------CallID OK -> testing cseq nr len\n"))
+                       /* && (fprintf(stderr,"------CallID OK -> testing cseq nr len\n")) */
                        && get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len
-                       && (fprintf(stderr,"------Cseq nr OK -> testing from len\n"))
+                       /* && (fprintf(stderr,"------Cseq nr OK -> testing from len\n")) */
                        && /*from length*/ EQ_LEN(from)
-                       && (fprintf(stderr,"------from OK -> testing To uri len\n"))
+                       /* && (fprintf(stderr,"------from OK -> testing To uri len\n")) */
                        && /*to uri*/get_to(t_msg)->uri.len==get_to(p_msg)->uri.len
-                       && (fprintf(stderr,"------To uri OK -> testing To tag len\n"))
+                       /* && (fprintf(stderr,"------To uri OK -> testing To tag len\n")) */
                        && /*to tag*/p_cell->uas.tag->len==get_to(p_msg)->tag_value.len
-                       && (fprintf(stderr,"------To tag OK -> testing uri len\n"))
+                       /* && (fprintf(stderr,"------To tag OK -> testing uri len\n")) */
                        && /*req URI*/(p_cell->uas.status==200 || EQ_REQ_URI_LEN )
-                       && (fprintf(stderr,"------uri OK -> testing via len\n"))
+                       /* && (fprintf(stderr,"------uri OK -> testing via len\n")) */
                        && /*VIA*/(p_cell->uas.status==200 || EQ_VIA_LEN(via1)) )
                                /* so far the lengths are the same
                                -> let's check the contents */
-                               if ( fprintf(stderr,"------callid |%.*s| |%.*s|\n",
+                               if ( /* fprintf(stderr,"------callid |%.*s| |%.*s|\n",
                                        p_msg->callid->body.len,p_msg->callid->body.s,
                                        t_msg->callid->body.len,t_msg->callid->body.s)
-                               && /*callid*/!memcmp( t_msg->callid->body.s,
+                               && */ /*callid*/!memcmp( t_msg->callid->body.s,
                                        p_msg->callid->body.s,p_msg->callid->body.len)
-                               && fprintf(stderr,"------cseq |%.*s| |%.*s|\n",
+                               /* && fprintf(stderr,"------cseq |%.*s| |%.*s|\n",
                                        get_cseq(p_msg)->number.len,get_cseq(p_msg)->number.s,
-                                       get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s)
+                                       get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s) */
                                && /*cseq nr*/!memcmp(get_cseq(t_msg)->number.s,
                                        get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)
-                               && fprintf(stderr,"------from |%.*s| |%.*s|\n",
+                               /* &&  fprintf(stderr,"------from |%.*s| |%.*s|\n",
                                        p_msg->from->body.len, translate_pointer(p_msg->orig,
                                                p_msg->buf,p_msg->from->body.s),
-                                       t_msg->from->body.len,t_msg->from->body.s)
+                                       t_msg->from->body.len,t_msg->from->body.s) */
                                && /*from*/EQ_STR(from)
-                               && fprintf(stderr,"------to uri |%.*s| |%.*s|\n",
+                               /* && fprintf(stderr,"------to uri |%.*s| |%.*s|\n",
                                        get_to(p_msg)->uri.len,get_to(p_msg)->uri.s,
-                                       get_to(t_msg)->uri.len,get_to(t_msg)->uri.s)
+                                       get_to(t_msg)->uri.len,get_to(t_msg)->uri.s) */
                                && /*to uri*/!memcmp(get_to(t_msg)->uri.s,
                                        get_to(p_msg)->uri.s,get_to(t_msg)->uri.len)
-                               && fprintf(stderr,"------to tag |%.*s| |%.*s|\n",
+                               /* && fprintf(stderr,"------to tag |%.*s| |%.*s|\n",
                     get_to(p_msg)->tag_value.len,get_to(p_msg)->tag_value.s,
-                    p_cell->uas.tag->len, p_cell->uas.tag->s)
+                    p_cell->uas.tag->len, p_cell->uas.tag->s) */
                                && /*to tag*/!memcmp(p_cell->uas.tag->s,
                                        get_to(p_msg)->tag_value.s,p_cell->uas.tag->len)
-                               && fprintf(stderr,"------URI %d |%.*s| |%.*s|\n",
+                               /* && fprintf(stderr,"------URI %d |%.*s| |%.*s|\n",
                                        p_cell->uas.status,p_msg->first_line.u.request.uri.len,
                                        translate_pointer(p_msg->orig, p_msg->buf,
                                                p_msg->first_line.u.request.uri.s),
                                        t_msg->first_line.u.request.uri.len,
-                                       t_msg->first_line.u.request.uri.s)
+                                       t_msg->first_line.u.request.uri.s) */
                                && /*req URI*/(p_cell->uas.status==200 || EQ_REQ_URI_STR)
-                               && fprintf(stderr,"------VIA %d |%.*s| |%.*s|\n",
+                               /* && fprintf(stderr,"------VIA %d |%.*s| |%.*s|\n",
                                        p_cell->uas.status, 
                                        (p_msg->via1->bsize-(p_msg->via1->name.s-
                                                (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
@@ -187,7 +187,7 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
                                                p_msg->via1->name.s),
                     (t_msg->via1->bsize-(t_msg->via1->name.s-
                                                (t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
-                                       t_msg->via1->name.s)
+                                       t_msg->via1->name.s) */
                                && /*VAI*/(p_cell->uas.status==200 ||EQ_VIA_STR(via1)) )
                                        { /* WE FOUND THE GOLDEN EGG !!!! */
                                                goto found;
@@ -245,67 +245,67 @@ struct cell* t_lookupOriginalT(  struct s_table* hash_table ,
 
                /* is it the wanted transaction ? */
                /* first only the length are checked */
-               if ( fprintf(stderr,"starting\n") && p_cell->uas.request->REQ_METHOD!=METHOD_CANCEL
-                       && fprintf(stderr,"checking callid length....\n")
+               if ( /* fprintf(stderr,"starting\n")  && */ p_cell->uas.request->REQ_METHOD!=METHOD_CANCEL
+                       /* && fprintf(stderr,"checking callid length....\n") */
                        && /*callid length*/ EQ_LEN(callid)
-                       && fprintf(stderr,"OK. checking cseg nr len....\n")     
+                       /* && fprintf(stderr,"OK. checking cseg nr len....\n")   */
                        && get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len
-                       && fprintf(stderr,"OK. checking REQ_URI len.... \n")
+                       /* && fprintf(stderr,"OK. checking REQ_URI len.... \n") */
                        && EQ_REQ_URI_LEN
-                       && fprintf(stderr,"OK. checking VIA %d %d....\n",
+                       /* && fprintf(stderr,"OK. checking VIA %d %d....\n",
                                (p_msg->via1->bsize-(p_msg->via1->name.s-
                                        (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
                                (t_msg->via1->bsize-(t_msg->via1->name.s-
-                                       (t_msg->via1->hdr.s+t_msg->via1->hdr.len))))
-            && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
+                                       (t_msg->via1->hdr.s+t_msg->via1->hdr.len)))) */
+            /* && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
                 (p_msg->via1->bsize-(p_msg->via1->name.s-
                      (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
                 translate_pointer(p_msg->orig,p_msg->buf,
                        p_msg->via1->name.s),
                 (t_msg->via1->bsize-(t_msg->via1->name.s-
                       (t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
-                t_msg->via1->name.s)
+                t_msg->via1->name.s) */
                        && EQ_VIA_LEN(via1) 
-                       && fprintf(stderr,"OK. checking FROM len... \n")
+                       /* && fprintf(stderr,"OK. checking FROM len... \n") */
                        && EQ_LEN(from)
-                       && fprintf(stderr,"OK. checking TO len... \n")
+                       /* && fprintf(stderr,"OK. checking TO len... \n") */
                        && EQ_LEN(to)
-                       && fprintf(stderr,"OK\n") )
+                       /* && fprintf(stderr,"OK\n") */ )
                                /* so far the lengths are the same
                                 let's check the contents */
                                if (
-                       fprintf(stderr,"checking callid |%.*s| |%.*s|\n",
+                       /* fprintf(stderr,"checking callid |%.*s| |%.*s|\n",
                        p_msg->callid->body.len, translate_pointer(p_msg->orig,
                                p_msg->buf,p_msg->callid->body.s),
-                       t_msg->callid->body.len,t_msg->callid->body.s)
-                                       && /*callid*/ EQ_STR(callid)
-                                       && fprintf(stderr,"OK. cseq nr |%.*s| |%.*s|\n",
+                       t_msg->callid->body.len,t_msg->callid->body.s) 
+                                       && *//*callid*/ EQ_STR(callid)
+                                       /* && fprintf(stderr,"OK. cseq nr |%.*s| |%.*s|\n",
                                                get_cseq(p_msg)->number.len,get_cseq(p_msg)->number.s,
-                                               get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s)
+                                               get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s) */
                                        && /*cseq_nr*/ !memcmp(get_cseq(t_msg)->number.s,
                                                get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)
-                       && fprintf(stderr,"OK. URI %d |%.*s| |%.*s|\n",
+                       /* && fprintf(stderr,"OK. URI %d |%.*s| |%.*s|\n",
                        p_cell->uas.status,p_msg->first_line.u.request.uri.len,
                        translate_pointer(p_msg->orig, p_msg->buf,
                                p_msg->first_line.u.request.uri.s),
                        t_msg->first_line.u.request.uri.len,
-                       t_msg->first_line.u.request.uri.s)
+                       t_msg->first_line.u.request.uri.s) */
                                        && EQ_REQ_URI_STR
-                       && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
+                       /* && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
                            (p_msg->via1->bsize-(p_msg->via1->name.s-
                            (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
                            translate_pointer(p_msg->orig,p_msg->buf,
                            p_msg->via1->name.s),
                                        (t_msg->via1->bsize-(t_msg->via1->name.s-
                            (t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
-                                               t_msg->via1->name.s)
+                                               t_msg->via1->name.s) */
                                        && EQ_VIA_STR(via1)
-                       && fprintf(stderr,"OK. from |%.*s| |%.*s|\n",
+                       /* && fprintf(stderr,"OK. from |%.*s| |%.*s|\n",
                         p_msg->from->body.len, translate_pointer(p_msg->orig,
                             p_msg->buf,p_msg->from->body.s),
-                        t_msg->from->body.len,t_msg->from->body.s)
+                        t_msg->from->body.len,t_msg->from->body.s) */
                                        && EQ_STR(from)
-                                       && fprintf(stderr,"OK\n") )
+                                       /* && fprintf(stderr,"OK\n") */ )
                                        { /* WE FOUND THE GOLDEN EGG !!!! */
                                                DBG("DEBUG: t_lookupOriginalT: canceled transaction"
                                                        " found (%p)! \n",p_cell );
@@ -559,9 +559,13 @@ enum addifnew_status t_addifnew( struct sip_msg* p_msg )
        struct cell *new_cell;
 
        /* is T still up-to-date ? */
-       DBG("DEBUG: t_check_new_request: msg id=%d , global msg id=%d ,"
+       DBG("DEBUG: t_addifnew: msg id=%d , global msg id=%d ,"
                " T on entrance=%p\n",p_msg->id,global_msg_id,T);
-       if ( p_msg->id != global_msg_id || T==T_UNDEFINED )
+       if ( p_msg->id != global_msg_id || T==T_UNDEFINED 
+               /* if someone tried to do something previously by mistake with
+                  a transaction which did not exist yet, try to look-up
+                  the transacion too */
+               || T==T_NULL)
        {
                global_msg_id = p_msg->id;
                T = T_UNDEFINED;
@@ -604,7 +608,7 @@ enum addifnew_status t_addifnew( struct sip_msg* p_msg )
                }
        } else {
                if (T)
-                       LOG(L_ERR, "ERROR: t_check_new_request: already "
+                       LOG(L_ERR, "ERROR: t_addifnew: already "
                        "processing this message, T found!\n");
                else
                        LOG(L_ERR, "ERROR: t_check_new_request: already "
index ef1a8bf..fa623e4 100644 (file)
@@ -8,10 +8,12 @@
 #include "t_funcs.h"
 #include "../../dprint.h"
 #include "../../config.h"
-#include "../../parser_f.h"
+#include "../../parser/parser_f.h"
 #include "../../ut.h"
 #include "../../timer.h"
 
+#include "t_hooks.h"
+
 
 
 
@@ -38,11 +40,11 @@ int t_retransmit_reply( /* struct sip_msg* p_msg    */ )
        int len;
 
        if (!T->uas.response.buffer)
-               return 0;
+               return -1;
 
        if ( (len=T->uas.response.buffer_len)==0 || len>BUF_SIZE ) {
                UNLOCK_REPLIES( T );
-               return -1;
+               return -2;
        }
        memcpy( b, T->uas.response.buffer, len );
        UNLOCK_REPLIES( T );
@@ -370,6 +372,7 @@ int t_on_reply( struct sip_msg  *p_msg )
        if (relay >= 0) {
                SEND_PR_BUFFER( rb, buf, res_len );
                t_update_timers_after_sending_reply( rb );
+               callback_event( TMCB_REPLY, p_msg );
        }
 
        /* *** ACK handling *** */
@@ -378,6 +381,7 @@ int t_on_reply( struct sip_msg  *p_msg )
                {   /*retransmit*/
                        /* I don't need any additional syncing here -- after ack
                           is introduced it's never changed */
+                       DBG("DEBUG: localy cached ACK retranmitted\n");
                        SEND_ACK_BUFFER( &(T->uac[branch].request) );
                } else if (msg_class>2 ) {
                        /*on a non-200 reply to INVITE*/
index 28218d2..7f78ee2 100644 (file)
@@ -17,7 +17,20 @@ int timer_group[NR_OF_TIMER_LISTS] =
        TG_RT, TG_RT, TG_RT, TG_RT
 };
 
-
+/* default values of timeouts for all the timer list
+   (see timer.h for enumeration of timer lists)
+*/
+unsigned int timer_id2timeout[NR_OF_TIMER_LISTS] = {
+       FR_TIME_OUT,            /* FR_TIMER_LIST */
+       INV_FR_TIME_OUT,        /* FR_INV_TIMER_LIST */
+       WT_TIME_OUT,            /* WT_TIMER_LIST */
+       DEL_TIME_OUT,           /* DELETE_LIST */
+       RETR_T1,                        /* RT_T1_TO_1 */
+       RETR_T1 << 1,           /* RT_T1_TO_2 */
+       RETR_T1 << 2,           /* RT_T1_TO_3 */
+       RETR_T2                         /* RT_T2 */
+                                               /* NR_OF_TIMER_LISTS */
+};
 
 
 void reset_timer_list( struct s_table* hash_table, enum lists list_id)
index 1af14b3..e6b7394 100644 (file)
@@ -25,7 +25,10 @@ enum lists
 
 
 #define is_in_timer_list2(_tl) ( (_tl)->timer_list )
+
 extern int timer_group[NR_OF_TIMER_LISTS];
+extern unsigned int timer_id2timeout[NR_OF_TIMER_LISTS];
+
 struct timer;
 
 #include "lock.h"
index 0c21bfd..9fbae99 100644 (file)
@@ -17,6 +17,8 @@
 #include "sip_msg.h"
 #include "h_table.h"
 #include "t_funcs.h"
+#include "t_hooks.h"
+#include "tm_load.h"
 
 
 
@@ -39,11 +41,6 @@ static int w_t_add_fork_on_no_rpl(struct sip_msg* msg,char* str,char* str2);
 static int w_t_clear_forks(struct sip_msg* msg, char* str, char* str2);
 static void w_onbreak(struct sip_msg* msg) { t_unref(); }
 
-static int w_t_setflag( struct sip_msg* msg, char *flag, char *foo );
-static int w_t_resetflag( struct sip_msg* msg, char *flag, char *foo );
-static int w_t_isflagset( struct sip_msg* msg, char *flag, char *foo );
-static int fixup_t_flag(void** param, int param_no);
-
 static int mod_init(void);
 
 #ifdef STATIC_TM
@@ -51,7 +48,8 @@ struct module_exports tm_exports = {
 #else
 struct module_exports exports= {
 #endif
-       "tm_module",
+       "tm",
+       /* -------- exported functions ----------- */
        (char*[]){                      
                                "t_add_transaction",
                                "t_lookup_request",
@@ -67,9 +65,8 @@ struct module_exports exports= {
                                "t_fork_to_uri",
                                "t_clear_forks",
                                "t_fork_on_no_response",
-                               "t_setflag",
-                               "t_resetflag",
-                               "t_isflagset"
+                               "register_tmcb",
+                               "load_tm"
                        },
        (cmd_function[]){
                                        w_t_add_transaction,
@@ -86,9 +83,8 @@ struct module_exports exports= {
                                        w_t_add_fork_uri,
                                        w_t_clear_forks,
                                        w_t_add_fork_on_no_rpl,
-                                       w_t_setflag,
-                                       w_t_resetflag,
-                                       w_t_isflagset
+                                       (cmd_function) register_tmcb,
+                                       (cmd_function) load_tm
                                        },
        (int[]){
                                0, /* t_add_transaction */
@@ -105,9 +101,8 @@ struct module_exports exports= {
                                1, /* t_fork_to_uri */
                                0, /* t_clear_forks */
                                1,  /* t_add_fork_on_no_response */
-                               1, /* t_setflag */
-                               1, /* t_resetflag */
-                               1 /* w_t_isflagset */
+                               2 /* register_tmcb */,
+                               1 /* load_tm */
                        },
        (fixup_function[]){
                                0,                                              /* t_add_transaction */
@@ -124,16 +119,45 @@ struct module_exports exports= {
                                fixup_t_add_fork_uri,   /* t_fork_to_uri */
                                0,                                              /* t_clear_forks */
                                fixup_t_add_fork_uri,   /* t_add_fork_on_no_response */
-                               fixup_t_flag,                   /* t_setflag */
-                               fixup_t_flag,                   /* t_resetflag */
-                               fixup_t_flag                    /* t_isflagset */
+                               0,                                              /* register_tmcb */
+                               0                                               /* load_tm */
        
                },
-       17,
-       NULL,   /* Module parameter names */
-       NULL,   /* Module parameter types */
-       NULL,   /* Module parameter variable pointers */
-       0,      /* Number of module paramers */
+       16,
+
+       /* ------------ exported variables ---------- */
+       (char *[]) { /* Module parameter names */
+               "fr_timer",
+               "fr_inv_timer",
+               "wt_timer",
+               "delete_timer",
+               "retr_timer1p1",
+               "retr_timer1p2",
+               "retr_timer1p3",
+               "retr_timer2"
+       },
+       (modparam_t[]) { /* variable types */
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM,
+               INT_PARAM
+       },
+       (void *[]) { /* variable pointers */
+               &(timer_id2timeout[FR_TIMER_LIST]),
+               &(timer_id2timeout[FR_INV_TIMER_LIST]),
+               &(timer_id2timeout[WT_TIMER_LIST]),
+               &(timer_id2timeout[DELETE_LIST]),
+               &(timer_id2timeout[RT_T1_TO_1]),
+               &(timer_id2timeout[RT_T1_TO_2]),
+               &(timer_id2timeout[RT_T1_TO_3]),
+               &(timer_id2timeout[RT_T2])
+       },
+       8,      /* Number of module paramers */
+
        mod_init, /* module initialization function */
        (response_function) t_on_reply,
        (destroy_function) tm_shutdown,
@@ -405,8 +429,13 @@ static int t_relay_to( struct sip_msg  *p_msg , char *str_ip , char *str_port)
                        ret = 0;
                        break;
                case AIN_RETR:          /* it's a retransmission */
-                       if ( !t_retransmit_reply( p_msg ) )
-                               DBG( "SER: WARNING: bad t_retransmit_reply\n");
+                       ret=t_retransmit_reply( p_msg );
+                       /* look at ret for better debugging output ... */
+                       if (ret>0) DBG("DEBUG: reply retransmitted (status %d)\n", ret);
+                       else if (ret==-1) DBG("DEBUG: no reply to retransmit; "
+                               "probably a non-INVITE transaction which was not replied\n");
+                       else LOG(L_ERR, "ERROR: reply retranmission failed\n");
+                       /* eventually, do not worry and proceed whatever happened to you...*/
                        ret = 1;
                        break;
                case AIN_NEW:           /* it's a new request */
@@ -456,6 +485,7 @@ static int t_relay_to( struct sip_msg  *p_msg , char *str_ip , char *str_port)
                        ret = 1;
                        break;
                case AIN_RTRACK:        /* ACK retransmission */
+                       DBG( "SER: ACK retransmission\n");
                        ret = 1;
                        break;
                default:
@@ -493,89 +523,3 @@ static int t_relay( struct sip_msg  *p_msg , char* foo, char* bar)
 
 
 
-/* wrapping functions for flaf processing  */
-
-static int fixup_t_flag(void** param, int param_no)
-{
-    unsigned int *code;
-       char *c;
-
-       DBG("TM module: fixing flag: %s\n", (char *) (*param));
-
-       if (param_no!=1) {
-               LOG(L_ERR, "ERROR: TM module: only parameter #1 for flags can be fixed\n");
-               return E_BUG;
-       };
-
-       if ( !(code = malloc( sizeof( unsigned int) )) ) return E_OUT_OF_MEM;
-
-       *code = 0;
-       c = *param;
-       while ( *c && (*c==' ' || *c=='\t')) c++; /* intial whitespaces */
-
-       if (strcasecmp(c, "white")==0) *code=FL_WHITE;
-       else if (strcasecmp(c, "yellow")==0) *code=FL_YELLOW;
-       else if (strcasecmp(c, "green")==0) *code=FL_GREEN;
-       else if (strcasecmp(c, "red")==0) *code=FL_RED;
-       else if (strcasecmp(c, "blue")==0) *code=FL_BLUE;
-       else if (strcasecmp(c, "magenta")==0) *code=FL_MAGENTA;
-       else if (strcasecmp(c, "brown")==0) *code=FL_BROWN;
-       else if (strcasecmp(c, "black")==0) *code=FL_BLACK;
-       else while ( *c && *c>='0' && *c<='9' ) {
-               *code = *code*10+ *c-'0';
-               if (*code > (sizeof( tflags_t ) * CHAR_BIT - 1 )) {
-                       LOG(L_ERR, "ERROR: TM module: too big flag number: %s; MAX=%d\n",
-                               (char *) (*param), sizeof( tflags_t ) * CHAR_BIT - 1 );
-                       goto error;
-               }
-               c++;
-       }
-       while ( *c && (*c==' ' || *c=='\t')) c++; /* terminating whitespaces */
-
-       if ( *code == 0 ) {
-               LOG(L_ERR, "ERROR: TM module: bad flag number: %s\n", (char *) (*param));
-               goto error;
-       }
-
-       /* free string */
-       free( *param );
-       /* fix now */
-       *param = code;
-       
-       return 0;
-
-error:
-       free( code );
-       return E_CFG;
-}
-
-
-static int w_t_setflag( struct sip_msg* msg, char *flag, char *foo )
-{
-    if (t_check( msg , 0 , 0)==-1) return -1;
-    if (!T) {
-        DBG("DEBUG: t_setflag: no transaction found\n");
-        return -1;
-    }
-       return t_setflag( (unsigned int) flag );
-}
-
-static int w_t_resetflag( struct sip_msg* msg, char *flag, char *foo )
-{
-    if (t_check( msg , 0 , 0)==-1) return -1;
-    if (!T) {
-        DBG("DEBUG: t_resetflag: no transaction found\n");
-        return -1;
-    }
-       return t_resetflag( (unsigned int) flag );
-}
-
-static int w_t_isflagset( struct sip_msg* msg, char *flag, char *foo )
-{
-    if (t_check( msg , 0 , 0)==-1) return -1;
-    if (!T) {
-        DBG("DEBUG: t_isflagset: no transaction found\n");
-        return -1;
-    }
-       return t_isflagset( (unsigned int) flag );
-}
diff --git a/modules/tm/tm_load.c b/modules/tm/tm_load.c
new file mode 100644 (file)
index 0000000..ad74ddf
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ */
+
+#include "tm_load.h"
+
+int load_tm( struct tm_binds *tmb)
+{
+       if (!( tmb->register_tmcb=(register_tmcb_f) find_export("register_tmcb", 2)) ) {
+               LOG(L_ERR, "ERROR: tm_bind: TM module function 'register_tmcb' not found\n");
+               return -1;
+       }
+
+       if (!( tmb->t_relay_to=find_export("t_relay_to", 2)) ) {
+               LOG(L_ERR, "ERROR: tm_bind: TM module function 't_relay_to' not found\n");
+               return -1;
+       }
+       if (!( tmb->t_relay=find_export("t_relay", 0)) ) {
+               LOG(L_ERR, "ERROR: tm_bind: TM module function 't_relay' not found\n");
+               return -1;
+       }
+       if (!( tmb->t_fork_to_uri=find_export("t_fork_to_uri", 1)) ) {
+               LOG(L_ERR, "ERROR: tm_bind: TM module function 't_fork_to_uri' not found\n");
+               return -1;
+       }
+       if (!( tmb->t_fork_on_no_response=find_export("t_fork_on_no_response", 1)) ) {
+               LOG(L_ERR, "ERROR: tm_bind: TM module function 't_fork_on_no_response' not found\n");
+               return -1;
+       }
+
+       return 1;
+
+}
diff --git a/modules/tm/tm_load.h b/modules/tm/tm_load.h
new file mode 100644 (file)
index 0000000..d119b56
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ */
+
+#ifndef _TM_BIND_H
+#define _TM_BIND_H
+
+#include "../../sr_module.h"
+#include "t_hooks.h"
+
+struct tm_binds {
+       register_tmcb_f register_tmcb;
+
+/*
+       cmd_function    t_isflagset;
+       cmd_function    t_setflag;
+       cmd_function    t_resetflag;
+*/
+
+       cmd_function    t_relay_to;
+       cmd_function    t_relay;
+       cmd_function    t_fork_to_uri;
+       cmd_function    t_fork_on_no_response;
+};
+
+
+typedef int(*load_tm_f)( struct tm_binds *tmb );
+int load_tm( struct tm_binds *tmb);
+
+
+#endif
index 86a8370..37ebcd2 100644 (file)
@@ -8,7 +8,7 @@
 #define MY_HF_SEP ": "
 #define MY_HF_SEP_LEN 2
 
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 
 char * build_req_buf_from_sip_req (    struct sip_msg* msg, 
                                unsigned int *returned_len);
similarity index 99%
rename from msg_parser.c
rename to parser/msg_parser.c
index 791f449..fc1ade0 100644 (file)
 
 #include "msg_parser.h"
 #include "parser_f.h"
-#include "ut.h"
-#include "error.h"
-#include "dprint.h"
-#include "data_lump_rpl.h"
-#include "mem/mem.h"
+#include "../ut.h"
+#include "../error.h"
+#include "../dprint.h"
+#include "../data_lump_rpl.h"
+#include "../mem/mem.h"
 
 #ifdef DEBUG_DMALLOC
 #include <mem/dmalloc.h>
similarity index 96%
rename from msg_parser.h
rename to parser/msg_parser.h
index 90309e0..d829dcc 100644 (file)
@@ -5,8 +5,9 @@
 #ifndef msg_parser_h
 #define msg_parser_h
 
-#include "str.h"
-#include "data_lump.h"
+#include "../str.h"
+#include "../data_lump.h"
+#include "../flags.h"
 
 #define SIP_REQUEST 1
 #define SIP_REPLY   2
@@ -216,6 +217,11 @@ struct sip_msg{
        /* index to TM hash table; stored in core to avoid unnecessary calcs */
        unsigned int  hash_index;
 
+       /* allows to set various flags on the message; may be used for 
+          simple inter-module communication or remembering processing state
+          reached */
+       flag_t flags;
+
        
 };
 
similarity index 99%
rename from parse_fline.c
rename to parser/parse_fline.c
index f3fc0be..83fce43 100644 (file)
@@ -7,7 +7,7 @@
 
 
 
-#include "dprint.h"
+#include "../dprint.h"
 #include "msg_parser.h"
 
 
similarity index 99%
rename from parse_hname.c
rename to parser/parse_hname.c
index e1b7b56..ee5fa00 100644 (file)
@@ -17,7 +17,7 @@
 
 
 #include "msg_parser.h"
-#include "dprint.h"
+#include "../dprint.h"
 
 enum { INITIAL=0,
                VIA1, VIA2,
diff --git a/parser/parse_hname2.c b/parser/parse_hname2.c
new file mode 100644 (file)
index 0000000..fab8239
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * $Id$
+ */
+
+/* 
+ * TODO: Optimize short variants of headers
+ *       Test, Test, Test....
+ *       Hardwire into ser core
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "msg_parser.h"
+#include "../strs.h"
+#include "../dprint.h"
+
+/*
+ * Size of hash table, this is magic value
+ * that ensures, that there are no synonyms for
+ * frequently used keys (frequently used keys are
+ * 4-byte parts of message headers we recognize)
+ * WARNING ! This value MUST be recalculated if you want
+ * a new header to be recognized
+ */
+#define HASH_TABLE_SIZE 1471
+
+
+
+
+/*
+ * Hash function
+ */
+#define HASH_FUNC(val) ((val) % HASH_TABLE_SIZE)
+
+
+/*
+ * This constants marks empty hash table element
+ */
+#define HASH_EMPTY 0x2d2d2d2d
+
+
+/*
+ * Hash table entry
+ */
+struct ht_entry {
+       unsigned int key;
+       unsigned int value;
+};
+
+/*
+hash_table = (struct ht_entry*)malloc(HASH_TABLE_SIZE 
+       * sizeof(struct ht_entry));
+*/
+
+static struct ht_entry hash_table[ HASH_TABLE_SIZE ];
+
+/*
+ * Pointer to the hash table
+ */
+/*
+static struct ht_entry *hash_table;
+*/
+
+
+/*
+ * Declarations
+ */
+static inline char* q_memchr    (char* p, int c, unsigned int size);
+static inline char* skip_ws     (char* p, unsigned int size);
+void         init_htable (void);
+static void         set_entry   (unsigned int key, unsigned int val);
+static inline int   unify       (int key);
+
+/*
+ * Fast replacement of standard memchr function
+ */
+static inline char* q_memchr(char* p, int c, unsigned int size)
+{
+       char* end;
+
+       end=p+size;
+       for(;p<end;p++){
+               if (*p==(unsigned char)c) return p;
+       }
+       return 0;
+}
+
+
+/*
+ * Skip all whitechars and return position of the first
+ * non-white char
+ */
+static inline char* skip_ws(char* p, unsigned int size)
+{
+       char* end;
+       
+       end = p + size;
+       for(; p < end; p++) {
+               if ((*p != ' ') && (*p != '\t')) return p;
+       }
+       return p;
+}
+       
+
+/*
+ * Used to initialize hash table
+ */
+static void set_entry(unsigned int key, unsigned int val)
+{
+       hash_table[HASH_FUNC(key)].key = key;
+       hash_table[HASH_FUNC(key)].value = val;
+}
+
+
+/*
+ * cSeQ -> CSeq and so on...
+ */ 
+static inline int unify(int key)
+{
+       register struct ht_entry* en;
+
+       en = &hash_table[HASH_FUNC(key)];
+       if (en->key == key) {
+               return en->value;
+       } else {
+               return key;
+       }
+}
+
+
+#define Via1_CASE         \
+     hdr->type = HDR_VIA; \
+     hdr->name.len = 3;   \
+     *(p + 3) = '\0';     \
+     return p + 4        
+
+
+#define From_CASE          \
+     hdr->type = HDR_FROM; \
+     p += 4;               \
+     goto dc_end          
+                                                             
+
+#define To12_CASE        \
+     hdr->type = HDR_TO; \
+     hdr->name.len = 2;  \
+     *(p + 2) = '\0';    \
+     return (p + 3)
+
+
+#define CSeq_CASE          \
+     hdr->type = HDR_CSEQ; \
+     p += 4;               \
+     goto dc_end
+
+
+#define Call_CASE                      \
+     p += 4;                           \
+     val = READ(p);                    \
+     switch(val) {                     \
+     case _ID1:                        \
+            hdr->type = HDR_CALLID;   \
+            hdr->name.len = 7;        \
+            *(p + 3) = '\0';          \
+            return (p + 4);           \
+                                      \
+     case _ID2:                        \
+            hdr->type = HDR_CALLID;   \
+            p += 4;                   \
+            goto dc_end;              \
+     }                                 \
+                                       \
+     val = unify(val);                 \
+     switch(val) {                     \
+     case _ID1:                        \
+            hdr->type = HDR_CALLID;   \
+            hdr->name.len = 7;        \
+            *(p + 3) = '\0';          \
+            return (p + 4);           \
+                                      \
+     case _ID2:                        \
+            hdr->type = HDR_CALLID;   \
+            p += 4;                   \
+            goto dc_end;              \
+                                       \
+     default: goto other;              \
+     }                                 \
+     break
+
+
+#define Cont_CASE                     \
+     p += 4;                          \
+     val = READ(p);                   \
+     switch(val) {                    \
+     case act1:                       \
+            hdr->type = HDR_CONTACT; \
+            hdr->name.len = 7;       \
+            *(p + 3) = '\0';         \
+            return (p + 4);          \
+                                     \
+     case act2:                       \
+            hdr->type = HDR_CONTACT; \
+            p += 4;                  \
+            goto dc_end;             \
+     }                                \
+                                      \
+     val = unify(val);                \
+     switch(val) {                    \
+     case act1:                       \
+            hdr->type = HDR_CONTACT; \
+            hdr->name.len = 7;       \
+            *(p + 3) = '\0';         \
+            return (p + 4);          \
+                                     \
+     case act2:                       \
+            hdr->type = HDR_CONTACT; \
+            p += 4;                  \
+            goto dc_end;             \
+                                      \
+     default: goto other;             \
+     }                                \
+     break
+
+
+#define Rout_CASE                   \
+     p += 4;                        \
+     switch(*p) {                   \
+     case 'e':                      \
+     case 'E':                      \
+            hdr->type = HDR_ROUTE; \
+            p++;                   \
+            goto dc_end;           \
+                                    \
+     default:                       \
+            goto other;            \
+     }                              \
+     break
+
+
+#define Max_CASE                                   \
+     p += 4;                                       \
+     val = READ(p);                                \
+     switch(val) {                                 \
+     case Forw:                                    \
+            p += 4;                               \
+            val = READ(p);                        \
+            if (val == ards) {                    \
+                    hdr->type = HDR_MAXFORWARDS;  \
+                    p += 4;                       \
+                    goto dc_end;                  \
+            }                                     \
+                                                   \
+            val = unify(val);                     \
+            if (val == ards) {                    \
+                    hdr->type = HDR_MAXFORWARDS;  \
+                    p += 4;                       \
+                    goto dc_end;                  \
+            }                                     \
+            goto other;                           \
+     }                                             \
+                                                   \
+     val = unify(val);                             \
+     switch(val) {                                 \
+     case Forw:                                    \
+            p += 4;                               \
+            val = READ(p);                        \
+            if (val == ards) {                    \
+                    hdr->type = HDR_MAXFORWARDS;  \
+                    p += 4;                       \
+                    goto dc_end;                  \
+            }                                     \
+                                                   \
+            val = unify(val);                     \
+            if (val == ards) {                    \
+                    hdr->type = HDR_MAXFORWARDS;  \
+                    p += 4;                       \
+                    goto dc_end;                  \
+            }                                     \
+     default: goto other;                          \
+     }                                             \
+                                                   \
+     break
+
+
+#define Reco_CASE                                 \
+     p += 4;                                      \
+     val = READ(p);                               \
+     switch(val) {                                \
+     case rd_R:                                   \
+            p += 4;                              \
+            val = READ(p);                       \
+            if (val == oute) {                   \
+                    hdr->type = HDR_RECORDROUTE; \
+                    p += 4;                      \
+                    goto dc_end;                 \
+            }                                    \
+                                                  \
+            val = unify(val);                    \
+            if (val == oute) {                   \
+                    hdr->type = HDR_RECORDROUTE; \
+                    p += 4;                      \
+                    goto dc_end;                 \
+            }                                    \
+            goto other;                          \
+     }                                            \
+                                                  \
+     val = unify(val);                            \
+     switch(val) {                                \
+     case rd_R:                                   \
+            p += 4;                              \
+            val = READ(p);                       \
+            if (val == oute) {                   \
+                    hdr->type = HDR_RECORDROUTE; \
+                    p += 4;                      \
+                    goto dc_end;                 \
+            }                                    \
+                                                  \
+            val = unify(val);                    \
+            if (val == oute) {                   \
+                    hdr->type = HDR_RECORDROUTE; \
+                    p += 4;                      \
+                    goto dc_end;                 \
+            }                                    \
+     default: goto other;                         \
+     }                                            \
+     break
+
+
+#define Via2_CASE         \
+     hdr->type = HDR_VIA; \
+     p += 4;              \
+     goto dc_end
+
+
+#define READ(val) \
+(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
+
+/*
+ * Yet another parse_hname - Ultra Fast version :-)
+ */
+char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
+{
+       register char* p;
+       register int val;
+
+       p = begin;
+       val = READ(p);
+       hdr->name.s = begin;
+
+       if ((end - begin) < 4) {
+               hdr->type = HDR_ERROR;
+               return begin;
+       }
+
+       switch(val) {
+       case Via1: Via1_CASE;
+       case From: From_CASE;
+       case To12: To12_CASE;
+       case CSeq: CSeq_CASE;
+       case Call: Call_CASE;
+       case Cont: Cont_CASE;
+       case Rout: Rout_CASE;
+       case Max_: Max_CASE;
+       case Reco: Reco_CASE;
+        case Via2: Via2_CASE;
+
+       default:
+               switch(*p) {
+               case 'T':
+               case 't':
+                       switch(*(p + 1)) {
+                       case 'o':
+                       case 'O':
+                       case ' ':   /* Short form */
+                               hdr->type = HDR_TO;
+                               p += 2;
+                               goto dc_end;
+
+                       case ':':
+                               hdr->type = HDR_TO;
+                               hdr->name.len = 1;
+                               *(p + 1) = '\0';
+                               return (p + 2);
+                       }
+
+               case 'V':
+               case 'v':
+                       switch(*(p + 1)) {
+                       case ' ':
+                               hdr->type = HDR_VIA;
+                               p += 2;
+                               goto dc_end;
+                               
+                       case ':':
+                               hdr->type = HDR_VIA;
+                               hdr->name.len = 1;
+                               *(p + 1) = '\0';
+                               return (p + 2);
+                       }
+                       break;
+
+               case 'F':
+               case 'f':
+                       switch(*(p + 1)) {
+                       case ' ':
+                               hdr->type = HDR_FROM;
+                               p += 2;
+                               goto dc_end;
+                               
+                       case ':':
+                               hdr->type = HDR_FROM;
+                               hdr->name.len = 1;
+                               *(p + 1)= '\0';
+                               return (p + 2);
+                       }
+                       break;
+
+               case 'I':
+               case 'i':
+                       switch(*(p + 1)) {
+                       case ' ':
+                               hdr->type = HDR_CALLID;
+                               p += 2;
+                               goto dc_end;
+                               
+                       case ':':
+                               hdr->type = HDR_CALLID;
+                               hdr->name.len = 1;
+                               *(p + 1) = '\0';
+                               return (p + 2);
+                       }
+                       break;
+
+               case 'M':
+               case 'm':
+                       switch(*(p + 1)) {
+                       case ' ':
+                               hdr->type = HDR_CONTACT;
+                               p += 2;
+                               goto dc_end;
+                               
+                       case ':':
+                               hdr->type = HDR_CONTACT;
+                               hdr->name.len = 1;
+                               *(p + 1) = '\0';
+                               return (p + 2);
+                       }
+                       break;
+               }
+               
+               val = unify(val);
+               switch(val) {
+               case Via1: Via1_CASE;
+               case From: From_CASE;
+               case To12: To12_CASE;
+               case CSeq: CSeq_CASE;                                                             
+               case Call: Call_CASE;
+               case Cont: Cont_CASE;
+               case Rout: Rout_CASE;                                                             
+               case Max_: Max_CASE;
+               case Reco: Reco_CASE;
+               case Via2: Via2_CASE;
+               default: goto other;
+               }
+        }
+
+            /* Double colon hasn't been found yet */
+ dc_end:
+               p = skip_ws(p, end - p);
+       if (*p != ':') {   
+               goto other;
+       } else {
+               hdr->name.len = p - hdr->name.s;
+               *p = '\0';
+               return (p + 1);
+       }
+
+            /* Unknown header type */
+ other:    
+       p = q_memchr(p, ':', end - p);
+       if (!p) {        /* No double colon found, error.. */
+               hdr->type = HDR_ERROR;
+               hdr->name.s = NULL;
+               hdr->name.len = 0;
+               return NULL;
+       } else {
+               hdr->type = HDR_OTHER;
+               *p = '\0';
+               hdr->name.len = p - hdr->name.s;
+               return (p + 1);
+       }
+}
+
+
+void init_htable(void)
+{
+       int i;
+
+            /*
+             * Create hash table array
+             */
+
+/*
+       hash_table = (struct ht_entry*)malloc(HASH_TABLE_SIZE * sizeof(struct ht_entry));
+
+*/
+            /*
+             * Mark all elements as empty
+             */
+       for(i = 0; i < HASH_TABLE_SIZE; i++) {
+               set_entry(HASH_EMPTY, HASH_EMPTY);
+       }
+
+        set_entry(via1, Via1);
+       set_entry(viA1, Via1);
+       set_entry(vIa1, Via1);
+        set_entry(vIA1, Via1);
+        set_entry(Via1, Via1);
+        set_entry(ViA1, Via1);
+       set_entry(VIa1, Via1);
+       set_entry(VIA1, Via1);
+       
+        set_entry(via2, Via2);
+       set_entry(viA2, Via2);
+       set_entry(vIa2, Via2);
+       set_entry(vIA2, Via2);
+       set_entry(Via2, Via2);
+       set_entry(ViA2, Via2);
+       set_entry(VIa2, Via2);
+       set_entry(VIA2, Via2);
+       
+       set_entry(from, From);
+       set_entry(froM, From);
+       set_entry(frOm, From);
+       set_entry(frOM, From);
+       set_entry(fRom, From);
+       set_entry(fRoM, From);
+       set_entry(fROm, From);
+       set_entry(fROM, From);
+       set_entry(From, From);
+       set_entry(FroM, From);
+       set_entry(FrOm, From);
+       set_entry(FrOM, From);
+       set_entry(FRom, From);
+       set_entry(FRoM, From);
+       set_entry(FROm, From);
+       set_entry(FROM, From);
+       
+       set_entry(to12, To12);
+       set_entry(tO12, To12);
+       set_entry(To12, To12);
+       set_entry(TO12, To12);
+
+       set_entry(to21, To21);
+       set_entry(tO21, To21);
+       set_entry(To21, To21);
+       set_entry(TO21, To21);
+
+       set_entry(cseq, CSeq);
+       set_entry(cseQ, CSeq);
+       set_entry(csEq, CSeq);
+       set_entry(csEQ, CSeq);
+       set_entry(cSeq, CSeq);
+       set_entry(cSeQ, CSeq);
+       set_entry(cSEq, CSeq);
+       set_entry(cSEQ, CSeq);
+       set_entry(Cseq, CSeq);
+       set_entry(CseQ, CSeq);
+       set_entry(CsEq, CSeq);
+       set_entry(CsEQ, CSeq);
+       set_entry(CSeq, CSeq);
+       set_entry(CSeQ, CSeq);
+       set_entry(CSEq, CSeq);
+       set_entry(CSEQ, CSeq);
+       
+       set_entry(call, Call);
+       set_entry(calL, Call);
+       set_entry(caLl, Call);
+       set_entry(caLL, Call);
+       set_entry(cAll, Call);
+       set_entry(cAlL, Call);
+       set_entry(cALl, Call);
+       set_entry(cALL, Call);
+       set_entry(Call, Call);
+       set_entry(CalL, Call);
+       set_entry(CaLl, Call);
+       set_entry(CaLL, Call);
+       set_entry(CAll, Call);
+       set_entry(CAlL, Call);
+       set_entry(CALl, Call);
+       set_entry(CALL, Call);
+
+       set_entry(_id1, _ID1);
+       set_entry(_iD1, _ID1);
+       set_entry(_Id1, _ID1);
+       set_entry(_ID1, _ID1);
+
+       set_entry(_id2, _ID2);
+       set_entry(_iD2, _ID2);
+       set_entry(_Id2, _ID2);
+       set_entry(_ID2, _ID2);
+
+       set_entry(cont, Cont);
+       set_entry(conT, Cont);
+       set_entry(coNt, Cont);
+       set_entry(coNT, Cont);
+       set_entry(cOnt, Cont);
+       set_entry(cOnT, Cont);
+       set_entry(cONt, Cont);
+       set_entry(cONT, Cont);
+       set_entry(Cont, Cont);
+       set_entry(ConT, Cont);
+       set_entry(CoNt, Cont);
+       set_entry(CoNT, Cont);
+       set_entry(COnt, Cont);
+       set_entry(COnT, Cont);
+       set_entry(CONt, Cont);
+       set_entry(CONT, Cont);
+
+       set_entry(act1, act1);
+       set_entry(acT1, act1);
+       set_entry(aCt1, act1);
+       set_entry(aCT1, act1);
+       set_entry(Act1, act1);
+       set_entry(AcT1, act1);
+       set_entry(ACt1, act1);
+       set_entry(ACT1, act1);
+
+       set_entry(act2, act2);
+       set_entry(acT2, act2);
+       set_entry(aCt2, act2);
+       set_entry(aCT2, act2);
+       set_entry(Act2, act2);
+       set_entry(AcT2, act2);
+       set_entry(ACt2, act2);
+       set_entry(ACT2, act2);
+
+       set_entry(max_, Max_);
+       set_entry(maX_, Max_);
+       set_entry(mAx_, Max_);
+       set_entry(mAX_, Max_);
+       set_entry(Max_, Max_);
+       set_entry(MaX_, Max_);
+       set_entry(MAx_, Max_);
+       set_entry(MAX_, Max_);
+
+       set_entry(forw, Forw);
+       set_entry(forW, Forw);
+       set_entry(foRw, Forw);
+       set_entry(foRW, Forw);
+       set_entry(fOrw, Forw);
+       set_entry(fOrW, Forw);
+       set_entry(fORw, Forw);
+       set_entry(fORW, Forw);
+       set_entry(Forw, Forw);
+       set_entry(ForW, Forw);
+       set_entry(FoRw, Forw);
+       set_entry(FoRW, Forw);
+       set_entry(FOrw, Forw);
+       set_entry(FOrW, Forw);
+       set_entry(FORw, Forw);
+       set_entry(FORW, Forw);
+
+       set_entry(ards, ards);
+       set_entry(ardS, ards);
+       set_entry(arDs, ards);
+       set_entry(arDS, ards);
+       set_entry(aRds, ards);
+       set_entry(aRdS, ards);
+       set_entry(aRDs, ards);
+       set_entry(aRDS, ards);
+       set_entry(Ards, ards);
+       set_entry(ArdS, ards);
+       set_entry(ArDs, ards);
+       set_entry(ArDS, ards);
+       set_entry(ARds, ards);
+       set_entry(ARdS, ards);
+       set_entry(ARDs, ards);
+       set_entry(ARDS, ards);
+
+       set_entry(rout, Rout);
+       set_entry(rouT, Rout);
+       set_entry(roUt, Rout);
+       set_entry(roUT, Rout);
+       set_entry(rOut, Rout);
+       set_entry(rOuT, Rout);
+       set_entry(rOUt, Rout);
+       set_entry(rOUT, Rout);
+       set_entry(Rout, Rout);
+       set_entry(RouT, Rout);
+       set_entry(RoUt, Rout);
+       set_entry(RoUT, Rout);
+       set_entry(ROut, Rout);
+       set_entry(ROuT, Rout);
+       set_entry(ROUt, Rout);
+       set_entry(ROUT, Rout);
+
+       set_entry(reco, Reco);
+       set_entry(recO, Reco);
+       set_entry(reCo, Reco);
+       set_entry(reCO, Reco);
+       set_entry(rEco, Reco);
+       set_entry(rEcO, Reco);
+       set_entry(rECo, Reco);
+       set_entry(rECO, Reco);
+       set_entry(Reco, Reco);
+       set_entry(RecO, Reco);
+       set_entry(ReCo, Reco);
+       set_entry(ReCO, Reco);
+       set_entry(REco, Reco);
+       set_entry(REcO, Reco);
+       set_entry(RECo, Reco);
+       set_entry(RECO, Reco);
+
+       set_entry(rd_r, rd_R);
+       set_entry(rd_R, rd_R);
+       set_entry(rD_r, rd_R);
+       set_entry(rD_R, rd_R);
+       set_entry(Rd_r, rd_R);
+       set_entry(Rd_R, rd_R);
+       set_entry(RD_r, rd_R);
+       set_entry(RD_R, rd_R);
+
+       set_entry(oute, oute);
+       set_entry(outE, oute);
+       set_entry(ouTe, oute);
+       set_entry(ouTE, oute);
+       set_entry(oUte, oute);
+       set_entry(oUtE, oute);
+       set_entry(oUTe, oute);
+       set_entry(oUTE, oute);
+       set_entry(Oute, oute);
+       set_entry(OutE, oute);
+       set_entry(OuTe, oute);
+       set_entry(OuTE, oute);
+       set_entry(OUte, oute);
+       set_entry(OUtE, oute);
+       set_entry(OUTe, oute);
+       set_entry(OUTE, oute);
+}
+
+
similarity index 99%
rename from parse_to.c
rename to parser/parse_to.c
index 5987f63..87e2886 100644 (file)
@@ -2,10 +2,10 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include "dprint.h"
+#include "../dprint.h"
 #include "msg_parser.h"
-#include "ut.h"
-#include "mem/mem.h"
+#include "../ut.h"
+#include "../mem/mem.h"
 
 
 enum{ START_TO, DISPLAY_QUOTED, E_DISPLAY_QUOTED, DISPLAY_TOKEN
similarity index 99%
rename from parse_via.c
rename to parser/parse_via.c
index 779d155..ff5dbe2 100644 (file)
 
 #include <stdlib.h>
 #include <string.h>
-#include "dprint.h"
+#include "../dprint.h"
 #include "msg_parser.h"
-#include "ut.h"
-#include "mem/mem.h"
+#include "../ut.h"
+#include "../mem/mem.h"
 
 
 
similarity index 96%
rename from parser_f.c
rename to parser/parser_f.c
index ac0bd78..75c3558 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include  "parser_f.h"
-#include "ut.h"
+#include "../ut.h"
 
 /* returns pointer to next line or after the end of buffer */
 char* eat_line(char* buffer, unsigned int len)
similarity index 100%
rename from parser_f.h
rename to parser/parser_f.h
index 60547e3..2e43a9d 100644 (file)
--- a/receive.c
+++ b/receive.c
@@ -9,7 +9,7 @@
 #include "receive.h"
 #include "dprint.h"
 #include "route.h"
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 #include "forward.h"
 #include "action.h"
 #include "mem/mem.h"
diff --git a/route.h b/route.h
index ac298f3..104b740 100644 (file)
--- a/route.h
+++ b/route.h
@@ -12,7 +12,7 @@
 #include "config.h"
 #include "error.h"
 #include "route_struct.h"
-#include "msg_parser.h"
+#include "parser/msg_parser.h"
 
 /*#include "cfg_parser.h" */
 
index 28c3af9..04d78a4 100644 (file)
@@ -26,7 +26,8 @@ enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O, ACTION_O, NUMBER_O};
 
 enum { FORWARD_T=1, SEND_T, 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, IF_T, MODULE_T };
+               SET_PORT_T, SET_URI_T, IF_T, MODULE_T,
+               SETFLAG_T, RESETFLAG_T, ISFLAGSET_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 };
 
index 4912983..9e8764d 100644 (file)
@@ -7,7 +7,7 @@
 #ifndef sr_module_h
 #define sr_module_h
 
-#include "msg_parser.h" /* for sip_msg */
+#include "parser/msg_parser.h" /* for sip_msg */
 
 typedef  struct module_exports* (*module_register)();
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);