> Tarek,
> 
> This looks like a nice patch, which will make the scenario language much 
> more extensible.
> 
> I just have two suggestions:
> 1.  Would it be possible to compile the regular expression when reading 
> the XML file?  This would eliminate some per-message overhead, and improve 
> performance at high loads.  I am not sure if this would be difficult to 
> implement or not.

Good suggestion.  Rather than compiling at parse time, I made a change to only 
perform the compile once, for the first call, and then store the compiled expr 
in the message class, so I believe it amounts to the same thing.

New diff attached (this replaces the previous diff)

> 2.  This could also make sense for the reply codes as well as requests. 
> For example, instead of using <recv reply="100" /> to match a 100 reply, 
> the regular expression <recv reply="1.." /> could match any provisional 
> response.  Conversely, reply="[2-6].." would match any final reply.  I am 
> not 100% sure what I would use this for yet, but it seems like a logical 
> extension.

The issue here is that recv reply is given an atol() treatment, where recv 
request is stored as a string, so there would be a bit more surgery to keep 
recv reply as string and convert the compare operations over, and I suspect I'd 
need to store the successful match off for return_code matching...  I'll keep 
it in mind, however, next time I find myself with some time.

> Charles
> 

diff -bruN sipp.2007-01-08/call.cpp sipp.2007-01-08.new/call.cpp
--- sipp.2007-01-08/call.cpp    2006-12-21 05:24:42.000000000 -0500
+++ sipp.2007-01-08.new/call.cpp        2007-01-09 18:01:30.917636168 -0500
@@ -2601,6 +2601,41 @@
   }
 }
 
+bool call::matches_scenario(int index, int reply_code, char * request, char * 
responsecseqmethod)
+{         
+  int        result;
+          
+  if ((reply_code) && ((scenario[index] -> recv_response) == reply_code) && \
+     (scenario[index]->recv_response_for_cseq_method_list) && \
+     (strstr(scenario[index]->recv_response_for_cseq_method_list, 
responsecseqmethod))) {
+        return true;
+  }   
+    
+  if ((scenario[index] -> recv_request) && \
+     (!strcmp(scenario[index] -> recv_request, request))) {
+        return true;
+  } 
+  
+  if ((scenario[index] -> recv_request) && (scenario[index] -> regexp_match)) {
+  
+     if (scenario[index] -> regexp_compile == NULL) {
+        regex_t *re = new regex_t;
+        if (regcomp(re, scenario[index] -> recv_request, 
REG_EXTENDED|REG_NOSUB)) {
+           // regexp is not well formed
+           scenario[index] -> regexp_match = 0;
+           free(re);
+           return false;
+        }
+        scenario[index] -> regexp_compile = re;
+     }
+
+     result = regexec(scenario[index] -> regexp_compile, request, (size_t)0, 
NULL, 0);
+     if (!result) return true;
+  }
+
+  return false;
+}
+
 bool call::process_incoming(char * msg)
 {
   int             reply_code;
@@ -2622,15 +2657,6 @@
    /* Ignore the messages received during a pause if -pause_msg_ign is set */
    if(scenario[msg_index] -> M_type == MSG_TYPE_PAUSE && pause_msg_ign) 
return(true);
 
-#define MATCHES_SCENARIO(index)                                \
-      (((reply_code) &&                                        \
-        ((scenario[index] -> recv_response) == reply_code) &&            \
-         (scenario[index]->recv_response_for_cseq_method_list) &&   \
-        (strstr(scenario[index]->recv_response_for_cseq_method_list, 
responsecseqmethod))) ||  \
-       ((scenario[index] -> recv_request) &&                   \
-        (!strcmp(scenario[index] -> recv_request,              \
-                 request))))
-
   /* Authorize nop as a first command, even in server mode */
   if((msg_index == 0) && (scenario[msg_index] -> M_type == MSG_TYPE_NOP)) {
     actionResult = executeAction(NULL, msg_index);
@@ -2755,7 +2781,7 @@
   for(search_index = msg_index;
       search_index < scenario_len;
       search_index++) {
-    if(!MATCHES_SCENARIO(search_index)) {
+    if(!matches_scenario(search_index, reply_code, request, 
responsecseqmethod)) {
       if(scenario[search_index] -> optional) {
         continue;
       }
@@ -2778,7 +2804,7 @@
         search_index >= 0;
         search_index--) {
       if (scenario[search_index]->optional == OPTIONAL_FALSE) contig = false;
-      if(MATCHES_SCENARIO(search_index)) {
+      if(matches_scenario(search_index, reply_code, request, 
responsecseqmethod)) {
         if (contig || scenario[search_index]->optional == OPTIONAL_GLOBAL) {
          found = true;
          break;  
diff -bruN sipp.2007-01-08/call.hpp sipp.2007-01-08.new/call.hpp
--- sipp.2007-01-08/call.hpp    2006-11-01 22:45:18.000000000 -0500
+++ sipp.2007-01-08.new/call.hpp        2007-01-09 11:32:11.053090282 -0500
@@ -209,6 +209,7 @@
   bool run(); 
   void formatNextReqUrl (char* next_req_url);
   void computeRouteSetAndRemoteTargetUri (char* rrList, char* contact, bool 
bRequestIncoming);
+  bool matches_scenario(int index, int reply_code, char * request, char * 
responsecseqmethod);
   bool process_incoming(char * msg);
 
   T_ActionResult executeAction(char * msg, int scenarioIndex);
diff -bruN sipp.2007-01-08/scenario.cpp sipp.2007-01-08.new/scenario.cpp
--- sipp.2007-01-08/scenario.cpp        2006-12-20 07:57:58.000000000 -0500
+++ sipp.2007-01-08.new/scenario.cpp    2007-01-09 18:05:03.871740165 -0500
@@ -54,6 +54,8 @@
   recv_response = 0;
   recv_request = NULL;
   optional = 0;
+  regexp_match = 0;
+  regexp_compile = NULL;
 
   /* Anyway */
   start_rtd = 0;
@@ -101,6 +103,11 @@
     free (recv_request);
   recv_request = NULL;
 
+  if(regexp_compile != NULL)
+    regfree(regexp_compile);
+    free(regexp_compile);
+  regexp_compile = NULL;
+
 #ifdef __3PCC__
   if(M_sendCmdData != NULL)
     delete(M_sendCmdData);
@@ -518,6 +525,12 @@
          }
         }
 
+        if (0 != (ptr = xp_get_value((char *)"regexp_match"))) {
+          if(!strcmp(ptr, "true")) {
+            scenario[scenario_len] -> regexp_match = 1;
+          }
+        }
+
         if (0 != (ptr = xp_get_value((char *)"timeout"))) {
           scenario[scenario_len]->retrans_delay = get_long(ptr, "message 
timeout");
         }
diff -bruN sipp.2007-01-08/scenario.hpp sipp.2007-01-08.new/scenario.hpp
--- sipp.2007-01-08/scenario.hpp        2006-12-20 07:57:58.000000000 -0500
+++ sipp.2007-01-08.new/scenario.hpp    2007-01-09 18:02:05.410983806 -0500
@@ -102,6 +102,8 @@
   unsigned int   recv_response;
   char         * recv_request;
   int            optional;
+  int            regexp_match;
+  regex_t      * regexp_compile;
 
   /* Anyway */
   int            start_rtd;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Sipp-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sipp-users

Reply via email to