Browse code

Merge branch 'andrei/mod_register' of ssh://git.sip-router.org/sip-router into daniel

* 'andrei/mod_register' of ssh://git.sip-router.org/sip-router:
minor macro additions for kamailio compatibility
modules: support for mod_register

Daniel-Constantin Mierla authored on 20/11/2008 20:05:38
Showing 4 changed files
... ...
@@ -87,6 +87,7 @@ int log_facility_fixup(void *handle, str *name, void **val);
87 87
 #define LOC_INFO	__FILE__ ":" CT2STR(__LINE__) ": "
88 88
 
89 89
 
90
+#define is_printable(level) (cfg_get(core, core_cfg, debug)>=(level))
90 91
 
91 92
 #ifdef NO_DEBUG
92 93
 	#ifdef __SUNPRO_C
... ...
@@ -216,17 +216,29 @@ static inline int version_control(void *handle, char *path)
216 216
 	return 0;
217 217
 }
218 218
 
219
-/* returns 0 on success , <0 on error */
219
+/** load a sr module.
220
+ * tries to load the module specified by path.
221
+ * If modname does contain a '/' or a '.' it would be assumed to contain a 
222
+ * path to the module and it will be used as give.
223
+ * else <MODS_DIR>/<modname>.so will be tried and if this fails
224
+ *  <MODS_DIR>/<modname>/<modname>.so
225
+ * @param modname - path or module name
226
+ * @return 0 on success , <0 on error
227
+ */
220 228
 int load_module(char* path)
221 229
 {
222 230
 	void* handle;
223 231
 	char* error;
232
+	mod_register_function mr;
224 233
 	union module_exports_u* exp;
225 234
 	unsigned* mod_if_ver;
226 235
 	struct sr_module* t;
227 236
 	struct stat stat_buf;
228 237
 	char* modname;
229 238
 	int len;
239
+	int dlflags;
240
+	int new_dlflags;
241
+	int retries;
230 242
 
231 243
 #ifndef RTLD_NOW
232 244
 /* for openbsd */
... ...
@@ -287,7 +299,9 @@ int load_module(char* path)
287 287
 		}
288 288
 #endif /* !EXTRA_DEBUG */
289 289
 	}
290
-
290
+	retries=2;
291
+	dlflags=RTLD_NOW;
292
+reload:
291 293
 	handle=dlopen(path, RTLD_NOW); /* resolve all symbols now */
292 294
 	if (handle==0){
293 295
 		LOG(L_ERR, "ERROR: load_module: could not open module <%s>: %s\n",
... ...
@@ -314,11 +328,47 @@ int load_module(char* path)
314 314
 		goto error1;
315 315
 	}
316 316
 	/* launch register */
317
+	mr = (mod_register_function)dlsym(handle, DLSYM_PREFIX "mod_register");
318
+	if (((error =(char*)dlerror())==0) && mr) {
319
+		/* no error call it */
320
+		new_dlflags=dlflags;
321
+		if (mr(path, &dlflags, 0, 0)!=0) {
322
+			LOG(L_ERR, "ERROR: load_module: %s: mod_register failed\n", path);
323
+			goto error1;
324
+		}
325
+		if (new_dlflags!=dlflags && new_dlflags!=0) {
326
+			/* we have to reload the module */
327
+			dlclose(handle);
328
+			dlflags=new_dlflags;
329
+			retries--;
330
+			if (retries>0) goto reload;
331
+			LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
332
+					" on the dlflags\n", path);
333
+			goto error;
334
+		}
335
+	}
317 336
 	exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
318 337
 	if ( (error =(char*)dlerror())!=0 ){
319 338
 		LOG(L_ERR, "ERROR: load_module: %s\n", error);
320 339
 		goto error1;
321 340
 	}
341
+	/* hack to allow for kamailio style dlflags inside exports */
342
+	if (*mod_if_ver == 1) {
343
+		new_dlflags = exp->v1.dlflags;
344
+		if (new_dlflags!=dlflags && new_dlflags!=DEFAULT_DLFLAGS) {
345
+			/* we have to reload the module */
346
+			dlclose(handle);
347
+			WARN("%s: exports dlflags interface is deprecated and it will not"
348
+					"be supported in newer versions; consider using"
349
+					" mod_register() instead", path);
350
+			dlflags=new_dlflags;
351
+			retries--;
352
+			if (retries>0) goto reload;
353
+			LOG(L_ERR, "ERROR: load_module: %s: cannot agree"
354
+					" on the dlflags\n", path);
355
+			goto error;
356
+		}
357
+	}
322 358
 	if (register_module(*mod_if_ver, exp, path, handle)<0) goto error1;
323 359
 	return 0;
324 360
 
... ...
@@ -89,6 +89,20 @@
89 89
 
90 90
 #endif
91 91
 
92
+/** type used for the mod_register function export.
93
+ *  mod_register is a function called when loading a module
94
+ *  (if present), prior to registering the module exports.
95
+ *  @param path - path to the module, including file name
96
+ *  @param dlflags - pointer to the dlflags used when loading the module.
97
+ *                   If the value is changed to a different and non-zero
98
+ *                   value, the module will be reloaded with the new flags.
99
+ *  @param reserved1 - reserved for future use.
100
+ *  @param reserved2 - reserver for future use
101
+ *  @return 0 on success, -1 on error, all the other values are reserved
102
+ *                      for future use (<0 meaning error and >0 success)
103
+ */
104
+typedef  int (*mod_register_function)(char*, int*, void*, void*);
105
+
92 106
 typedef  struct module_exports* (*module_register)(void);
93 107
 typedef  int (*cmd_function)(struct sip_msg*, char*, char*);
94 108
 typedef  int (*cmd_function3)(struct sip_msg*, char*, char*, char*);
... ...
@@ -138,6 +152,7 @@ typedef int (*param_func_t)( modparam_t type, void* val);
138 138
 #define BRANCH_ROUTE  8  /* Function can be used in branch_route blocks */
139 139
 #define ONSEND_ROUTE 16  /* Function can be used in onsend_route blocks */
140 140
 #define ERROR_ROUTE  32  /* Function can be used in an error route */ 
141
+#define LOCAL_ROUTE  64  /* Function can be used in a local route */
141 142
 
142 143
 /* Macros - used as rank in child_init function */
143 144
 #define PROC_MAIN      0  /* Main ser process */
... ...
@@ -61,9 +61,10 @@ typedef struct stat_export_ {
61 61
 
62 62
 #define get_stat(name)  0
63 63
 #define get_stat_val(v) 0
64
+#define get_stat_var_from_num_code(num_code, in_code) 0
64 65
 #define update_stat(v, n)
65 66
 #define reset_stat(v)
66
-#define if_update_stat (cond, v, n)
67
+#define if_update_stat(cond, v, n)
67 68
 
68 69
 #ifdef STATISTICS
69 70
 #warning "sorry sip-router does not support STATISTICS"