Browse code

*** empty log message ***

Jan Janak authored on 27/08/2002 09:47:03
Showing 19 changed files
... ...
@@ -13,7 +13,7 @@
13 13
 /*
14 14
  * Find a character occurence that is not quoted
15 15
  */
16
-char* find_not_quoted(str* _s, char _c)
16
+char* ul_fnq(str* _s, char _c)
17 17
 {
18 18
 	int quoted = 0, i;
19 19
 	
... ...
@@ -32,23 +32,16 @@ char* find_not_quoted(str* _s, char _c)
32 32
 /*
33 33
  * Extract username part from URI
34 34
  */
35
-int get_user(str* _s)
35
+int ul_get_user(str* _s)
36 36
 {
37 37
 	char* at, *dcolon, *dc;
38
-	dcolon = find_not_quoted(_s, ':');
38
+	dcolon = ul_fnq(_s, ':');
39 39
 
40
-	LOG(L_ERR, "get_user(): %.*s\n", _s->len, _s->s);
41
-	if (dcolon == 0) {
42
-		LOG(L_ERR, "No : found\n");
43
-		abort();
44
-		return -1;
45
-	}
40
+	if (dcolon == 0) return -1;
46 41
 
47 42
 	_s->s = dcolon + 1;
48 43
 	_s->len -= dcolon - _s->s + 1;
49 44
 	
50
-	LOG(L_ERR, "get_user2(): %.*s\n", _s->len, _s->s);
51
-
52 45
 	at = q_memchr(_s->s, '@', _s->len);
53 46
 	dc = q_memchr(_s->s, ':', _s->len);
54 47
 	if (at) {
... ...
@@ -13,13 +13,13 @@
13 13
 /*
14 14
  * Find a character occurence that is not quoted
15 15
  */
16
-char* find_not_quoted(str* _s, char _c);
16
+char* ul_fnq(str* _s, char _c);
17 17
 
18 18
 
19 19
 /*
20 20
  * Extract username part from URI
21 21
  */
22
-int get_user(str* _s);
22
+int ul_get_user(str* _s);
23 23
 
24 24
 
25 25
 /*
... ...
@@ -53,7 +53,6 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
53 53
 {
54 54
 	urecord_t* r;
55 55
 	str user;
56
-	time_t t;
57 56
 	ucontact_t* ptr;
58 57
 	int res;
59 58
 	
... ...
@@ -70,21 +69,24 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
70 69
 	if (_m->new_uri.s) str_copy(&user, &_m->new_uri);
71 70
 	else str_copy(&user, &_m->first_line.u.request.uri);
72 71
 	
73
-	if ((get_user(&user) < 0) || !user.len) {
72
+	if ((ul_get_user(&user) < 0) || !user.len) {
74 73
 		LOG(L_ERR, "lookup(): Error while extracting username\n");
75 74
 		return -3;
76 75
 	}
77 76
 	
78 77
 	get_act_time();
79 78
 
80
-	res = ul_get_record((udomain_t*)_t, &user, &r);
79
+	ul_lock_udomain((udomain_t*)_t);
80
+	res = ul_get_urecord((udomain_t*)_t, &user, &r);
81 81
 	if (res < 0) {
82 82
 		LOG(L_ERR, "lookup(): Error while querying usrloc\n");
83
+		ul_unlock_udomain((udomain_t*)_t);
83 84
 		return -4;
84 85
 	}
85 86
 	
86 87
 	if (res > 0) {
87 88
 		DBG("lookup(): \'%.*s\' Not found in usrloc\n", user.len, user.s);
89
+		ul_unlock_udomain((udomain_t*)_t);
88 90
 		return -5;
89 91
 	}
90 92
 
... ...
@@ -93,7 +95,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
93 95
 	
94 96
 	if (ptr && (rwrite(_m, &ptr->c) < 0)) {
95 97
 		LOG(L_ERR, "lookup(): Unable to rewrite Request-URI\n");
96
-		ul_release_record(r);
98
+		ul_unlock_udomain((udomain_t*)_t);
97 99
 		return -6;
98 100
 	}
99 101
 	
... ...
@@ -105,7 +107,7 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
105 107
 		if (ptr->expires > act_time) {
106 108
 			if (append_branch(_m, ptr->c.s, ptr->c.len) == -1) {
107 109
 				LOG(L_ERR, "lookup(): Error while appending a branch\n");
108
-				ul_release_record(r);
110
+				ul_unlock_udomain((udomain_t*)_t);
109 111
 				return -7;
110 112
 			}
111 113
 		} 
... ...
@@ -113,6 +115,6 @@ int lookup(struct sip_msg* _m, char* _t, char* _s)
113 115
 	}
114 116
 	
115 117
  skip:
116
-	ul_release_record(r);
118
+	ul_unlock_udomain((udomain_t*)_t);
117 119
 	return 1;
118 120
 }
... ...
@@ -5,6 +5,7 @@
5 5
  */
6 6
 
7 7
 #include "reg_mod.h"
8
+#include <stdio.h>
8 9
 #include "../../sr_module.h"
9 10
 #include "../../timer.h"
10 11
 #include "../../dprint.h"
... ...
@@ -113,7 +114,7 @@ static int domain_fixup(void** param, int param_no)
113 114
 	udomain_t* d;
114 115
 
115 116
 	if (param_no == 1) {
116
-		if (ul_register_domain((char*)*param, &d) < 0) {
117
+		if (ul_register_udomain((char*)*param, &d) < 0) {
117 118
 			LOG(L_ERR, "domain_fixup(): Error while registering domain\n");
118 119
 			return E_UNSPEC;
119 120
 		}
... ...
@@ -5,6 +5,7 @@
5 5
  */
6 6
 
7 7
 #include "reply.h"
8
+#include <stdio.h>
8 9
 #include "../../parser/msg_parser.h"
9 10
 #include "../../data_lump_rpl.h"
10 11
 #include "rerrno.h"
... ...
@@ -28,8 +29,6 @@ static int l;
28 29
  */
29 30
 void build_contact(ucontact_t* _c)
30 31
 {
31
-	struct lump_rpl* ptr;
32
-	
33 32
 	l = 0;
34 33
 	while(_c) {
35 34
 		if (_c->expires > act_time) {
... ...
@@ -15,6 +15,8 @@
15 15
 #include "rerrno.h"
16 16
 #include "reply.h"
17 17
 #include "convert.h"
18
+#include "uri.h"
19
+#include "regtime.h"
18 20
 
19 21
 
20 22
 /*
... ...
@@ -26,7 +28,8 @@ static inline int star(udomain_t* _d, str* _u)
26 28
 {
27 29
 	urecord_t* r;
28 30
 	
29
-	if (ul_delete_record(_d, _u) < 0) {
31
+	ul_lock_udomain(_d);
32
+	if (ul_delete_urecord(_d, _u) < 0) {
30 33
 		LOG(L_ERR, "star(): Error while removing record from usrloc\n");
31 34
 		
32 35
 		     /* Delete failed, try to get corresponding
... ...
@@ -34,12 +37,13 @@ static inline int star(udomain_t* _d, str* _u)
34 37
 		      * contacts
35 38
 		      */
36 39
 		rerrno = R_UL_DEL_R;
37
-		if (!ul_get_record(_d, _u, &r)) {
40
+		if (!ul_get_urecord(_d, _u, &r)) {
38 41
 			build_contact(r->contacts);
39
-			ul_release_record(r);
40 42
 		}
43
+		ul_unlock_udomain(_d);
41 44
 		return -1;
42 45
 	}
46
+	ul_unlock_udomain(_d);
43 47
 	return 0;
44 48
 }
45 49
 
... ...
@@ -55,17 +59,19 @@ static inline int no_contacts(udomain_t* _d, str* _u)
55 59
 	urecord_t* r;
56 60
 	int res;
57 61
 	
58
-	res = ul_get_record(_d, _u, &r);
62
+	ul_lock_udomain(_d);
63
+	res = ul_get_urecord(_d, _u, &r);
59 64
 	if (res < 0) {
60 65
 		rerrno = R_UL_GET_R;
61 66
 		LOG(L_ERR, "no_contacts(): Error while retrieving record from usrloc\n");
67
+		ul_unlock_udomain(_d);
62 68
 		return -1;
63 69
 	}
64 70
 	
65 71
 	if (res == 0) {  /* Contacts found */
66 72
 		build_contact(r->contacts);
67
-		ul_release_record(r);
68 73
 	}
74
+	ul_unlock_udomain(_d);
69 75
 	return 0;
70 76
 }
71 77
 
... ...
@@ -79,6 +85,7 @@ static inline int no_contacts(udomain_t* _d, str* _u)
79 85
 static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str* _u)
80 86
 {
81 87
 	urecord_t* r = 0;
88
+	ucontact_t* c;
82 89
 	int e, cseq;
83 90
 	float q;
84 91
 	str uri, callid;
... ...
@@ -92,19 +99,17 @@ static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str*
92 99
 		if (e == 0) goto skip;
93 100
 		
94 101
 	        if (r == 0) {
95
-			if (ul_new_record(_u, &r) < 0) {
102
+			if (ul_insert_urecord(_d, _u, &r) < 0) {
96 103
 				rerrno = R_UL_NEW_R;
97
-				LOG(L_ERR, "insert(): Can't create new record structure\n");
104
+				LOG(L_ERR, "insert(): Can't insert new record structure\n");
98 105
 				return -2;
99 106
 			}
100
-			     /* FIXME !!! */
101
-			r->domain = _d->name;
102 107
 		}
103 108
 		
104 109
 		     /* Calculate q value of the contact */
105 110
 		if (calc_contact_q(_c->q, &q) < 0) {
106 111
 			LOG(L_ERR, "insert(): Error while calculating q\n");
107
-			ul_free_record(r);
112
+			ul_delete_urecord(_d, _u);
108 113
 			return -3;
109 114
 		}
110 115
 
... ...
@@ -120,14 +125,14 @@ static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str*
120 125
 		if (atoi(&(((struct cseq_body*)_m->cseq->parsed)->number), &cseq) < 0) {
121 126
 			rerrno = R_INV_CSEQ;
122 127
 			LOG(L_ERR, "insert(): Error while converting cseq number\n");
123
-			ul_free_record(r);
128
+			ul_delete_urecord(_d, _u);
124 129
 			return -4;
125 130
 		}
126 131
 
127
-		if (ul_insert_contact(r, &uri, e, q, &callid, cseq) < 0) {
132
+		if (ul_insert_ucontact(r, &uri, e, q, &callid, cseq, &c) < 0) {
128 133
 			rerrno = R_UL_INS_C;
129 134
 			LOG(L_ERR, "insert(): Error while inserting contact\n");
130
-			ul_free_record(r);
135
+			ul_delete_urecord(_d, _u);
131 136
 			return -5;
132 137
 		}
133 138
 		
... ...
@@ -135,15 +140,8 @@ static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str*
135 140
 		_c = get_next_contact(_c);
136 141
 	}
137 142
 	
138
-	if (r) {
139
-		if (ul_insert_record(_d, r) < 0) {
140
-			rerrno = R_UL_INS_R;
141
-			LOG(L_ERR, "insert(): Error while inserting record\n");
142
-			ul_free_record(r);
143
-			return -6;
144
-		}
145
-
146
-		build_contact(r->contacts);
143
+	if (r && !r->contacts) {
144
+		ul_delete_urecord(_d, _u);
147 145
 	}
148 146
 
149 147
 	return 0;
... ...
@@ -163,7 +161,7 @@ static inline int insert(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str*
163 161
  */
164 162
 static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
165 163
 {
166
-	ucontact_t* c;
164
+	ucontact_t* c, *c2;
167 165
 	str uri, callid;
168 166
 	int cseq, e;
169 167
 	float q;
... ...
@@ -180,7 +178,7 @@ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
180 178
 		str_copy(&uri, &_c->uri);
181 179
 		get_raw_uri(&uri);
182 180
 		
183
-		if (ul_get_contact(_r, &uri, &c) > 0) {
181
+		if (ul_get_ucontact(_r, &uri, &c) > 0) {
184 182
 			LOG(L_ERR, "contact not found\n"); /*d*/
185 183
 			     /* Contact not found */
186 184
 			if (e != 0) {
... ...
@@ -203,7 +201,7 @@ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
203 201
 				}
204 202
 				
205 203
 				LOG(L_ERR, "inserting\n"); /*d*/
206
-				if (ul_insert_contact(_r, &uri, e, q, &callid, cseq) < 0) {
204
+				if (ul_insert_ucontact(_r, &uri, e, q, &callid, cseq, &c2) < 0) {
207 205
 					rerrno = R_UL_INS_C;
208 206
 					LOG(L_ERR, "update(): Error while inserting contact\n");
209 207
 					return -4;
... ...
@@ -213,7 +211,7 @@ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
213 211
 			LOG(L_ERR, "contact found\n"); /*d*/
214 212
 			if (e == 0) {
215 213
 				LOG(L_ERR, "deleting\n"); /*d*/
216
-				if (ul_delete_contact(_r, c) < 0) {
214
+				if (ul_delete_ucontact(_r, c) < 0) {
217 215
 					rerrno = R_UL_DEL_C;
218 216
 					LOG(L_ERR, "update(): Error while deleting contact\n");
219 217
 					return -5;
... ...
@@ -237,7 +235,7 @@ static inline int update(struct sip_msg* _m, urecord_t* _r, contact_t* _c)
237 235
 				}
238 236
 				
239 237
 				LOG(L_ERR, "updating\n"); /*d*/
240
-				if (ul_update_contact(c, e, q, &callid, cseq) < 0) {
238
+				if (ul_update_ucontact(c, e, q, &callid, cseq) < 0) {
241 239
 					rerrno = R_UL_UPD_C;
242 240
 					LOG(L_ERR, "update(): Error while updating contact\n");
243 241
 					return -8;
... ...
@@ -261,10 +259,12 @@ static inline int contacts(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str
261 259
 	urecord_t* r;
262 260
 	LOG(L_ERR, "contacts()\n"); /*d*/
263 261
 
264
-	res = ul_get_record(_d, _u, &r);
262
+	ul_lock_udomain(_d);
263
+	res = ul_get_urecord(_d, _u, &r);
265 264
 	if (res < 0) {
266 265
 		rerrno = R_UL_GET_R;
267 266
 		LOG(L_ERR, "contacts(): Error while retrieving record from usrloc\n");
267
+		ul_unlock_udomain(_d);
268 268
 		return -2;
269 269
 	}
270 270
 
... ...
@@ -272,17 +272,20 @@ static inline int contacts(struct sip_msg* _m, contact_t* _c, udomain_t* _d, str
272 272
 		if (update(_m, r, _c) < 0) {
273 273
 			LOG(L_ERR, "contacts(): Error while updating record\n");
274 274
 			build_contact(r->contacts);
275
-			ul_release_record(r);
275
+			ul_release_urecord(r);
276
+			ul_unlock_udomain(_d);
276 277
 			return -3;
277 278
 		}
278 279
 		build_contact(r->contacts);
279
-		ul_release_record(r);
280
+		ul_release_urecord(r);
280 281
 	} else {
281 282
 		if (insert(_m, _c, _d, _u) < 0) {
282 283
 			LOG(L_ERR, "contacts(): Error while inserting record\n");
284
+			ul_unlock_udomain(_d);
283 285
 			return -4;
284 286
 		}
285 287
 	}
288
+	ul_unlock_udomain(_d);
286 289
 	return 0;
287 290
 }
288 291
 
... ...
@@ -311,7 +314,7 @@ int save(struct sip_msg* _m, char* _t, char* _s)
311 314
 	str_copy(&user, &((struct to_body*)_m->to->parsed)->uri);
312 315
 
313 316
 	LOG(L_ERR, "user = \'%.*s\'\n", user.len, user.s);
314
-	if (get_user(&user) < 0) {
317
+	if (ul_get_user(&user) < 0) {
315 318
 		rerrno = R_TO_USER;
316 319
 		LOG(L_ERR, "save(): Can't extract username part from To URI, sending 400\n");
317 320
 		goto error;
... ...
@@ -332,5 +335,5 @@ int save(struct sip_msg* _m, char* _t, char* _s)
332 335
 	
333 336
  error:
334 337
 	send_reply(_m);
335
-	return -1;
338
+	return 0;
336 339
 }
... ...
@@ -24,7 +24,7 @@ void get_raw_uri(str* _s)
24 24
 	char* aq;
25 25
 	
26 26
 	if (_s->s[_s->len - 1] == '>') {
27
-		aq = find_not_quoted(_s, '<');
27
+		aq = ul_fnq(_s, '<');
28 28
 		_s->len -= aq - _s->s + 2;
29 29
 		_s->s = aq + 1;
30 30
 	}
... ...
@@ -13,38 +13,40 @@ struct usrloc_func ul_func;
13 13
 
14 14
 int bind_usrloc(void)
15 15
 {
16
-	ul_register_domain = (register_domain_t)find_export("~ul_register_domain", 1);
17
-	if (ul_register_domain == 0) return -1;
16
+	ul_register_udomain = (register_udomain_t)find_export("~ul_register_udomain", 1);
17
+	if (ul_register_udomain == 0) return -1;
18 18
 
19
-	ul_insert_record = (insert_record_t)find_export("~ul_insert_record", 1);
20
-	if (ul_insert_record == 0) return -1;
19
+	ul_insert_urecord = (insert_urecord_t)find_export("~ul_insert_urecord", 1);
20
+	if (ul_insert_urecord == 0) return -1;
21 21
 
22
-	ul_delete_record = (delete_record_t)find_export("~ul_delete_record", 1);
23
-	if (ul_delete_record == 0) return -1;
22
+	ul_delete_urecord = (delete_urecord_t)find_export("~ul_delete_urecord", 1);
23
+	if (ul_delete_urecord == 0) return -1;
24 24
 
25
-	ul_get_record = (get_record_t)find_export("~ul_get_record", 1);
26
-	if (ul_get_record == 0) return -1;
25
+	ul_get_urecord = (get_urecord_t)find_export("~ul_get_urecord", 1);
26
+	if (ul_get_urecord == 0) return -1;
27 27
 
28
-        ul_release_record = (release_record_t)find_export("~ul_release_record", 1);
29
-	if (ul_release_record == 0) return -1;
28
+	ul_lock_udomain = (lock_udomain_t)find_export("~ul_lock_udomain", 1);
29
+	if (ul_lock_udomain == 0) return -1;
30
+	
31
+	ul_unlock_udomain = (unlock_udomain_t)find_export("~ul_unlock_udomain", 1);
32
+	if (ul_unlock_udomain == 0) return -1;
30 33
 
31
-	ul_new_record = (new_record_t)find_export("~ul_new_record", 1);
32
-	if (ul_new_record == 0) return -1;
33 34
 
34
-	ul_free_record = (free_record_t)find_export("~ul_free_record", 1);
35
-	if (ul_free_record == 0) return -1;
35
+	ul_release_urecord = (release_urecord_t)find_export("~ul_release_urecord", 1);
36
+	if (ul_release_urecord == 0) return -1;
36 37
 
37
-	ul_insert_contact = (insert_contact_t)find_export("~ul_insert_contact", 1);
38
-	if (ul_insert_contact == 0) return -1;
38
+	ul_insert_ucontact = (insert_ucontact_t)find_export("~ul_insert_ucontact", 1);
39
+	if (ul_insert_ucontact == 0) return -1;
39 40
 
40
-	ul_delete_contact = (delete_contact_t)find_export("~ul_delete_contact", 1);
41
-	if (ul_delete_contact == 0) return -1;
41
+	ul_delete_ucontact = (delete_ucontact_t)find_export("~ul_delete_ucontact", 1);
42
+	if (ul_delete_ucontact == 0) return -1;
42 43
 
43
-	ul_get_contact = (get_contact_t)find_export("~ul_get_contact", 1);
44
-	if (ul_get_contact == 0) return -1;
44
+	ul_get_ucontact = (get_ucontact_t)find_export("~ul_get_ucontact", 1);
45
+	if (ul_get_ucontact == 0) return -1;
45 46
 
46
-	ul_update_contact = (update_contact_t)find_export("~ul_update_contact", 1);
47
-	if (ul_update_contact == 0) return -1;
47
+
48
+	ul_update_ucontact = (update_ucontact_t)find_export("~ul_update_ucontact", 1);
49
+	if (ul_update_ucontact == 0) return -1;
48 50
 
49 51
 	return 0;
50 52
 }
... ...
@@ -175,6 +175,7 @@ int timer_handler(void)
175 175
 		ptr = ptr->next;
176 176
 	}
177 177
 	
178
+	print_all_udomains();
178 179
 	return res;
179 180
 }
180 181
 
... ...
@@ -17,7 +17,7 @@
17 17
 /*
18 18
  * Create a new contact structure
19 19
  */
20
-int new_ucontact(str* _aor, str* _contact, time_t _e, float _q,
20
+int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, float _q,
21 21
 		 str* _callid, int _cseq, ucontact_t** _c)
22 22
 {
23 23
 	*_c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));
... ...
@@ -26,6 +26,8 @@ int new_ucontact(str* _aor, str* _contact, time_t _e, float _q,
26 26
 		return -1;
27 27
 	}
28 28
 
29
+
30
+	(*_c)->domain = _dom;
29 31
 	(*_c)->aor = _aor;
30 32
 
31 33
 	(*_c)->c.s = (char*)shm_malloc(_contact->len);
... ...
@@ -53,6 +55,7 @@ int new_ucontact(str* _aor, str* _contact, time_t _e, float _q,
53 55
 	(*_c)->cseq = _cseq;
54 56
 	(*_c)->next = 0;
55 57
 	(*_c)->prev = 0;
58
+	(*_c)->state = CS_NEW;
56 59
 	
57 60
 	return 0;
58 61
 }	
... ...
@@ -75,15 +78,24 @@ void free_ucontact(ucontact_t* _c)
75 78
 void print_ucontact(ucontact_t* _c)
76 79
 {
77 80
 	time_t t = time(0);
81
+	char* st;
82
+
83
+	switch(_c->state) {
84
+	case CS_NEW:   st = "CS_NEW";     break;
85
+	case CS_SYNC:  st = "CS_SYNC";    break;
86
+	case CS_DIRTY: st = "CS_DIRTY";   break;
87
+	default:       st = "CS_UNKNOWN"; break;
88
+	}
78 89
 
79 90
 	printf("~~~Contact(%p)~~~\n", _c);
80 91
 	printf("domain : \'%.*s\'\n", _c->domain->len, _c->domain->s);
81 92
 	printf("aor    : \'%.*s\'\n", _c->aor->len, _c->aor->s);
82 93
 	printf("Contact: \'%.*s\'\n", _c->c.len, _c->c.s);
83
-	printf("Expires: %d\n", (unsigned int)(_c->expires) - t);
94
+	printf("Expires: %lu\n", (unsigned int)(_c->expires) - t);
84 95
 	printf("q      : %10.2f\n", _c->q);
85 96
 	printf("Call-ID: \'%.*s\'\n", _c->callid.len, _c->callid.s);
86 97
 	printf("CSeq   : %d\n", _c->cseq);
98
+	printf("State  : %s\n", st);
87 99
 	printf("next   : %p\n", _c->next);
88 100
 	printf("prev   : %p\n", _c->prev);
89 101
 	printf("~~~/Contact~~~~\n");
... ...
@@ -91,19 +103,19 @@ void print_ucontact(ucontact_t* _c)
91 103
 
92 104
 
93 105
 /*
94
- * Update existing contact with new values
106
+ * Update ucontact structure in memory
95 107
  */
96
-int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
108
+int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
97 109
 {
98 110
 	char* ptr;
99
-
111
+	
100 112
 	if (_c->callid.len < _cid->len) {
101 113
 		ptr = (char*)shm_malloc(_cid->len);
102 114
 		if (ptr == 0) {
103 115
 			LOG(L_ERR, "update_ucontact(): No memory left\n");
104 116
 			return -1;
105 117
 		}
106
-
118
+		
107 119
 		memcpy(ptr, _cid->s, _cid->len);
108 120
 		shm_free(_c->callid.s);
109 121
 		_c->callid.s = ptr;
... ...
@@ -111,34 +123,163 @@ int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
111 123
 		memcpy(_c->callid.s, _cid->s, _cid->len);
112 124
 	}
113 125
 	_c->callid.len = _cid->len;
114
-
126
+	
115 127
 	_c->expires = _e;
116 128
 	_c->q = _q;
117 129
 	_c->cseq = _cs;
118 130
 
119
-	if (use_db) {
120
-		if (write_through) {
121
-			if (db_upd_ucontact(_c) < 0) {
122
-				LOG(L_ERR, "update_ucontact(): Error while updating database\n");
123
-			}
124
-		} else { /* write back */
131
+	return 0;
132
+}
125 133
 
126
-		}
134
+
135
+/* ================ State related functions =============== */
136
+
137
+
138
+/*
139
+ * Update state of the contat if we are using write back scheme
140
+ */
141
+void st_update_ucontact(ucontact_t* _c)
142
+{
143
+	switch(_c->state) {
144
+	case CS_NEW:
145
+		     /* Contact is new and is not in the database yet,
146
+		      * we remain in the same state here because the
147
+		      * contact must be inserted later in the timer
148
+		      */
149
+		break;
150
+
151
+	case CS_SYNC:
152
+		     /* Modified contact need to be updated also in
153
+		      * the database, so transit into CS_DIRTY and
154
+		      * let the timer to do the update again
155
+		      */
156
+		_c->state = CS_DIRTY;
157
+		break;
158
+
159
+	case CS_DIRTY:
160
+		     /* Modification of dirty contact results in
161
+		      * dirty contact again, don't change anything
162
+		      */
163
+		break;
127 164
 	}
165
+}
128 166
 
129
-	return 0;
167
+
168
+/*
169
+ * Update state of the contact if we
170
+ * are using write-back scheme
171
+ * Returns 1 if the contact should be
172
+ * delete from memory immediatelly,
173
+ * 0 otherwise
174
+ */
175
+int st_delete_ucontact(ucontact_t* _c)
176
+{
177
+	switch(_c->state) {
178
+	case CS_NEW:
179
+		     /* Contact is new and isn't in the database
180
+		      * yet, we can delete it from the memory
181
+		      * safely
182
+		      */
183
+		return 1;
184
+
185
+	case CS_SYNC:
186
+	case CS_DIRTY:
187
+		     /* Contact is in the database,
188
+		      * we cannot remove it from the memory 
189
+		      * directly, but we can set expires to zero
190
+		      * and the timer will take care of deleting 
191
+		      * the contact from the memory as well as 
192
+		      * from the database
193
+		      */
194
+		_c->expires = 0;
195
+		return 0;
196
+	}
197
+
198
+	return 0; /* Makes gcc happy */
130 199
 }
131 200
 
132 201
 
133 202
 /*
134
- * Delete contact from the database
203
+ * Called when the timer is about to delete
204
+ * an expired contact, this routine returns
205
+ * 1 if the contact should be removed from
206
+ * the database and 0 otherwise
207
+ */
208
+int st_expired_ucontact(ucontact_t* _c)
209
+{
210
+	     /* There is no need to change contact
211
+	      * state, because the contact will
212
+	      * be deleted anyway
213
+	      */
214
+
215
+	switch(_c->state) {
216
+	case CS_NEW:
217
+		     /* Contact is not in the database
218
+		      * yet, remove it from memory only
219
+		      */
220
+		return 0;
221
+
222
+	case CS_SYNC:
223
+	case CS_DIRTY:
224
+		     /* Remove from database here */
225
+		return 1;
226
+	}
227
+
228
+	return 0; /* Makes gcc happy */
229
+}
230
+
231
+
232
+/*
233
+ * Called when the timer is about flushing the contact,
234
+ * updates contact state and returns 1 if the contact
235
+ * should be inserted, 2 if updated and 0 otherwise
236
+ */
237
+int st_flush_ucontact(ucontact_t* _c)
238
+{
239
+	switch(_c->state) {
240
+	case CS_NEW:
241
+		     /* Contact is new and is not in
242
+		      * the database yet so we have
243
+		      * to insert it
244
+		      */
245
+		_c->state = CS_SYNC;
246
+		return 1;
247
+
248
+	case CS_SYNC:
249
+		     /* Contact is synchronized, do
250
+		      * nothing
251
+		      */
252
+		return 0;
253
+
254
+	case CS_DIRTY:
255
+		     /* Contact has been modified and
256
+		      * is in the db already so we
257
+		      * have to update it
258
+		      */
259
+		_c->state = CS_SYNC;
260
+		return 2;
261
+	}
262
+
263
+	return 0; /* Makes gcc happy */
264
+}
265
+
266
+
267
+/* ============== Database related functions ================ */
268
+
269
+
270
+/*
271
+ * Insert contact into the database
135 272
  */
136
-int db_del_ucontact(ucontact_t* _c)
273
+int db_insert_ucontact(ucontact_t* _c)
137 274
 {
138 275
 	char b[256];
139
-	db_key_t keys[2] = {user_col, contact_col};
140
-	db_val_t vals[2] = {{DB_STR, 0, {.str_val = {_c->aor->s, _c->aor->len}}},
141
-			    {DB_STR, 0, {.str_val = {_c->c.s, _c->c.len}}}
276
+	db_key_t keys[] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col};
277
+	db_val_t vals[] = {{DB_STR,     0, {.str_val = {_c->aor->s, _c->aor->len}}},
278
+			  {DB_STR,      0, {.str_val = {_c->c.s, _c->c.len}}},
279
+			  {DB_DATETIME, 0, {.time_val = _c->expires}},
280
+			  {DB_DOUBLE,   0, {.double_val = _c->q}},
281
+			  {DB_STR,      0, {.str_val = {_c->callid.s, _c->callid.len}}},
282
+			  {DB_INT,      0, {.int_val = _c->cseq}}
142 283
 	};
143 284
 
144 285
 	     /* FIXME */
... ...
@@ -146,8 +287,8 @@ int db_del_ucontact(ucontact_t* _c)
146 287
 	b[_c->domain->len] = '\0';
147 288
 	db_use_table(db, b);
148 289
 
149
-	if (db_delete(db, keys, vals, 2) < 0) {
150
-		LOG(L_ERR, "db_del_ucontact(): Error while deleting from database\n");
290
+	if (db_insert(db, keys, vals, 6) < 0) {
291
+		LOG(L_ERR, "db_ins_ucontact(): Error while inserting contact\n");
151 292
 		return -1;
152 293
 	}
153 294
 
... ...
@@ -158,7 +299,7 @@ int db_del_ucontact(ucontact_t* _c)
158 299
 /*
159 300
  * Update contact in the database
160 301
  */
161
-int db_upd_ucontact(ucontact_t* _c)
302
+int db_update_ucontact(ucontact_t* _c)
162 303
 {
163 304
 	char b[256];
164 305
 	db_key_t keys1[2] = {user_col, contact_col};
... ...
@@ -188,18 +329,14 @@ int db_upd_ucontact(ucontact_t* _c)
188 329
 
189 330
 
190 331
 /*
191
- * Insert contact into the database
332
+ * Delete contact from the database
192 333
  */
193
-int db_ins_ucontact(ucontact_t* _c)
334
+int db_delete_ucontact(ucontact_t* _c)
194 335
 {
195 336
 	char b[256];
196
-	db_key_t keys[] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col};
197
-	db_val_t vals[] = {{DB_STR,     0, {.str_val = {_c->aor->s, _c->aor->len}}},
198
-			  {DB_STR,      0, {.str_val = {_c->c.s, _c->c.len}}},
199
-			  {DB_DATETIME, 0, {.time_val = _c->expires}},
200
-			  {DB_DOUBLE,   0, {.double_val = _c->q}},
201
-			  {DB_STR,      0, {.str_val = {_c->callid.s, _c->callid.len}}},
202
-			  {DB_INT,      0, {.int_val = _c->cseq}}
337
+	db_key_t keys[2] = {user_col, contact_col};
338
+	db_val_t vals[2] = {{DB_STR, 0, {.str_val = {_c->aor->s, _c->aor->len}}},
339
+			    {DB_STR, 0, {.str_val = {_c->c.s, _c->c.len}}}
203 340
 	};
204 341
 
205 342
 	     /* FIXME */
... ...
@@ -207,10 +344,38 @@ int db_ins_ucontact(ucontact_t* _c)
207 344
 	b[_c->domain->len] = '\0';
208 345
 	db_use_table(db, b);
209 346
 
210
-	if (db_insert(db, keys, vals, 6) < 0) {
211
-		LOG(L_ERR, "db_ins_ucontact(): Error while inserting contact\n");
347
+	if (db_delete(db, keys, vals, 2) < 0) {
348
+		LOG(L_ERR, "db_del_ucontact(): Error while deleting from database\n");
212 349
 		return -1;
213 350
 	}
214 351
 
215 352
 	return 0;
216 353
 }
354
+
355
+
356
+/*
357
+ * Update ucontact with new values
358
+ */
359
+int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs)
360
+{
361
+	switch(db_mode) {
362
+	case NO_DB:
363
+		return mem_update_ucontact(_c, _e, _q, _cid, _cs);
364
+		
365
+	case WRITE_THROUGH:
366
+		if (mem_update_ucontact(_c, _e, _q, _cid, _cs) < 0) {
367
+			LOG(L_ERR, "update_ucontact(): Error while updating\n");
368
+			return -1;
369
+		}
370
+
371
+		if (db_update_ucontact(_c) < 0) {
372
+			LOG(L_ERR, "update_ucontact(): Error while updating database\n");
373
+		}
374
+		return 0;
375
+
376
+	case WRITE_BACK:
377
+		st_update_ucontact(_c);
378
+		return mem_update_ucontact(_c, _e, _q, _cid, _cs);
379
+	}
380
+	return 0;
381
+}
... ...
@@ -12,6 +12,13 @@
12 12
 #include "../../str.h"
13 13
 
14 14
 
15
+typedef enum cstate {
16
+	CS_NEW,        /* New contact - not flushed yet */
17
+	CS_SYNC,       /* Synchronized contact with the database */
18
+	CS_DIRTY       /* Update contact - not flushed yet */
19
+} cstate_t;
20
+
21
+
15 22
 typedef struct ucontact {
16 23
 	str* domain;           /* Pointer to domain name */
17 24
 	str* aor;              /* Pointer to the address of record string in record structure*/
... ...
@@ -20,6 +27,7 @@ typedef struct ucontact {
20 27
 	float q;               /* q parameter */
21 28
 	str callid;            /* Call-ID header field */
22 29
         int cseq;              /* CSeq value */
30
+	cstate_t state;        /* State of the contact */
23 31
 	struct ucontact* next; /* Next contact in the linked list */
24 32
 	struct ucontact* prev; /* Previous contact in the linked list */
25 33
 } ucontact_t;
... ...
@@ -28,7 +36,7 @@ typedef struct ucontact {
28 36
 /*
29 37
  * Create a new contact structure
30 38
  */
31
-int new_ucontact(str* _aor, str* _contact, time_t _e, float _q, 
39
+int new_ucontact(str* _dom, str* _aor, str* _contact, time_t _e, float _q, 
32 40
 		 str* _callid, int _cseq, ucontact_t** _c);
33 41
 
34 42
 
... ...
@@ -45,27 +53,77 @@ void print_ucontact(ucontact_t* _c);
45 53
 
46 54
 
47 55
 /*
48
- * Update existing contact with new values
56
+ * Update existing contact in memory with new values
49 57
  */
50
-int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
58
+int mem_update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
59
+
60
+
61
+
62
+/* ===== State transition functions - for write back cache scheme ======== */
51 63
 
52 64
 
53 65
 /*
54
- * Delete contact from the database
66
+ * Update state of the contact if we
67
+ * are using write-back scheme
55 68
  */
56
-int db_del_ucontact(ucontact_t* _c);
69
+void st_update_ucontact(ucontact_t* _c);
57 70
 
58 71
 
59 72
 /*
60
- * Update contact in the database
73
+ * Update state of the contact if we
74
+ * are using write-back scheme
75
+ * Returns 1 if the contact should be
76
+ * deleted from memory immediatelly,
77
+ * 0 otherwise
78
+ */
79
+int st_delete_ucontact(ucontact_t* _c);
80
+
81
+
82
+/*
83
+ * Called when the timer is about to delete
84
+ * an expired contact, this routine returns
85
+ * 1 if the contact should be removed from
86
+ * the database and 0 otherwise
61 87
  */
62
-int db_upd_ucontact(ucontact_t* _c);
88
+int st_expired_ucontact(ucontact_t* _c);
89
+
90
+
91
+/*
92
+ * Called when the timer is about flushing the contact,
93
+ * updates contact state and returns 1 if the contact
94
+ * should be inserted, 2 if updated and 0 otherwise
95
+ */
96
+int st_flush_ucontact(ucontact_t* _c);
97
+
98
+
99
+/* ==== Database related functions ====== */
63 100
 
64 101
 
65 102
 /*
66 103
  * Insert contact into the database
67 104
  */
68
-int db_ins_ucontact(ucontact_t* _c);
105
+int db_insert_ucontact(ucontact_t* _c);
106
+
107
+
108
+/*
109
+ * Update contact in the database
110
+ */
111
+int db_update_ucontact(ucontact_t* _c);
112
+
113
+
114
+/*
115
+ * Delete contact from the database
116
+ */
117
+int db_delete_ucontact(ucontact_t* _c);
118
+
119
+
120
+/* ====== Module interface ====== */
121
+
122
+
123
+/*
124
+ * Update ucontact with new values
125
+ */
126
+int update_ucontact(ucontact_t* _c, time_t _e, float _q, str* _cid, int _cs);
69 127
 
70 128
 
71 129
 #endif /* UCONTACT_H */
... ...
@@ -165,48 +165,80 @@ void print_udomain(udomain_t* _d)
165 165
 }
166 166
 
167 167
 
168
-static inline int ins(struct urecord* _r, str* _c, int _e, float _q, str* _cid, int _cs)
168
+
169
+int preload_udomain(udomain_t* _d)
169 170
 {
170
-	ucontact_t* c, *ptr, *prev = 0;
171
+	char b[256];
172
+	db_key_t columns[6] = {user_col, contact_col, expires_col, q_col, callid_col, cseq_col};
173
+	db_res_t* res;
174
+	db_row_t* row;
175
+	int i, cseq;
171 176
 	
172
-	if (new_ucontact(&_r->aor, _c, _e, _q, _cid, _cs, &c) < 0) {
173
-		LOG(L_ERR, "ins(): Can't create new contact\n");
177
+	str user, contact, callid;
178
+	time_t expires;
179
+	float q;
180
+
181
+	urecord_t* r;
182
+	ucontact_t* c;
183
+
184
+	memcpy(b, _d->name->s, _d->name->len);
185
+	b[_d->name->len] = '\0';
186
+	db_use_table(db, b);
187
+	if (db_query(db, 0, 0, columns, 0, 6, 0, &res) < 0) {
188
+		LOG(L_ERR, "preload_udomain(): Error while doing db_query\n");
174 189
 		return -1;
175 190
 	}
176 191
 
177
-	ptr = _r->contacts;
178
-	while(ptr) {
179
-		if (ptr->q < _q) break;
180
-		prev = ptr;
181
-		ptr = ptr->next;
192
+	if (RES_ROW_N(res) == 0) {
193
+		DBG("preload_udomain(): Table is empty\n");
194
+		db_free_query(db, res);
195
+		return 0;
182 196
 	}
183 197
 
184
-	if (ptr) {
185
-		if (!ptr->prev) {
186
-			ptr->prev = c;
187
-			c->next = ptr;
188
-			_r->contacts = c;
189
-		} else {
190
-			c->next = ptr;
191
-			c->prev = ptr->prev;
192
-			ptr->prev->next = c;
193
-			ptr->prev = c;
198
+	lock_udomain(_d);
199
+
200
+	for(i = 0; i < RES_ROW_N(res); i++) {
201
+		row = RES_ROWS(res) + i;
202
+		
203
+		user.s      = (char*)VAL_STRING(ROW_VALUES(row));
204
+		user.len    = strlen(user.s);
205
+		contact.s   = (char*)VAL_STRING(ROW_VALUES(row) + 1);
206
+		contact.len = strlen(contact.s);
207
+		expires     = VAL_TIME  (ROW_VALUES(row) + 2);
208
+		q           = VAL_DOUBLE(ROW_VALUES(row) + 3);
209
+		cseq        = VAL_INT   (ROW_VALUES(row) + 5);
210
+		callid.s    = (char*)VAL_STRING(ROW_VALUES(row) + 4);
211
+		callid.len  = strlen(callid.s);
212
+
213
+		if (get_urecord(_d, &user, &r) > 0) {
214
+			if (mem_insert_urecord(_d, &user, &r) < 0) {
215
+				LOG(L_ERR, "preload_udomain(): Can't create a record\n");
216
+				db_free_query(db, res);
217
+				unlock_udomain(_d);
218
+				return -2;
219
+			}
194 220
 		}
195
-	} else if (prev) {
196
-		prev->next = c;
197
-		c->prev = prev;
198
-	} else {
199
-		_r->contacts = c;
221
+		
222
+		if (mem_insert_ucontact(r, &contact, expires, q, &callid, cseq, &c) < 0) {
223
+			LOG(L_ERR, "preload_udomain(): Error while inserting contact\n");
224
+			db_free_query(db, res);
225
+			unlock_udomain(_d);
226
+			return -3;
227
+		}
228
+
229
+		     /* We have to do this, because insert_ucontact sets state to CS_NEW
230
+		      * and we have the contact in the dabase already
231
+		      */
232
+		c->state = CS_SYNC;
200 233
 	}
201 234
 
202
-	c->domain = _r->domain;
235
+	db_free_query(db, res);
236
+	unlock_udomain(_d);
203 237
 	return 0;
204 238
 }
205 239
 
206 240
 
207 241
 /*
208
- * Load data from a database
209
- */
210 242
 int preload_udomain(udomain_t* _d)
211 243
 {
212 244
 	char b[256];
... ...
@@ -220,7 +252,6 @@ int preload_udomain(udomain_t* _d)
220 252
 	time_t expires;
221 253
 	str s, contact, callid;
222 254
 
223
-	     /* FIXME */
224 255
 	memcpy(b, _d->name->s, _d->name->len);
225 256
 	b[_d->name->len] = '\0';
226 257
 	db_use_table(db, b);
... ...
@@ -244,32 +275,18 @@ int preload_udomain(udomain_t* _d)
244 275
 			DBG("preload_udomain(): Preloading contacts for username \'%s\'\n", user);
245 276
 			aor = user;
246 277
 
247
-			if (rec && (insert_urecord(_d, rec) < 0)) {
248
-				LOG(L_ERR, "preload_udomain(): Error while inserting record\n");
249
-				free_urecord(rec);
250
-				db_free_query(db, res);
251
-				free_urecord(rec);
252
-				return -2;
253
-			}
278
+			if (rec) release_urecord(rec);
254 279
 
255 280
 			s.s = (char*)user;
256 281
 			s.len = strlen(user);
257 282
 
258
-			if (new_urecord(&s, &rec) < 0) {
283
+			if (insert_urecord(_d_d->name, &s, &rec) < 0) {
259 284
 				LOG(L_ERR, "preload_udomain(): Can't create new record\n");
260 285
 				db_free_query(db, res);
261 286
 				return -3;
262 287
 			}
263
-			rec->domain = _d->name;
264 288
 		}
265 289
 		
266
-		contact.s   = (char*)VAL_STRING(ROW_VALUES(row) + 1);
267
-		contact.len = strlen(contact.s);
268
-		expires     = VAL_TIME  (ROW_VALUES(row) + 2);
269
-		q           = VAL_DOUBLE(ROW_VALUES(row) + 3);
270
-		cseq        = VAL_INT   (ROW_VALUES(row) + 5);
271
-		callid.s    = (char*)VAL_STRING(ROW_VALUES(row) + 4);
272
-		callid.len  = strlen(callid.s);
273 290
 
274 291
 		if (ins(rec, &contact, expires, q, &callid, cseq) < 0) {
275 292
 			LOG(L_ERR, "preload_udomain(): Error while adding contact\n");
... ...
@@ -289,172 +306,164 @@ int preload_udomain(udomain_t* _d)
289 306
 	db_free_query(db, res);
290 307
 	return 0;
291 308
 }
309
+*/
292 310
 
293 311
 
294 312
 /*
295 313
  * Insert a new record into domain
296 314
  */
297
-int insert_urecord(udomain_t* _d, urecord_t* _r)
315
+int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
298 316
 {
299 317
 	int sl;
300
-
301
-	sl = hash_func(_d, _r->aor.s, _r->aor.len);
302 318
 	
303
-	if (sl == -1) {
304
-		LOG(L_ERR, "insert_urecord(): Error while hashing slot\n");
319
+	if (new_urecord(_d->name, _aor, _r) < 0) {
320
+		LOG(L_ERR, "insert_urecord(): Error while creating urecord\n");
305 321
 		return -1;
306 322
 	}
307 323
 
308
-	get_lock(&_d->lock);
309
-
310
-	if (db) {  /* Update database */
311
-		/*
312
-	        if (db_insert_location(db, _l) < 0) {
313
-			LOG(L_ERR, "insert_record(): Error while inserting bindings into database\n");
314
-			free_element(ptr);
315
-			release_lock(&_d->lock);
316
-			return -3;
317
-		}
318
-		*/
319
-	}
320
-
321
-	slot_add(&_d->table[sl], _r);
322
-	udomain_add(_d, _r);
323
-	_r->domain = _d->name;
324
-	release_lock(&_d->lock);
324
+	sl = hash_func(_d, _aor->s, _aor->len);
325
+	slot_add(&_d->table[sl], *_r);
326
+	udomain_add(_d, *_r);
325 327
 	return 0;
326 328
 }
327 329
 
328 330
 
329
-/* 
330
- * It is neccessary to call cache_release_el when you don't need element
331
- * returned by this function anymore
332
- *
333
- * WARNING: You must call no other domain function between get_record
334
- *          and release_record, if you do so, deadlock will occur !!!
331
+/*
332
+ * Remove a record from domain
335 333
  */
336
-int get_urecord(udomain_t* _d, str* _a, urecord_t** _r)
334
+void mem_delete_urecord(udomain_t* _d, struct urecord* _r)
337 335
 {
338
-	int sl, i;
339
-	urecord_t* r;
336
+	udomain_remove(_d, _r);
337
+	slot_rem(_r->slot, _r);
338
+	free_urecord(_r);
339
+}
340 340
 
341
-	sl = hash_func(_d, _a->s, _a->len);
342 341
 
343
-	if (sl == -1) {
344
-		LOG(L_ERR, "get_urecord(): Error while generating hash\n");
345
-		return -1;
346
-	}
342
+int timer_udomain(udomain_t* _d)
343
+{
344
+	struct urecord* ptr, *t;
347 345
 
348
-	get_lock(&_d->lock);
349
-	r = _d->table[sl].first;
346
+	lock_udomain(_d);
350 347
 
351
-	for(i = 0; i < _d->table[sl].n; i++) {
352
-		if ((r->aor.len == _a->len) && !memcmp(r->aor.s, _a->s, _a->len)) {
353
-			*_r = r;
354
-			return 0;
355
-		}
348
+	ptr = _d->d_ll.first;
356 349
 
357
-		r = r->s_ll.next;
350
+	while(ptr) {
351
+		if (timer_urecord(ptr) < 0) {
352
+			LOG(L_ERR, "timer_udomain(): Error in timer_urecord\n");
353
+			unlock_udomain(_d);
354
+			return -1;
355
+		}
356
+		
357
+		     /* Remove the entire record
358
+		      * if it is empty
359
+		      */
360
+		if (ptr->contacts == 0) {
361
+			t = ptr;
362
+			ptr = ptr->d_ll.next;
363
+			mem_delete_urecord(_d, t);
364
+		} else {
365
+			ptr = ptr->d_ll.next;
366
+		}
358 367
 	}
368
+	
369
+	unlock_udomain(_d);
370
+	return 0;
371
+}
372
+
373
+
374
+/*
375
+ * Get lock
376
+ */
377
+void lock_udomain(udomain_t* _d)
378
+{
379
+	get_lock(&_d->lock);
380
+}
359 381
 
382
+
383
+/*
384
+ * Release lock
385
+ */
386
+void unlock_udomain(udomain_t* _d)
387
+{
360 388
 	release_lock(&_d->lock);
361
-	return 1;   /* Nothing found */
362 389
 }
363 390
 
364 391
 
365 392
 /*
366
- * Remove a record from domain
393
+ * Create and insert a new record
367 394
  */
368
-int delete_urecord(udomain_t* _d, str* _a)
395
+int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
369 396
 {
370
-	int sl, i;
371
-	urecord_t* r;
372
-	
373
-	sl = hash_func(_d, _a->s, _a->len);
374
-	if (sl == -1) {
375
-		LOG(L_ERR, "delete_urecord(): Error while generating hash\n");
397
+	if (mem_insert_urecord(_d, _aor, _r) < 0) {
398
+		LOG(L_ERR, "insert_urecord(): Error while inserting record\n");
376 399
 		return -1;
377 400
 	}
401
+	return 0;
402
+}
403
+
404
+
405
+/*
406
+ * Obtain a urecord pointer if the urecord exists in domain
407
+ */
408
+int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r)
409
+{
410
+	int sl, i;
411
+	urecord_t* r;
412
+
413
+	sl = hash_func(_d, _aor->s, _aor->len);
378 414
 
379
-	get_lock(&_d->lock);
380 415
 	r = _d->table[sl].first;
381 416
 
382 417
 	for(i = 0; i < _d->table[sl].n; i++) {
383
-		if ((r->aor.len == _a->len) && !memcmp(r->aor.s, _a->s, _a->len)) {
384
-			if (use_db) {
385
-				if (write_through) {
386
-					if (db_del_urecord(r) < 0) {
387
-						LOG(L_ERR, "delete_urecord(): Error while deleting from database\n");
388
-					}
389
-				} else {
390
-				}
391
-			}
392
-			
393
-			udomain_remove(_d, r);
394
-			slot_rem(&_d->table[sl], r);
395
-
396
-			r->domain = 0;
397
-			free_urecord(r);
398
-			release_lock(&_d->lock);
418
+		if ((r->aor.len == _aor->len) && !memcmp(r->aor.s, _aor->s, _aor->len)) {
419
+			*_r = r;
399 420
 			return 0;
400 421
 		}
401 422
 
402 423
 		r = r->s_ll.next;
403 424
 	}
404 425
 
405
-	release_lock(&_d->lock);
406
-	return 1; /* Record not found */
426
+	return 1;   /* Nothing found */
407 427
 }
408 428
 
409 429
 
410 430
 /*
411
- * Release a record previosly obtained through get_record
431
+ * Delete a urecord from domain
412 432
  */
413
-void release_urecord(urecord_t* _r)
414
-{
415
-	fl_lock_t* l;
416
-
417
-	if (_r->contacts == 0) {
418
-		l = &_r->slot->d->lock;
419
-		udomain_remove(_r->slot->d, _r);
420
-		slot_rem(_r->slot, _r);
421
-		_r->domain = 0;
422
-		release_lock(l);
423
-		free_urecord(_r);
424
-		return;
425
-	}
426
-
427
-	release_lock(&_r->slot->d->lock);
428
-}
429
-
430
-
431
-int timer_udomain(udomain_t* _d)
433
+int delete_urecord(udomain_t* _d, str* _aor)
432 434
 {
433
-	struct urecord* ptr, *t;
434
-
435
-	get_lock(&_d->lock);
436
-
437
-	ptr = _d->d_ll.first;
435
+	struct ucontact* c, *t;
436
+	struct urecord* r;
438 437
 
439
-	while(ptr) {
440
-		if (timer_urecord(ptr) < 0) {
441
-			LOG(L_ERR, "timer_udomain(): Error in timer_urecord\n");
442
-			release_lock(&_d->lock);
443
-			return -1;
438
+	if (get_urecord(_d, _aor, &r) > 0) {
439
+		return 0;
440
+	}
441
+	
442
+	switch(db_mode) {
443
+	case WRITE_THROUGH:
444
+		if (db_delete_urecord(r) < 0) {
445
+			LOG(L_ERR, "delete_urecord(): Error while deleting record from database\n");
444 446
 		}
445
-		
446
-		if (ptr->contacts == 0) {
447
-			t = ptr;
448
-			ptr = ptr->d_ll.next;
449
-			udomain_remove(t->slot->d, t);
450
-			slot_rem(t->slot, t);
451
-			t->domain = 0;
452
-			free_urecord(t);
453
-		} else {
454
-			ptr = ptr->d_ll.next;
447
+		mem_delete_urecord(_d, r);
448
+		return 0;
449
+
450
+	case WRITE_BACK:
451
+		c = r->contacts;
452
+		while(c) {
453
+			t = c;
454
+			c = c->next;
455
+			if (delete_ucontact(r, t) < 0) {
456
+				LOG(L_ERR, "delete_urecord(): Error while deleting contact\n");
457
+				return -1;
458
+			}
455 459
 		}
460
+		release_urecord(r);
461
+		return 0;
462
+
463
+	case NO_DB:
464
+		mem_delete_urecord(_d, r);
465
+		return 0;
456 466
 	}
457
-	
458
-	release_lock(&_d->lock);
467
+
459 468
 	return 0;
460 469
 }
... ...
@@ -73,27 +73,46 @@ int timer_udomain(udomain_t* _d);
73 73
 /*
74 74
  * Insert record into domain
75 75
  */
76
-int insert_urecord(udomain_t* _d, struct urecord* _r);
76
+int mem_insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r);
77 77
 
78 78
 
79 79
 /*
80
- * Find record with specified AOR
80
+ * Delete a record
81 81
  */
82
-int get_urecord(udomain_t* _d, str* _a, struct urecord** _r);
82
+void mem_delete_urecord(udomain_t* _d, struct urecord* _r);
83 83
 
84 84
 
85 85
 /*
86
- * Delete a record
86
+ * Get lock
87
+ */
88
+void lock_udomain(udomain_t* _d);
89
+
90
+
91
+/*
92
+ * Release lock
87 93
  */
88
-int delete_urecord(udomain_t* _d, str* _a);
94
+void unlock_udomain(udomain_t* _d);
95
+
96
+
97
+/* ===== module interface ======= */
89 98
 
90 99
 
91 100
 /*
92
- * Release a record structure previously obtained
93
- * using get_record
101
+ * Create and insert a new record
94 102
  */
95
-void release_urecord(struct urecord* _r);
103
+int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r);
96 104
 
97 105
 
106
+/*
107
+ * Obtain a urecord pointer if the urecord exists in domain
108
+ */
109
+int get_urecord(udomain_t* _d, str* _aor, struct urecord** _r);
110
+
111
+
112
+/*
113
+ * Delete a urecord from domain
114
+ */
115
+int delete_urecord(udomain_t* _d, str* _aor);
116
+
98 117
 
99 118
 #endif /* UDOMAIN_H */
... ...
@@ -33,8 +33,7 @@ char* cseq_col       = "cseq";                             /* Name of column con
33 33
 char* method_col     = "method";                           /* Name of column containing supported method */
34 34
 char* db_url         = "sql://janakj:heslo@localhost/ser"; /* Database URL */
35 35
 int   timer_interval = 60;                                 /* Timer interval in seconds */
36
-int   write_through  = 0;                                  /* Enable or disable write-through cache scheme */
37
-int   use_db         = 1;                                  /* Specifies whether to use database for persistent storage */
36
+int   db_mode        = 0;                                  /* Database sync scheme: 0-no db, 1-write through, 2-write back */
38 37
 
39 38
 
40 39
 db_con_t* db; /* Database connection handle */
... ...
@@ -43,20 +42,20 @@ db_con_t* db; /* Database connection handle */
43 42
 struct module_exports exports = {
44 43
 	"usrloc",
45 44
 	(char*[]) {
46
-		"~ul_register_domain", /* Create a new domain */
45
+		"~ul_register_udomain", /* Create a new domain */
47 46
 
48
-		"~ul_insert_record",   /* Insert record into a domain */
49
-		"~ul_delete_record",   /* Delete record from a domain */
50
-		"~ul_get_record",      /* Get record from a domain */
51
-		"~ul_release_record",  /* Release record obtained using get_record */
47
+		"~ul_insert_urecord",   /* Insert record into a domain */
48
+		"~ul_delete_urecord",   /* Delete record from a domain */
49
+		"~ul_get_urecord",      /* Get record from a domain */
50
+		"~ul_lock_udomain",     /* Lock domain */
51
+		"~ul_unlock_udomain",   /* Unlock domain */
52 52
 
53
-		"~ul_new_record",      /* Create new record structure */
54
-		"~ul_free_record",     /* Release a record structure */
55
-		"~ul_insert_contact",  /* Insert a new contact into a record */
56
-		"~ul_delete_contact",  /* Remove a contact from a record */
57
-		"~ul_get_contact",     /* Return pointer to a contact */
53
+		"~ul_release_urecord",  /* Release record obtained using get_record */
54
+		"~ul_insert_ucontact",  /* Insert a new contact into a record */
55
+		"~ul_delete_ucontact",  /* Remove a contact from a record */
56
+		"~ul_get_ucontact",     /* Return pointer to a contact */
58 57
 
59
-		"~ul_update_contact"   /* Update a contact */
58
+		"~ul_update_ucontact"   /* Update a contact */
60 59
 	},
61 60
 	(cmd_function[]) {
62 61
 		(cmd_function)register_udomain,
... ...
@@ -64,10 +63,10 @@ struct module_exports exports = {
64