Browse code

uid_domain: convert to memory logging helper

Henning Westerholt authored on 13/02/2020 21:37:46
Showing 1 changed files
... ...
@@ -245,7 +245,7 @@ static int allocate_tables(void)
245 245
 	domains_2 = (domain_t**)shm_malloc(sizeof(domain_t*));
246 246
 
247 247
 	if (!hash_1 || !hash_2 || !active_hash || !domains_1 || !domains_2) {
248
-		ERR("No memory left\n");
248
+		SHM_MEM_ERROR;
249 249
 		return -1;
250 250
 	}
251 251
 	memset(hash_1, 0, sizeof(struct hash_entry*) * HASH_SIZE);
... ...
@@ -444,7 +444,7 @@ static int lookup_domain(struct sip_msg* msg, char* flags, char* fp)
444 444
 
445 445
 	tmp.s = pkg_malloc(domain.len);
446 446
 	if (!tmp.s) {
447
-		ERR("No memory left\n");
447
+		PKG_MEM_ERROR;
448 448
 		return -1;
449 449
 	}
450 450
 	memcpy(tmp.s, domain.s, domain.len);
... ...
@@ -480,7 +480,7 @@ static int get_did(str* did, str* domain)
480 480
 
481 481
 	tmp.s = pkg_malloc(domain->len);
482 482
 	if (!tmp.s) {
483
-		ERR("No memory left\n");
483
+		PKG_MEM_ERROR;
484 484
 		return -1;
485 485
 	}
486 486
 	memcpy(tmp.s, domain->s, domain->len);
Browse code

uid_domain: updated to the new mod interface

Daniel-Constantin Mierla authored on 28/09/2018 08:09:35 • Victor Seva committed on 28/09/2018 11:03:26
Showing 1 changed files
... ...
@@ -120,13 +120,13 @@ static domain_t dom_buf[2];
120 120
  * Exported functions
121 121
  */
122 122
 static cmd_export_t cmds[] = {
123
-	{"is_local",      is_local,              1, fixup_var_str_1,
123
+	{"is_local",      is_local,              1, fixup_var_str_1, 0,
124 124
 	 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
125
-	{"lookup_domain", lookup_domain,         2, lookup_domain_fixup,
125
+	{"lookup_domain", lookup_domain,         2, lookup_domain_fixup, 0,
126 126
 	 REQUEST_ROUTE|FAILURE_ROUTE },
127
-	{"get_did",       (cmd_function)get_did, 0, 0, 0},
128
-	{"bind_domain",   (cmd_function)bind_domain, 0, 0, 0},
129
-	{0, 0, 0, 0, 0}
127
+	{"get_did",       (cmd_function)get_did, 0, 0, 0, 0},
128
+	{"bind_domain",   (cmd_function)bind_domain, 0, 0, 0, 0},
129
+	{0, 0, 0, 0, 0, 0}
130 130
 };
131 131
 
132 132
 
... ...
@@ -155,15 +155,16 @@ static param_export_t params[] = {
155 155
  * Module interface
156 156
  */
157 157
 struct module_exports exports = {
158
-	"uid_domain",
159
-	cmds,       /* Exported functions */
160
-	domain_rpc, /* RPC methods */
161
-	params,     /* Exported parameters */
162
-	mod_init,   /* module initialization function */
163
-	0,          /* response function*/
164
-	destroy,    /* destroy function */
165
-	0,          /* cancel function */
166
-	child_init  /* per-child init function */
158
+	"uid_domain", /* module name */
159
+	DEFAULT_DLFLAGS, /* dlopen flags */
160
+	cmds,         /* exported functions */
161
+	params,       /* exported parameters */
162
+	domain_rpc,   /* exported RPC methods */
163
+	0,            /* exported pseudo-variables */
164
+	0,            /* response handling function */
165
+	mod_init,     /* module init function */
166
+	child_init,   /* per-child init function */
167
+	destroy       /* module destroy function */
167 168
 };
168 169
 
169 170
 
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -31,13 +31,13 @@
31 31
 
32 32
 #include "uid_domain_mod.h"
33 33
 #include <stdio.h>
34
-#include "../../mem/shm_mem.h"
35
-#include "../../mem/mem.h"
36
-#include "../../sr_module.h"
37
-#include "../../ut.h"
38
-#include "../../parser/parse_from.h"
39
-#include "../../parser/parse_uri.h"
40
-#include "../../usr_avp.h"
34
+#include "../../core/mem/shm_mem.h"
35
+#include "../../core/mem/mem.h"
36
+#include "../../core/sr_module.h"
37
+#include "../../core/ut.h"
38
+#include "../../core/parser/parse_from.h"
39
+#include "../../core/parser/parse_uri.h"
40
+#include "../../core/usr_avp.h"
41 41
 #include "domain_api.h"
42 42
 #include "domain_rpc.h"
43 43
 #include "hash.h"
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,567 @@
1
+/*
2
+ * Domain module
3
+ *
4
+ * Copyright (C) 2002-2003 Juha Heinanen
5
+ *
6
+ * This file is part of sip-router, a free SIP server.
7
+ *
8
+ * sip-router is free software; you can redistribute it and/or modify it under
9
+ * the terms of the GNU General Public License as published by the Free
10
+ * Software Foundation; either version 2 of the License, or (at your option)
11
+ * any later version
12
+ *
13
+ * sip-router is distributed in the hope that it will be useful, but WITHOUT
14
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16
+ * more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License along
19
+ * with this program; if not, write to the Free Software Foundation, Inc.,
20
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ *
22
+ * History:
23
+ * -------
24
+ * 2003-03-11: New module interface (janakj)
25
+ * 2003-03-16: flags export parameter added (janakj)
26
+ * 2003-04-05: default_uri #define used (jiri)
27
+ * 2003-04-06: db connection closed in mod_init (janakj)
28
+ * 2004-06-06  updated to the new DB api, cleanup: static dbf & handler,
29
+ *              calls to domain_db_{bind,init,close,ver} (andrei)
30
+ */
31
+
32
+#include "uid_domain_mod.h"
33
+#include <stdio.h>
34
+#include "../../mem/shm_mem.h"
35
+#include "../../mem/mem.h"
36
+#include "../../sr_module.h"
37
+#include "../../ut.h"
38
+#include "../../parser/parse_from.h"
39
+#include "../../parser/parse_uri.h"
40
+#include "../../usr_avp.h"
41
+#include "domain_api.h"
42
+#include "domain_rpc.h"
43
+#include "hash.h"
44
+#include "domain.h"
45
+
46
+
47
+/*
48
+ * Module management function prototypes
49
+ */
50
+static int mod_init(void);
51
+static void destroy(void);
52
+static int child_init(int rank);
53
+
54
+static int is_local(struct sip_msg* msg, char* s1, char* s2);
55
+static int lookup_domain(struct sip_msg* msg, char* s1, char* s2);
56
+static int get_did(str* did, str* domain);
57
+
58
+static int lookup_domain_fixup(void** param, int param_no);
59
+
60
+MODULE_VERSION
61
+
62
+/*
63
+ * Version of domain table required by the module, increment this value if you
64
+ * change the table in an backwards incompatible way
65
+ */
66
+#define DOMAIN_TABLE_VERSION 2
67
+#define DOMATTR_TABLE_VERSION 1
68
+
69
+#define DOMAIN_TABLE  "uid_domain"
70
+#define DOMAIN_COL    "domain"
71
+#define DID_COL       "did"
72
+#define FLAGS_COL     "flags"
73
+
74
+#define DOMATTR_TABLE "uid_domain_attrs"
75
+#define DOMATTR_DID   "did"
76
+#define DOMATTR_NAME  "name"
77
+#define DOMATTR_TYPE  "type"
78
+#define DOMATTR_VALUE "value"
79
+#define DOMATTR_FLAGS "flags"
80
+#define DOMAIN_COL    "domain"
81
+
82
+int db_mode = 1;  /* Enable/disable domain cache */
83
+
84
+/*
85
+ * Module parameter variables
86
+ */
87
+static str db_url = STR_STATIC_INIT(DEFAULT_RODB_URL);
88
+
89
+str domain_table = STR_STATIC_INIT(DOMAIN_TABLE); /* Name of domain table */
90
+str domain_col   = STR_STATIC_INIT(DOMAIN_COL);   /* Name of domain column */
91
+str did_col      = STR_STATIC_INIT(DID_COL);      /* Domain id */
92
+str flags_col    = STR_STATIC_INIT(FLAGS_COL);    /* Domain flags */
93
+
94
+str domattr_table = STR_STATIC_INIT(DOMATTR_TABLE);
95
+str domattr_did   = STR_STATIC_INIT(DOMATTR_DID);
96
+str domattr_name  = STR_STATIC_INIT(DOMATTR_NAME);
97
+str domattr_type  = STR_STATIC_INIT(DOMATTR_TYPE);
98
+str domattr_value = STR_STATIC_INIT(DOMATTR_VALUE);
99
+str domattr_flags = STR_STATIC_INIT(DOMATTR_FLAGS);
100
+
101
+int load_domain_attrs = 0;  /* Load attributes for each domain by default */
102
+
103
+static db_ctx_t* db = NULL;
104
+db_cmd_t* load_domains_cmd = NULL, *get_did_cmd = NULL, *load_attrs_cmd = NULL;
105
+
106
+struct hash_entry*** active_hash = 0; /* Pointer to current hash table */
107
+struct hash_entry** hash_1 = 0;       /* Pointer to hash table 1 */
108
+struct hash_entry** hash_2 = 0;       /* Pointer to hash table 2 */
109
+
110
+domain_t** domains_1 = 0;    /* List of domains 1 */
111
+domain_t** domains_2 = 0;    /* List of domains 2 */
112
+
113
+/* Global domain structure, this one is used to store data retrieved from
114
+ * database when memory cache is disabled. There is one buffer for from and
115
+ * one buffer for to track.
116
+ */
117
+static domain_t dom_buf[2];
118
+
119
+/*
120
+ * Exported functions
121
+ */
122
+static cmd_export_t cmds[] = {
123
+	{"is_local",      is_local,              1, fixup_var_str_1,
124
+	 REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
125
+	{"lookup_domain", lookup_domain,         2, lookup_domain_fixup,
126
+	 REQUEST_ROUTE|FAILURE_ROUTE },
127
+	{"get_did",       (cmd_function)get_did, 0, 0, 0},
128
+	{"bind_domain",   (cmd_function)bind_domain, 0, 0, 0},
129
+	{0, 0, 0, 0, 0}
130
+};
131
+
132
+
133
+/*
134
+ * Exported parameters
135
+ */
136
+static param_export_t params[] = {
137
+	{"db_url",	          PARAM_STR, &db_url           },
138
+	{"db_mode",           PARAM_INT, &db_mode          },
139
+	{"domain_table",      PARAM_STR, &domain_table     },
140
+	{"domain_col",        PARAM_STR, &domain_col       },
141
+	{"did_col",           PARAM_STR, &did_col          },
142
+	{"flags_col",         PARAM_STR, &flags_col        },
143
+	{"domattr_table",     PARAM_STR, &domattr_table    },
144
+	{"domattr_did",       PARAM_STR, &domattr_did      },
145
+	{"domattr_name",      PARAM_STR, &domattr_name     },
146
+	{"domattr_type",      PARAM_STR, &domattr_type     },
147
+	{"domattr_value",     PARAM_STR, &domattr_value    },
148
+	{"domattr_flags",     PARAM_STR, &domattr_flags    },
149
+	{"load_domain_attrs", PARAM_INT, &load_domain_attrs},
150
+	{0, 0, 0}
151
+};
152
+
153
+
154
+/*
155
+ * Module interface
156
+ */
157
+struct module_exports exports = {
158
+	"uid_domain",
159
+	cmds,       /* Exported functions */
160
+	domain_rpc, /* RPC methods */
161
+	params,     /* Exported parameters */
162
+	mod_init,   /* module initialization function */
163
+	0,          /* response function*/
164
+	destroy,    /* destroy function */
165
+	0,          /* cancel function */
166
+	child_init  /* per-child init function */
167
+};
168
+
169
+
170
+static int init_db(void)
171
+{
172
+	db_fld_t load_domains_columns[] = {
173
+		{.name = did_col.s,    DB_STR},
174
+		{.name = domain_col.s, DB_STR},
175
+		{.name = flags_col.s,  DB_BITMAP},
176
+		{.name = NULL}
177
+	};
178
+	db_fld_t get_did_columns[] = {
179
+		{.name = did_col.s, DB_STR},
180
+		{.name = NULL}
181
+	};
182
+	db_fld_t load_attrs_columns[] = {
183
+		{.name = domattr_name.s, .type = DB_STR},
184
+		{.name = domattr_type.s, .type = DB_INT},
185
+		{.name = domattr_value.s, .type = DB_STR},
186
+		{.name = domattr_flags.s, .type = DB_BITMAP},
187
+		{.name = NULL}
188
+	};
189
+	db_fld_t get_did_match[] = {
190
+		{.name = domain_col.s, DB_STR},
191
+		{.name = NULL}
192
+	};
193
+	db_fld_t load_attrs_match[] = {
194
+		{.name = domattr_did.s, .type = DB_STR},
195
+		{.name = NULL}
196
+	};
197
+
198
+	db = db_ctx("domain");
199
+	if (db == NULL) {
200
+		ERR("Error while initializing database layer\n");
201
+		return -1;
202
+	}
203
+	if (db_add_db(db, db_url.s) < 0) return -1;
204
+	if (db_connect(db) < 0) return -1;
205
+
206
+	DBG("prepare load_domains_cmd\n");
207
+	load_domains_cmd = db_cmd(DB_GET, db, domain_table.s, load_domains_columns,
208
+							  NULL, NULL);
209
+	if (load_domains_cmd == NULL) {
210
+		ERR("Error while preparing load_domains database command\n");
211
+		return -1;
212
+	}
213
+
214
+	DBG("prepare get_did_cmd\n");
215
+	get_did_cmd = db_cmd(DB_GET, db, domain_table.s, get_did_columns,
216
+						 get_did_match, NULL);
217
+	if (get_did_cmd == NULL) {
218
+		ERR("Error while preparing get_did database command\n");
219
+		return -1;
220
+	}
221
+
222
+	if (load_domain_attrs) {
223
+		DBG("prepare load_attrs_cmd\n");
224
+		load_attrs_cmd = db_cmd(DB_GET, db, domattr_table.s,
225
+								load_attrs_columns, load_attrs_match, NULL);
226
+		if (load_attrs_cmd == NULL) {
227
+			ERR("Error while preparing load_attrs database command\n");
228
+			return -1;
229
+		}
230
+	}
231
+
232
+	return 0;
233
+}
234
+
235
+
236
+static int allocate_tables(void)
237
+{
238
+	active_hash = (struct hash_entry***)shm_malloc(sizeof(struct hash_entry**));
239
+	hash_1 = (struct hash_entry**)shm_malloc(sizeof(struct hash_entry*)
240
+											 * HASH_SIZE);
241
+	hash_2 = (struct hash_entry**)shm_malloc(sizeof(struct hash_entry*)
242
+											 * HASH_SIZE);
243
+	domains_1 = (domain_t**)shm_malloc(sizeof(domain_t*));
244
+	domains_2 = (domain_t**)shm_malloc(sizeof(domain_t*));
245
+
246
+	if (!hash_1 || !hash_2 || !active_hash || !domains_1 || !domains_2) {
247
+		ERR("No memory left\n");
248
+		return -1;
249
+	}
250
+	memset(hash_1, 0, sizeof(struct hash_entry*) * HASH_SIZE);
251
+	memset(hash_2, 0, sizeof(struct hash_entry*) * HASH_SIZE);
252
+	*active_hash = hash_1;
253
+	*domains_1 = 0;
254
+	*domains_2 = 0;
255
+	return 0;
256
+}
257
+
258
+static void destroy_tables(void)
259
+{
260
+	free_table(hash_1);
261
+	free_table(hash_2);
262
+	if (active_hash) shm_free(active_hash);
263
+
264
+	if (domains_1) {
265
+		free_domain_list(*domains_1);
266
+		shm_free(domains_1);
267
+	}
268
+
269
+	if (domains_2) {
270
+		free_domain_list(*domains_2);
271
+		shm_free(domains_2);
272
+	}
273
+}
274
+
275
+
276
+static int mod_init(void)
277
+{
278
+	/* Check if cache needs to be loaded from domain table */
279
+	if (db_mode) {
280
+		if (init_db() < 0) goto error;
281
+
282
+		if (allocate_tables() < 0) goto error;
283
+		if (reload_domain_list() < 0) goto error;
284
+
285
+		db_cmd_free(load_domains_cmd);
286
+		load_domains_cmd = NULL;
287
+
288
+		db_cmd_free(load_attrs_cmd);
289
+		load_attrs_cmd = NULL;
290
+
291
+		db_cmd_free(get_did_cmd);
292
+		get_did_cmd = NULL;
293
+
294
+		if (db) db_disconnect(db);
295
+		db_ctx_free(db);
296
+		db = NULL;
297
+	}
298
+
299
+	return 0;
300
+
301
+ error:
302
+	if (get_did_cmd) {
303
+		db_cmd_free(get_did_cmd);
304
+		get_did_cmd = NULL;
305
+	}
306
+	if (load_domains_cmd) {
307
+		db_cmd_free(load_domains_cmd);
308
+		load_domains_cmd = NULL;
309
+	}
310
+	if (load_attrs_cmd) {
311
+		db_cmd_free(load_attrs_cmd);
312
+		load_attrs_cmd = NULL;
313
+	}
314
+	if (db) db_disconnect(db);
315
+	db_ctx_free(db);
316
+	db = NULL;
317
+	return -1;
318
+}
319
+
320
+
321
+static int child_init(int rank)
322
+{
323
+	/* Check if database is needed by child */
324
+	if (rank > 0 || rank == PROC_RPC || rank == PROC_UNIXSOCK) {
325
+		if (init_db() < 0) return -1;
326
+	}
327
+
328
+	return 0;
329
+}
330
+
331
+
332
+static void free_old_domain(domain_t* d)
333
+{
334
+	int i;
335
+
336
+	if (!d) return;
337
+	if (d->did.s) {
338
+		pkg_free(d->did.s);
339
+		d->did.s = NULL;
340
+	}
341
+
342
+	if (d->domain) {
343
+		for(i = 0; i < d->n; i++) {
344
+			if (d->domain[i].s) pkg_free(d->domain[i].s);
345
+		}
346
+		pkg_free(d->domain);
347
+		d->domain = NULL;
348
+	}
349
+
350
+	if (d->flags) {
351
+		pkg_free(d->flags);
352
+		d->flags = NULL;
353
+	}
354
+
355
+	if (d->attrs) {
356
+		destroy_avp_list(&d->attrs);
357
+	}
358
+}
359
+
360
+
361
+static void destroy(void)
362
+{
363
+	/* Destroy is called from the main process only, there is no need to close
364
+	 * database here because it is closed in mod_init already
365
+	 */
366
+	if (!db_mode) {
367
+		free_old_domain(&dom_buf[0]);
368
+		free_old_domain(&dom_buf[1]);
369
+	}
370
+
371
+	if (load_domains_cmd) db_cmd_free(load_domains_cmd);
372
+	if (get_did_cmd) db_cmd_free(get_did_cmd);
373
+	if (load_attrs_cmd) db_cmd_free(load_attrs_cmd);
374
+
375
+	if (db) {
376
+		db_disconnect(db);
377
+		db_ctx_free(db);
378
+	}
379
+
380
+	destroy_tables();
381
+}
382
+
383
+
384
+
385
+/*
386
+ * Check if domain is local
387
+ */
388
+static int is_local(struct sip_msg* msg, char* fp, char* s2)
389
+{
390
+	str domain;
391
+
392
+	if (get_str_fparam(&domain, msg, (fparam_t*)fp) != 0) {
393
+		ERR("Unable to get domain to check\n");
394
+		return -1;
395
+	}
396
+
397
+	return is_domain_local(&domain);
398
+}
399
+
400
+
401
+static int db_load_domain(domain_t** d, unsigned long flags, str* domain)
402
+{
403
+	int ret;
404
+	int_str name, val;
405
+	domain_t* p;
406
+	str name_s = STR_STATIC_INIT(AVP_DID);
407
+
408
+	if (flags & AVP_TRACK_FROM) {
409
+		p = &dom_buf[0];
410
+	} else {
411
+		p = &dom_buf[1];
412
+	}
413
+
414
+	free_old_domain(p);
415
+
416
+	ret = db_get_did(&p->did, domain);
417
+	if (ret != 1) return ret;
418
+	if (load_domain_attrs) {
419
+		if (db_load_domain_attrs(p) < 0) return -1;
420
+	}
421
+
422
+	/* Create an attribute containing did of the domain */
423
+	name.s = name_s;
424
+	val.s = p->did;
425
+	if (add_avp_list(&p->attrs, AVP_CLASS_DOMAIN | AVP_NAME_STR | AVP_VAL_STR,
426
+					 name, val) < 0) return -1;
427
+
428
+	*d = p;
429
+	return 0;
430
+}
431
+
432
+
433
+static int lookup_domain(struct sip_msg* msg, char* flags, char* fp)
434
+{
435
+	str domain, tmp;
436
+	domain_t* d = NULL;
437
+	int ret = -1;
438
+
439
+	if (get_str_fparam(&domain, msg, (fparam_t*)fp) != 0) {
440
+		DBG("lookup_domain: Cannot get the domain name to lookup\n");
441
+		return -1;
442
+	}
443
+
444
+	tmp.s = pkg_malloc(domain.len);
445
+	if (!tmp.s) {
446
+		ERR("No memory left\n");
447
+		return -1;
448
+	}
449
+	memcpy(tmp.s, domain.s, domain.len);
450
+	tmp.len = domain.len;
451
+	strlower(&tmp);
452
+
453
+	if (db_mode) {
454
+		if (hash_lookup(&d, *active_hash, &tmp) == 1) {
455
+			set_avp_list((unsigned long)flags, &d->attrs);
456
+			ret = 1;
457
+		}
458
+	} else {
459
+		if (db_load_domain(&d, (unsigned long)flags, &tmp) == 0) {
460
+			set_avp_list((unsigned long)flags, &d->attrs);
461
+			ret = 1;
462
+		}
463
+	}
464
+
465
+	pkg_free(tmp.s);
466
+	return ret;
467
+}
468
+
469
+
470
+static int get_did(str* did, str* domain)
471
+{
472
+	str tmp;
473
+	domain_t* d;
474
+
475
+	if (!db_mode) {
476
+		ERR("lookup_domain only works in cache mode\n");
477
+		return -1;
478
+	}
479
+
480
+	tmp.s = pkg_malloc(domain->len);
481
+	if (!tmp.s) {
482
+		ERR("No memory left\n");
483
+		return -1;
484
+	}
485
+	memcpy(tmp.s, domain->s, domain->len);
486
+	tmp.len = domain->len;
487
+	strlower(&tmp);
488
+
489
+	if (hash_lookup(&d, *active_hash, &tmp) == 1) {
490
+		*did = d->did;
491
+		pkg_free(tmp.s);
492
+		return 1;
493
+	} else {
494
+		pkg_free(tmp.s);
495
+		return -1;
496
+	}
497
+}
498
+
499
+
500
+int reload_domain_list(void)
501
+{
502
+	struct hash_entry** new_table;
503
+	domain_t** new_list;
504
+
505
+	/* Choose new hash table and free its old contents */
506
+	if (*active_hash == hash_1) {
507
+		free_table(hash_2);
508
+		new_table = hash_2;
509
+		new_list = domains_2;
510
+	} else {
511
+		free_table(hash_1);
512
+		new_table = hash_1;
513
+		new_list = domains_1;
514
+	}
515
+
516
+	if (load_domains(new_list) < 0) goto error;
517
+	if (gen_domain_table(new_table, *new_list) < 0) goto error;
518
+	*active_hash = new_table;
519
+	return 0;
520
+
521
+ error:
522
+	free_table(new_table);
523
+	free_domain_list(*new_list);
524
+	return -1;
525
+}
526
+
527
+
528
+static int lookup_domain_fixup(void** param, int param_no)
529
+{
530
+	unsigned long flags=0;
531
+	char* s;
532
+
533
+	if (param_no == 1) {
534
+		/* Determine the track and class of attributes to be loaded */
535
+		s = (char*)*param;
536
+		if (*s != '$' || (strlen(s) != 3)) {
537
+			ERR("Invalid parameter value, $xy expected\n");
538
+			return -1;
539
+		}
540
+		switch((s[1] << 8) + s[2]) {
541
+		case 0x4644: /* $fd */
542
+		case 0x6664:
543
+		case 0x4664:
544
+		case 0x6644:
545
+			flags = AVP_TRACK_FROM | AVP_CLASS_DOMAIN;
546
+			break;
547
+
548
+		case 0x5444: /* $td */
549
+		case 0x7464:
550
+		case 0x5464:
551
+		case 0x7444:
552
+			flags = AVP_TRACK_TO | AVP_CLASS_DOMAIN;
553
+			break;
554
+
555
+		default:
556
+			ERR("Invalid parameter value: '%s'\n", s);
557
+			return -1;
558
+		}
559
+
560
+		pkg_free(*param);
561
+		*param = (void*)flags;
562
+	} else if (param_no == 2) {
563
+		return fixup_var_str_12(param, 2);
564
+	}
565
+
566
+	return 0;
567
+}