Browse code

modules_k/rls: RLS does not send NOTIFY requests when rls_watchers are cleaned in DB only mode

- Fixed now. The DB only clean function sets the updated flag. The notifier
process will detect that a record needs updated (and that its expires time
is in the past) and send a terminated-state NOTIFY and delete the record.

Peter Dunkley authored on 20/04/2012 10:43:41
Showing 2 changed files
... ...
@@ -852,6 +852,7 @@ static void timer_send_full_state_notifies(int round)
852 852
 	event_t parsed_event;
853 853
 	xmlDocPtr doc = NULL;
854 854
 	xmlNodePtr service_node = NULL;
855
+	int now = (int)time(NULL);
855 856
 
856 857
 	query_cols[0] = &str_updated_col;
857 858
 	query_vals[0].type = DB1_INT;
... ...
@@ -945,33 +946,41 @@ static void timer_send_full_state_notifies(int round)
945 946
 		sub.remote_cseq = VAL_INT(&values[18]);
946 947
 		sub.status = VAL_INT(&values[19]);
947 948
 		sub.version = VAL_INT(&values[20]);
948
-		sub.expires = VAL_INT(&values[21]) - (int)time(NULL);
949
-		if (sub.expires < 0) sub.expires = 0;
950
-		
951
-		if (rls_get_service_list(&sub.pres_uri, &sub.watcher_user,
952
-			&sub.watcher_domain, &service_node, &doc) < 0)
953
-		{
954
-			LM_ERR("failed getting resource list\n");
955
-			goto done;
956
-		}
957
-		if (doc == NULL)
958
-		{
959
-			LM_WARN("no document returned for uri <%.*s>\n",
960
-				sub.pres_uri.len, sub.pres_uri.s);
961
-			goto done;
962
-		}
949
+		if (VAL_INT(&values[21]) > now)
950
+			sub.expires = VAL_INT(&values[21]) - now;
951
+		else
952
+			sub.expires = 0;
953
+
954
+		if (sub.expires < rls_expires_offset) sub.expires = 0;
963 955
 
964
-		if (send_full_notify(&sub, service_node, &sub.pres_uri, 0) < 0)
956
+		if (sub.expires != 0)
965 957
 		{
966
-			LM_ERR("failed sending full state notify\n");
967
-			goto done;
968
-		}
958
+			if (rls_get_service_list(&sub.pres_uri, &sub.watcher_user,
959
+				&sub.watcher_domain, &service_node, &doc) < 0)
960
+			{
961
+				LM_ERR("failed getting resource list\n");
962
+				goto done;
963
+			}
964
+			if (doc == NULL)
965
+			{
966
+				LM_WARN("no document returned for uri <%.*s>\n",
967
+					sub.pres_uri.len, sub.pres_uri.s);
968
+				goto done;
969
+			}
969 970
 
970
-		if (sub.expires == 0)
971
+			if (send_full_notify(&sub, service_node, &sub.pres_uri, 0) < 0)
972
+			{
973
+				LM_ERR("failed sending full state notify\n");
974
+				goto done;
975
+			}
976
+			xmlFreeDoc(doc);
977
+			doc = NULL;
978
+		}
979
+		else
980
+		{
981
+			rls_send_notify(&sub, NULL, NULL, NULL);
971 982
 			delete_rlsdb(&sub.callid, &sub.to_tag, &sub.from_tag);
972
-
973
-		xmlFreeDoc(doc);
974
-		doc = NULL;
983
+		}
975 984
 	}
976 985
 
977 986
 done:
... ...
@@ -33,6 +33,7 @@
33 33
 #include "../../lib/srdb1/db.h"
34 34
 #include "../../parser/msg_parser.h"
35 35
 #include "../../parser/parse_from.h"
36
+#include "../../hashes.h"
36 37
 
37 38
 #include "rls.h"
38 39
 
... ...
@@ -113,34 +114,112 @@ void rls_update_db_subs_timer(db1_con_t *db,db_func_t dbf, shtable_t hash_table,
113 114
 int delete_expired_subs_rlsdb( void )
114 115
 
115 116
 {
116
-	db_key_t query_cols[1];
117
-	db_val_t query_vals[1];
117
+	db_key_t query_cols[3], result_cols[3], update_cols[1];
118
+	db_val_t query_vals[3], update_vals[1], *values;
118 119
 	db_op_t query_ops[1];
120
+	db_row_t *rows;
121
+	db1_res_t *result = NULL;
122
+	int n_query_cols = 0, n_result_cols = 0, n_update_cols = 0;
123
+	int r_callid_col = 0, r_to_tag_col = 0, r_from_tag_col = 0;
124
+	int i;
125
+	subs_t subs;
126
+	str rlsubs_did = {0, 0};
119 127
 
120 128
 	if(rls_db == NULL)
121 129
 	{
122 130
 		LM_ERR("null database connection\n");
123
-		return(-1);
131
+		goto error;
124 132
 	}
125 133
 
126 134
 	if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
127 135
 	{
128 136
 		LM_ERR("use table failed\n");
129
-		return(-1);
137
+		goto error;
130 138
 	}
131
-	query_cols[0]= &str_expires_col;
132
-	query_vals[0].type = DB1_INT;
133
-	query_vals[0].nul = 0;
134
-	query_vals[0].val.int_val= (int)time(NULL) - rls_expires_offset;
135
-	query_ops[0]= OP_LT;
136 139
 
137
-	if (rls_dbf.delete(rls_db, query_cols, query_ops, query_vals, 1) < 0)
140
+	query_cols[n_query_cols]= &str_expires_col;
141
+	query_vals[n_query_cols].type = DB1_INT;
142
+	query_vals[n_query_cols].nul = 0;
143
+	query_vals[n_query_cols].val.int_val= (int)time(NULL) - rls_expires_offset;
144
+	query_ops[n_query_cols]= OP_LT;
145
+	n_query_cols++;
146
+
147
+	result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
148
+	result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
149
+	result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
150
+
151
+	if(rls_dbf.query(rls_db, query_cols, query_ops, query_vals, result_cols, 
152
+				n_query_cols, n_result_cols, 0, &result )< 0)
138 153
 	{
139
-		LM_ERR("db delete failed for expired subs\n");
140
-		return(-1);
154
+		LM_ERR("Can't query db\n");
155
+		goto error;
141 156
 	}
142 157
 
143
-	return(1);
158
+	if(result == NULL) goto error;
159
+
160
+	for (i = 0; i <RES_ROW_N(result); i++)
161
+	{
162
+		rows = RES_ROWS(result);
163
+		values = ROW_VALUES(rows);
164
+
165
+		subs.callid.s = (char *) VAL_STRING(&values[r_callid_col]);
166
+		subs.callid.len = strlen(subs.callid.s);
167
+		subs.to_tag.s = (char *) VAL_STRING(&values[r_to_tag_col]);
168
+		subs.to_tag.len = strlen(subs.to_tag.s);
169
+		subs.from_tag.s = (char *) VAL_STRING(&values[r_from_tag_col]);
170
+		subs.from_tag.len = strlen(subs.from_tag.s);
171
+
172
+		if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0)
173
+		{
174
+			LM_ERR("cannot build rls subs did\n");
175
+			goto error;
176
+		}
177
+		subs.updated = core_hash(&rlsubs_did, NULL,
178
+			(waitn_time * rls_notifier_poll_rate * rls_notifier_processes) - 1);
179
+
180
+		n_query_cols = 0;
181
+
182
+		query_cols[n_query_cols] = &str_callid_col;
183
+		query_vals[n_query_cols].type = DB1_STR;
184
+		query_vals[n_query_cols].nul = 0;
185
+		query_vals[n_query_cols].val.str_val = subs.callid;
186
+		n_query_cols++;
187
+
188
+		query_cols[n_query_cols] = &str_to_tag_col;
189
+		query_vals[n_query_cols].type = DB1_STR;
190
+		query_vals[n_query_cols].nul = 0;
191
+		query_vals[n_query_cols].val.str_val = subs.to_tag;
192
+		n_query_cols++;
193
+
194
+		query_cols[n_query_cols] = &str_from_tag_col;
195
+		query_vals[n_query_cols].type = DB1_STR;
196
+		query_vals[n_query_cols].nul = 0;
197
+		query_vals[n_query_cols].val.str_val = subs.from_tag;
198
+		n_query_cols++;
199
+
200
+		update_cols[n_update_cols] = &str_updated_col;
201
+		update_vals[n_update_cols].type = DB1_INT;
202
+		update_vals[n_update_cols].nul = 0;
203
+		update_vals[n_update_cols].val.int_val = subs.updated;
204
+		n_update_cols++;
205
+
206
+		if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
207
+			update_cols,update_vals,n_query_cols,n_update_cols) < 0)
208
+		{
209
+			LM_ERR("db update failed for expired subs\n");
210
+			goto error;
211
+		}
212
+
213
+		pkg_free(rlsubs_did.s);
214
+	}
215
+
216
+	if(result) rls_dbf.free_result(rls_db, result);
217
+	return 1;
218
+
219
+error:
220
+	if (result) rls_dbf.free_result(rls_db, result);
221
+	if (rlsubs_did.s) pkg_free(rlsubs_did.s);
222
+	return -1;
144 223
 }
145 224
 
146 225
 /******************************************************************************/