Bläddra i källkod

- added support for maximum 2 parameters per cmd call
- added parameters no. for every function (can be 0, 1 or 2).
- new example module (textops)

Andrei Pelinescu-Onciul 24 år sedan
förälder
incheckning
34fd2612cd
11 ändrade filer med 160 tillägg och 20 borttagningar
  1. 3 1
      Makefile
  2. 2 1
      action.c
  3. 4 0
      cfg.lex
  4. 32 1
      cfg.y
  5. 61 5
      forward.c
  6. 1 1
      main.c
  7. 2 1
      receive.c
  8. 20 2
      route.c
  9. 20 3
      sr_module.c
  10. 10 4
      sr_module.h
  11. 5 1
      test/test2.cfg

+ 3 - 1
Makefile

@@ -6,10 +6,12 @@
 #  Arch supported: Linux, FreeBSD, SunOS (tested on Solaris 6), WinNT
 
 auto_gen=lex.yy.c cfg.tab.c   #lexx, yacc etc
+exclude_modules=CVS
 sources=$(filter-out $(auto_gen), $(wildcard *.c)) $(auto_gen) 
 objs=$(sources:.c=.o)
 depends=$(sources:.c=.d)
-modules=$(wildcard modules/*)
+modules=$(filter-out $(addprefix modules/, $(exclude_modules)), \
+						$(wildcard modules/*))
 
 NAME=ser
 

+ 2 - 1
action.c

@@ -278,7 +278,8 @@ int do_action(struct action* a, struct sip_msg* msg)
 		case MODULE_T:
 			if ( ((a->p1_type==CMDF_ST)&&a->p1.data)&&
 					((a->p2_type==STRING_ST)&&a->p2.data) ){
-				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data);
+				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data,
+													  (char*)a->p3.data);
 			}else{
 				LOG(L_CRIT,"BUG: do_action: bad module call\n");
 			}

+ 4 - 0
cfg.lex

@@ -197,6 +197,10 @@ EAT_ABLE	[\ \t\b\r]
 
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
+<STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
+						yyleng--; addstr(yytext, &str); }
+<STRING1>\\g		{ count(); yytext[yyleng-2]='\g';yytext[yyleng-1]=0; 
+						yyleng--; addstr(yytext, &str); }
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 

+ 32 - 1
cfg.y

@@ -554,7 +554,21 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
 		| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
 		| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
 										"string expected"); }
-		| ID LPAREN STRING RPAREN { f_tmp=find_export($1);
+		| ID LPAREN RPAREN			{ f_tmp=find_export($1, 0);
+									   if (f_tmp==0){
+										yyerror("unknown command %s, missing"
+										" loadmodule?\n");
+										$$=0;
+									   }else{
+										$$=mk_action(	MODULE_T,
+														CMDF_ST,
+														0,
+														f_tmp,
+														0
+													);
+									   }
+									}
+		| ID LPAREN STRING RPAREN { f_tmp=find_export($1, 1);
 									if (f_tmp==0){
 										yyerror("unknown command %s, missing"
 										" loadmodule?\n");
@@ -568,6 +582,23 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
 													);
 									}
 								  }
+		| ID LPAREN STRING  COMMA STRING RPAREN 
+								  { f_tmp=find_export($1, 2);
+									if (f_tmp==0){
+										yyerror("unknown command %s, missing"
+										" loadmodule?\n");
+										$$=0;
+									}else{
+										$$=mk_action3(	MODULE_T,
+														CMDF_ST,
+														STRING_ST,
+														STRING_ST,
+														f_tmp,
+														$3,
+														$5
+													);
+									}
+								  }
 		| ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
 		| if_cmd		{ $$=$1; }
 	;

+ 61 - 5
forward.c

@@ -138,9 +138,12 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 	}
 	
 	
-	/* compute new msg len*/
+	/* compute new msg len and fix overlapping zones*/
 	new_len=len;
+	s_offset=0;
 	for(t=msg->add_rm;t;t=t->next){
+		DBG("t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
+				t, t->op, t->u.offset, t->len, s_offset);
 		for(r=t->before;r;r=r->before){
 			switch(r->op){
 				case LUMP_ADD:
@@ -157,9 +160,28 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 				new_len+=t->len;
 				break;
 			case LUMP_DEL:
+				/* fix overlapping deleted zones */
+				if (t->u.offset < s_offset){
+					DBG( "overlapping DEL offsets (%d,%d(%d)), fixing...\n",
+						 s_offset, t->u.offset, t->len);
+					/* change len */
+					if (t->len>s_offset-t->u.offset) 
+							t->len-=s_offset-t->u.offset;
+					else t->len=0;
+					t->u.offset=s_offset;
+					DBG("fixed to %d(%d)\n", t->u.offset, t->len);
+				}
+				s_offset=t->u.offset+t->len;
 				new_len-=t->len;
 				break;
 			case LUMP_NOP:
+				/* fix offset if overlapping on a deleted zone */
+				if (t->u.offset < s_offset){
+					DBG("overlapping zones (%d,%d)\n", s_offset, t->u.offset);
+					t->u.offset=s_offset;
+					DBG("fixed to %d\n", t->u.offset);
+				}else
+					s_offset=t->u.offset;
 				/* do nothing */
 				break;
 			debug:
@@ -204,19 +226,53 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 	}
 /* copy msg adding/removing lumps */
 	for (t=msg->add_rm;t;t=t->next){
+		DBG(" t=%x, op=%d, offset=%x, len=%d, s_offset=%x\n",
+				t, t->op, t->u.offset, t->len, s_offset);
 		switch(t->op){
 			case LUMP_ADD:
 				/* just add it here! */
+				/* process before  */
+				for(r=t->before;r;r=r->before){
+					switch (r->op){
+						case LUMP_ADD:
+							/*just add it here*/
+							memcpy(new_buf+offset, r->u.value, r->len);
+							offset+=r->len;
+							break;
+						default:
+							/* only ADD allowed for before/after */
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
+									" data lump (%x)\n", r->op);
+								
+					}
+				}
+				/* copy "main" part */
 				memcpy(new_buf+offset, t->u.value, t->len);
 				offset+=t->len;
+				/* process after */
+				for(r=t->after;r;r=r->after){
+					switch (r->op){
+						case LUMP_ADD:
+							/*just add it here*/
+							memcpy(new_buf+offset, r->u.value, r->len);
+							offset+=r->len;
+							break;
+						default:
+							/* only ADD allowed for before/after */
+							LOG(L_CRIT, "BUG:forward_request: invalid op for"
+									" data lump (%x)\n", r->op);
+					}
+				}
 				break;
 			case LUMP_NOP:
 			case LUMP_DEL:
 				/* copy till offset */
 				if (s_offset>t->u.offset){
-					LOG(L_CRIT, "BUG: invalid offset in lump (%d)\n",
-								t->u.offset);
-					goto error;
+					DBG("Warning: (%d) overlapped lumps offsets,"
+						" ignoring(%x, %x)\n", t->op, s_offset,t->u.offset);
+					/* this should've been fixed above (when computing len) */
+					/* just ignore it*/
+					break;
 				}
 				size=t->u.offset-s_offset;
 				if (size){
@@ -232,7 +288,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 							memcpy(new_buf+offset, r->u.value, r->len);
 							offset+=r->len;
 							break;
-						defaut:
+						default:
 							/* only ADD allowed for before/after */
 							LOG(L_CRIT, "BUG:forward_request: invalid op for"
 									" data lump (%x)\n", r->op);

+ 1 - 1
main.c

@@ -30,7 +30,7 @@
 
 
 static char id[]="@(#) $Id$";
-static char version[]="ser 0.8.1-plugins";
+static char version[]="ser 0.8.2";
 static char flags[]="NOCR:"
 #ifdef NOCR
 "On"

+ 2 - 1
receive.c

@@ -26,12 +26,13 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
 	msg.len=len;
 	msg.src_ip=src_ip;
 	/* make a copy of the message */
-	msg.orig=(char*) malloc(len);
+	msg.orig=(char*) malloc(len+1);
 	if (msg.orig==0){
 		LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
 		goto error1;
 	}
 	memcpy(msg.orig, buf, len);
+	msg.orig[len]=0; /* null terminate it,good for using str* functions on it*/
 	
 	if (parse_msg(buf,len, &msg)!=0){
 		goto error;

+ 20 - 2
route.c

@@ -19,6 +19,7 @@
 #include "dprint.h"
 #include "proxy.h"
 #include "action.h"
+#include "sr_module.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -104,7 +105,8 @@ static int fix_actions(struct action* a)
 	struct action *t;
 	struct proxy_l* p;
 	char *tmp;
-	int ret;
+	int ret,r;
+	struct sr_module* mod;
 	
 	if (a==0){
 		LOG(L_CRIT,"BUG: fix_actions: null pointer\n");
@@ -140,7 +142,7 @@ static int fix_actions(struct action* a)
 							return E_BUG;
 					}
 					break;
-		case IF_T:
+			case IF_T:
 				if (t->p1_type!=EXPR_ST){
 					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
 								"%d for if (should be expr)\n",
@@ -170,6 +172,22 @@ static int fix_actions(struct action* a)
 						return ret;
 				}
 				break;
+			case MODULE_T:
+				if ((mod=find_module(t->p1.data, &r))!=0){
+					DBG("fixing %s %s\n", mod->path,
+							mod->exports->cmd_names[r]);
+					if (mod->exports->fixup_pointers[r]){
+						if (mod->exports->param_no[r]>0){
+							ret=mod->exports->fixup_pointers[r](&t->p2.data,1);
+							if (ret<0) return ret;
+						}
+						if (mod->exports->param_no[r]>1){
+							ret=mod->exports->fixup_pointers[r](&t->p3.data,2);
+							if (ret<0) return ret;
+						}
+					}
+				}
+			
 		}
 	}
 	return 0;

+ 20 - 3
sr_module.c

@@ -72,14 +72,15 @@ skip:
 
 /* searches the module list and returns a pointer to the "name" function or
  * 0 if not found */
-cmd_function find_export(char* name)
+cmd_function find_export(char* name, int param_no)
 {
 	struct sr_module* t;
 	int r;
 
 	for(t=modules;t;t=t->next){
 		for(r=0;r<t->exports->cmd_no;r++){
-			if(strcmp(name, t->exports->cmd_names[r])==0){
+			if((strcmp(name, t->exports->cmd_names[r])==0)&&
+				(t->exports->param_no[r]==param_no) ){
 				DBG("find_export: found <%s> in module %s [%s]\n",
 						name, t->exports->name, t->path);
 				return t->exports->cmd_pointers[r];
@@ -90,4 +91,20 @@ cmd_function find_export(char* name)
 	return 0;
 }
 
-	
+
+
+/* finds a module, given a pointer to a module function *
+ * returns pointer to module, & if i i!=0, *i=the function index */
+struct sr_module* find_module(void* f, int *i)
+{
+	struct sr_module* t;
+	int r;
+	for (t=modules;t;t=t->next){
+		for(r=0;r<t->exports->cmd_no;r++) 
+			if (f==t->exports->cmd_pointers[r]) {
+				if (i) *i=r;
+				return t;
+			}
+	}
+	return 0;
+}

+ 10 - 4
sr_module.h

@@ -8,13 +8,17 @@
 
 #include "msg_parser.h" /* for sip_msg */
 
-typedef  int (*cmd_function)(struct sip_msg*, char*);
+typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
+typedef  int (*fixup_function)(void** param, int param_no);
 typedef  int (*response_function)(struct sip_msg*);
 
 struct module_exports{
 	char* name; /* null terminated module name */
-	char** cmd_names;
-	cmd_function* cmd_pointers;
+	char** cmd_names; /* cmd names registered by this modules */
+	cmd_function* cmd_pointers; /* pointers to the corresponding functions */
+	int* param_no; /* number of parameters used by the function */
+	fixup_function* fixup_pointers; /* pointers to functions called to "fix"
+										the params, e.g: precompile a re */
 	int cmd_no; /* number of registered commands 
 				   (size of cmd_{names,pointers}*/
 	response_function response_f; /* function used for responses,
@@ -30,7 +34,9 @@ struct sr_module{
 
 
 int load_module(char* path);
-cmd_function find_export(char* name);
+cmd_function find_export(char* name, int param_no);
+struct sr_module* find_module(void *f, int* r);
+
 
 /* modules function prototypes:
  * struct module_exports* mod_register();

+ 5 - 1
test/test2.cfg

@@ -8,9 +8,13 @@ log_stderror=yes # (cmd line: -E)
 
 #modules
 loadmodule "modules/print/print.so"
+loadmodule "modules/textops/textops.so"
 
 route{
-	print("before forward");
+	print("before insert");
+	replace('^User-Agent:.*$', "User-Agent: ser 0.8.x");
+	print("after insert");
+	search_append('To:.*$', "Foo Bar");
 	forward(127.0.0.1,5061);
 	print("after forward");
 }