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 274
 					}
275 275
 				}
276 276
 			break;
277
+		case MODULE_T:
278
+			if ( ((a->p1_type==CMDF_ST)&&a->p1.data)&&
279
+					((a->p2_type==STRING_ST)&&a->p2.data) ){
280
+				ret=((cmd_function)(a->p1.data))(msg, (char*)a->p2.data);
281
+			}else{
282
+				LOG(L_CRIT,"BUG: do_action: bad module call\n");
283
+			}
284
+			break;
277 285
 		default:
278 286
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
279 287
 	}
... ...
@@ -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 146
 <INITIAL>{PORT}	{ count(); yylval.strval=yytext; return PORT; }
147 147
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
148 148
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
149
+<INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
149 150
 
150 151
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
151 152
 <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 24
 
25 25
 void yyerror(char* s);
26 26
 char* tmp;
27
+void* f_tmp;
27 28
 
28 29
 %}
29 30
 
... ...
@@ -71,6 +73,7 @@ char* tmp;
71 71
 %token PORT
72 72
 %token CHILDREN
73 73
 %token CHECK_VIA
74
+%token LOADMODULE
74 75
 
75 76
 
76 77
 
... ...
@@ -125,6 +128,7 @@ statements:	statements statement {}
125 125
 	;
126 126
 
127 127
 statement:	assign_stm 
128
+		| module_stm
128 129
 		| route_stm 
129 130
 		| CR	/* null statement*/
130 131
 	;
... ...
@@ -205,6 +209,14 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
205 205
 		| error EQUAL { yyerror("unknown config variable"); }
206 206
 	;
207 207
 
208
+module_stm:	LOADMODULE STRING	{ DBG("loading module %s", $2);
209
+		  						  if (load_module($2)!=0){
210
+								  		yyerror("failed to load module");
211
+								  }
212
+								}
213
+		 |	LOADMODULE error	{ yyerror("string expected");  }
214
+		 ;
215
+
208 216
 
209 217
 ipv4:	NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
210 218
 											if (($1>255) || ($1<0) ||
... ...
@@ -542,6 +554,22 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
542 542
 		| SET_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
543 543
 		| SET_URI LPAREN error RPAREN { $$=0; yyerror("bad argument, "
544 544
 										"string expected"); }
545
+		| ID LPAREN STRING RPAREN { DBG(" %s - doing nothing", $1);
546
+									f_tmp=find_export($1);
547
+									if (f_tmp==0){
548
+										yyerror("unknown command %s, missing"
549
+										" loadmodule?\n");
550
+										$$=0;
551
+									}else{
552
+										$$=mk_action(	MODULE_T,
553
+														CMDF_ST,
554
+														STRING_ST,
555
+														f_tmp,
556
+														$3
557
+													);
558
+									}
559
+								  }
560
+		| ID LPAREN error RPAREN { $$=0; yyerror("bad arguments"); }
545 561
 		| if_cmd		{ $$=$1; }
546 562
 	;
547 563
 
... ...
@@ -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 279
 			case IF_T:
280 280
 					DBG("if (");
281 281
 					break;
282
+			case MODULE_T:
283
+					DBG(" external_module_call(");
284
+					break;
282 285
 			default:
283 286
 					DBG("UNKNOWN(");
284 287
 		}
... ...
@@ -298,6 +302,9 @@ void print_action(struct action* a)
298 298
 			case ACTIONS_ST:
299 299
 					print_action((struct action*)t->p1.data);
300 300
 					break;
301
+			case CMDF_ST:
302
+					DBG("f_ptr<%x>",t->p1.data);
303
+					break;
301 304
 			default:
302 305
 					DBG("type<%d>", t->p1_type);
303 306
 		}
... ...
@@ -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 @@
0
+/* $Id$
1
+ */
2
+
3
+#include "sr_module.h"
4
+#include "dprint.h"
5
+
6
+#include <dlfcn.h>
7
+#include <strings.h>
8
+#include <stdlib.h>
9
+
10
+
11
+static struct sr_module* modules=0;
12
+
13
+
14
+
15
+/* returns 0 on success , <0 on error */
16
+int load_module(char* path)
17
+{
18
+	void* handle;
19
+	char* error;
20
+	struct sr_module* t, *mod;
21
+	struct module_exports* e;
22
+	struct module_exports* (*mod_register)();
23
+	
24
+	handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
25
+	if (handle==0){
26
+		LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
27
+					path, dlerror() );
28
+		goto error;
29
+	}
30
+	
31
+	for(t=modules;t; t=t->next){
32
+		if (t->handle==handle){
33
+			LOG(L_WARN, "WARNING: load_module: attempting to load the same"
34
+						" module twice (%s)\n", path);
35
+			goto skip;
36
+		}
37
+	}
38
+	/* launch register */
39
+	mod_register = dlsym(handle, "mod_register");
40
+	if ( (error =dlerror())!=0 ){
41
+		LOG(L_ERR, "ERROR: load_module: %s\n", error);
42
+		goto error1;
43
+	}
44
+	
45
+	e=(*mod_register)();
46
+	if (e==0){
47
+		LOG(L_ERR, "ERROR: mod_register returned null\n");
48
+		goto error1;
49
+	}
50
+	/* add module to the list */
51
+	if ((mod=malloc(sizeof(struct sr_module)))==0){
52
+		LOG(L_ERR, "load_module: memory allocation failure\n");
53
+		goto error1;
54
+	}
55
+	memset(mod,0, sizeof(struct sr_module));
56
+	mod->path=path;
57
+	mod->handle=handle;
58
+	mod->exports=e;
59
+	mod->next=modules;
60
+	modules=mod;
61
+	return 0;
62
+
63
+error1:
64
+	dlclose(handle);
65
+error:
66
+skip:
67
+	return -1;
68
+}
69
+
70
+
71
+
72
+/* searches the module list and returns a pointer to the "name" function or
73
+ * 0 if not found */
74
+cmd_function find_export(char* name)
75
+{
76
+	struct sr_module* t;
77
+	int r;
78
+
79
+	for(t=modules;t;t=t->next){
80
+		for(r=0;r<t->exports->cmd_no;r++){
81
+			if(strcmp(name, t->exports->cmd_names[r])==0){
82
+				DBG("find_export: found <%s> in module %s [%s]\n",
83
+						name, t->exports->name, t->path);
84
+				return t->exports->cmd_pointers[r];
85
+			}
86
+		}
87
+	}
88
+	DBG("find_export: <%s> not found \n", name);
89
+	return 0;
90
+}
91
+
92
+	
0 93
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+/* $Id$
1
+ *
2
+ * modules/plugin strtuctures declarations
3
+ *
4
+ */
5
+
6
+#ifndef sr_module
7
+
8
+#include "msg_parser.h" /* for sip_msg */
9
+
10
+typedef  int (*cmd_function)(struct sip_msg*, char*);
11
+typedef  int (*response_function)(struct sip_msg*);
12
+
13
+struct module_exports{
14
+	char* name; /* null terminated module name */
15
+	char** cmd_names;
16
+	cmd_function* cmd_pointers;
17
+	int cmd_no; /* number of registered commands 
18
+				   (size of cmd_{names,pointers}*/
19
+	response_function response_f; /* function used for responses,
20
+											   returns yes or no */
21
+};
22
+
23
+struct sr_module{
24
+	char* path;
25
+	void* handle;
26
+	struct module_exports* exports;
27
+	struct sr_module* next;
28
+};
29
+
30
+
31
+int load_module(char* path);
32
+cmd_function find_export(char* name);
33
+
34
+/* modules function prototypes:
35
+ * struct module_exports* mod_register();
36
+ * int   foo_cmd(struct sip_msg* msg, char* param);
37
+ *  - returns >0 if ok , <0 on error, 0 to stop processing (==DROP)
38
+ * int   response_f(struct sip_msg* msg)
39
+ *  - returns >0 if ok, 0 to drop message
40
+ */
41
+
42
+
43
+#endif