Browse code

- added loadable module support (sr_module.*) - bumped ver. no (WARNING: not tested yet)

Andrei Pelinescu-Onciul authored on 24/10/2001 12:43:39
Showing 9 changed files
... ...
@@ -35,7 +35,7 @@ YACC=bison
35 35
 YACC_FLAGS=-d -b cfg
36 36
 # on linux and freebsd keep it empty (e.g. LIBS= )
37 37
 # on solaris add -lxnet (e.g. LIBS= -lxnet)
38
-LIBS=-lfl
38
+LIBS=-lfl -ldl
39 39
 
40 40
 endif 
41 41
 ifeq  ($(ARCH), SunOS)
... ...
@@ -46,7 +46,7 @@ CFLAGS=-O2 -Wcast-align
46 46
 LEX=flex
47 47
 YACC=yacc
48 48
 YACC_FLAGS=-d -b cfg
49
-LIBS=-lfl -L/usr/local/lib -lxnet # or -lnsl -lsocket or -lglibc ?
49
+LIBS=-lfl -ldl -L/usr/local/lib -lxnet # or -lnsl -lsocket or -lglibc ?
50 50
 
51 51
 endif
52 52
 ifeq ($(ARCH), FreeBSD)
... ...
@@ -57,7 +57,7 @@ CFLAGS=-O2 -Wcast-align
57 57
 LEX=flex
58 58
 YACC=yacc
59 59
 YACC_FLAGS=-d -b cfg
60
-LIBS=-lfl
60
+LIBS=-lfl -ldl
61 61
 
62 62
 endif
63 63
 
... ...
@@ -70,7 +70,7 @@ YACC=bison
70 70
 YACC_FLAGS=-d -b cfg
71 71
 # on linux and freebsd keep it empty (e.g. LIBS= )
72 72
 # on solaris add -lxnet (e.g. LIBS= -lxnet)
73
-LIBS=-lfl
73
+LIBS=-lfl -ldl
74 74
 
75 75
 endif
76 76
 
... ...
@@ -13,6 +13,7 @@
13 13
 #include "udp_server.h"
14 14
 #include "route.h"
15 15
 #include "msg_parser.h"
16
+#include "sr_module.h"
16 17
 
17 18
 #include <sys/types.h>
18 19
 #include <sys/socket.h>
... ...
@@ -274,6 +275,14 @@ int do_action(struct action* a, struct sip_msg* msg)
274 275
 					}
275 276
 				}
276 277
 			break;
278
+		case MODULE_T:
279
+			if ( ((a->p1_type==CMDF_ST)&&a->p1.data)&&
280
+					((a->p2_type==STRING_ST)&&a->p2.data) ){
281
+				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data);
282
+			}else{
283
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
284
+			}
285
+			break;
277 286
 		default:
278 287
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
279 288
 	}
... ...
@@ -80,13 +80,15 @@ PORT	port
80 80
 CHILDREN children
81 81
 CHECK_VIA	check_via
82 82
 
83
+LOADMODULE	loadmodule
84
+
83 85
 /* values */
84 86
 YES			"yes"|"true"|"on"|"enable"
85 87
 NO			"no"|"false"|"off"|"disable"
86 88
 
87 89
 LETTER		[a-zA-Z]
88 90
 DIGIT		[0-9]
89
-ALPHANUM	{LETTER}|{DIGIT}
91
+ALPHANUM	{LETTER}|{DIGIT}|[_]
90 92
 NUMBER		{DIGIT}+
91 93
 ID			{LETTER}{ALPHANUM}*
92 94
 QUOTES		\"
... ...
@@ -146,6 +148,7 @@ EAT_ABLE	[\ \t\b\r]
146 148
 <INITIAL>{PORT}	{ count(); yylval.strval=yytext; return PORT; }
147 149
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
148 150
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
151
+<INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
149 152
 
150 153
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
151 154
 <INITIAL>{EQUAL_T}	{ count(); return EQUAL_T; }
... ...
@@ -17,6 +17,7 @@
17 17
 #include "globals.h"
18 18
 #include "route.h"
19 19
 #include "dprint.h"
20
+#include "sr_module.h"
20 21
 
21 22
 #ifdef DEBUG_DMALLOC
22 23
 #include <dmalloc.h>
... ...
@@ -24,6 +25,7 @@
24 25
 
25 26
 void yyerror(char* s);
26 27
 char* tmp;
28
+void* f_tmp;
27 29
 
28 30
 %}
29 31
 
... ...
@@ -71,6 +73,7 @@ char* tmp;
71 73
 %token PORT
72 74
 %token CHILDREN
73 75
 %token CHECK_VIA
76
+%token LOADMODULE
74 77
 
75 78
 
76 79
 
... ...
@@ -125,6 +128,7 @@ statements:	statements statement {}
125 128
 	;
126 129
 
127 130
 statement:	assign_stm 
131
+		| module_stm
128 132
 		| route_stm 
129 133
 		| CR	/* null statement*/
130 134
 	;
... ...
@@ -205,6 +209,14 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
205 209
 		| error EQUAL { yyerror("unknown config variable"); }
206 210
 	;
207 211
 
212
+module_stm:	LOADMODULE STRING	{ DBG("loading module %s", $2);
213
+		  						  if (load_module($2)!=0){
214
+								  		yyerror("failed to load module");
215
+								  }
216
+								}
217
+		 |	LOADMODULE error	{ yyerror("string expected");  }
218
+		 ;
219
+
208 220
 
209 221
 ipv4:	NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
210 222
 											if (($1>255) || ($1<0) ||
... ...
@@ -542,6 +554,22 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
542 554
 		| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
543 555
 		| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
544 556
 										"string expected"); }
557
+		| ID LPAREN STRING RPAREN { DBG(" %s - doing nothing", $1);
558
+									f_tmp=find_export($1);
559
+									if (f_tmp==0){
560
+										yyerror("unknown command %s, missing"
561
+										" loadmodule?\n");
562
+										$$=0;
563
+									}else{
564
+										$$=mk_action(	MODULE_T,
565
+														CMDF_ST,
566
+														STRING_ST,
567
+														f_tmp,
568
+														$3
569
+													);
570
+									}
571
+								  }
572
+		| ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
545 573
 		| if_cmd		{ $$=$1; }
546 574
 	;
547 575
 
... ...
@@ -30,7 +30,7 @@
30 30
 
31 31
 
32 32
 static char id[]="@(#) $Id$";
33
-static char version[]="ser 0.7";
33
+static char version[]="ser 0.8.1-plugins";
34 34
 static char flags[]="NOCR:"
35 35
 #ifdef NOCR
36 36
 "On"
... ...
@@ -57,6 +57,7 @@ struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2)
57 57
 	struct action* a;
58 58
 	a=(struct action*)malloc(sizeof(struct action));
59 59
 	if (a==0) goto  error;
60
+	memset(a,0,sizeof(struct action));
60 61
 	a->type=type;
61 62
 	a->p1_type=p1_type;
62 63
 	a->p2_type=p2_type;
... ...
@@ -279,6 +280,9 @@ void print_action(struct action* a)
279 280
 			case IF_T:
280 281
 					DBG("if (");
281 282
 					break;
283
+			case MODULE_T:
284
+					DBG(" external_module_call(");
285
+					break;
282 286
 			default:
283 287
 					DBG("UNKNOWN(");
284 288
 		}
... ...
@@ -298,6 +302,9 @@ void print_action(struct action* a)
298 302
 			case ACTIONS_ST:
299 303
 					print_action((struct action*)t->p1.data);
300 304
 					break;
305
+			case CMDF_ST:
306
+					DBG("f_ptr<%x>",t->p1.data);
307
+					break;
301 308
 			default:
302 309
 					DBG("type<%d>", t->p1_type);
303 310
 		}
... ...
@@ -13,9 +13,9 @@ enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O, DEFAULT_O, ACTION_O, NUMBER_O};
13 13
 
14 14
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
15 15
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T, 
16
-		SET_PORT_T, SET_URI_T, IF_T };
16
+		SET_PORT_T, SET_URI_T, IF_T, MODULE_T };
17 17
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
18
-		EXPR_ST, ACTIONS_ST };
18
+		EXPR_ST, ACTIONS_ST, CMDF_ST };
19 19
 
20 20
 	
21 21
 struct expr{
22 22
new file mode 100644
... ...
@@ -0,0 +1,93 @@
1
+/* $Id$
2
+ */
3
+
4
+#include "sr_module.h"
5
+#include "dprint.h"
6
+
7
+#include <dlfcn.h>
8
+#include <strings.h>
9
+#include <stdlib.h>
10
+
11
+
12
+static struct sr_module* modules=0;
13
+
14
+
15
+
16
+/* returns 0 on success , <0 on error */
17
+int load_module(char* path)
18
+{
19
+	void* handle;
20
+	char* error;
21
+	struct sr_module* t, *mod;
22
+	struct module_exports* e;
23
+	struct module_exports* (*mod_register)();
24
+	
25
+	handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
26
+	if (handle==0){
27
+		LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
28
+					path, dlerror() );
29
+		goto error;
30
+	}
31
+	
32
+	for(t=modules;t; t=t->next){
33
+		if (t->handle==handle){
34
+			LOG(L_WARN, "WARNING: load_module: attempting to load the same"
35
+						" module twice (%s)\n", path);
36
+			goto skip;
37
+		}
38
+	}
39
+	/* launch register */
40
+	mod_register = dlsym(handle, "mod_register");
41
+	if ( (error =dlerror())!=0 ){
42
+		LOG(L_ERR, "ERROR: load_module: %s\n", error);
43
+		goto error1;
44
+	}
45
+	
46
+	e=(*mod_register)();
47
+	if (e==0){
48
+		LOG(L_ERR, "ERROR: mod_register returned null\n");
49
+		goto error1;
50
+	}
51
+	/* add module to the list */
52
+	if ((mod=malloc(sizeof(struct sr_module)))==0){
53
+		LOG(L_ERR, "load_module: memory allocation failure\n");
54
+		goto error1;
55
+	}
56
+	memset(mod,0, sizeof(struct sr_module));
57
+	mod->path=path;
58
+	mod->handle=handle;
59
+	mod->exports=e;
60
+	mod->next=modules;
61
+	modules=mod;
62
+	return 0;
63
+
64
+error1:
65
+	dlclose(handle);
66
+error:
67
+skip:
68
+	return -1;
69
+}
70
+
71
+
72
+
73
+/* searches the module list and returns a pointer to the "name" function or
74
+ * 0 if not found */
75
+cmd_function find_export(char* name)
76
+{
77
+	struct sr_module* t;
78
+	int r;
79
+
80
+	for(t=modules;t;t=t->next){
81
+		for(r=0;r<t->exports->cmd_no;r++){
82
+			if(strcmp(name, t->exports->cmd_names[r])==0){
83
+				DBG("find_export: found <%s> in module %s [%s]\n",
84
+						name, t->exports->name, t->path);
85
+				return t->exports->cmd_pointers[r];
86
+			}
87
+		}
88
+	}
89
+	DBG("find_export: <%s> not found \n", name);
90
+	return 0;
91
+}
92
+
93
+	
0 94
new file mode 100644
... ...
@@ -0,0 +1,44 @@
1
+/* $Id$
2
+ *
3
+ * modules/plugin strtuctures declarations
4
+ *
5
+ */
6
+
7
+#ifndef sr_module
8
+
9
+#include "msg_parser.h" /* for sip_msg */
10
+
11
+typedef  int (*cmd_function)(struct sip_msg*, char*);
12
+typedef  int (*response_function)(struct sip_msg*);
13
+
14
+struct module_exports{
15
+	char* name; /* null terminated module name */
16
+	char** cmd_names;
17
+	cmd_function* cmd_pointers;
18
+	int cmd_no; /* number of registered commands 
19
+				   (size of cmd_{names,pointers}*/
20
+	response_function response_f; /* function used for responses,
21
+											   returns yes or no */
22
+};
23
+
24
+struct sr_module{
25
+	char* path;
26
+	void* handle;
27
+	struct module_exports* exports;
28
+	struct sr_module* next;
29
+};
30
+
31
+
32
+int load_module(char* path);
33
+cmd_function find_export(char* name);
34
+
35
+/* modules function prototypes:
36
+ * struct module_exports* mod_register();
37
+ * int   foo_cmd(struct sip_msg* msg, char* param);
38
+ *  - returns >0 if ok , <0 on error, 0 to stop processing (==DROP)
39
+ * int   response_f(struct sip_msg* msg)
40
+ *  - returns >0 if ok, 0 to drop message
41
+ */
42
+
43
+
44
+#endif