1 /*
2 * rls db - RLS database support
3 *
4 * Copyright (C) 2011 Crocodile RCS Ltd
5 *
6 * This file is part of Kamailio, a free SIP server.
7 *
8 * Kamailio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
12 *
13 * Kamailio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "../../core/mem/mem.h"
29 #include "../../core/mem/shm_mem.h"
30 #include "../../core/dprint.h"
31 #include "../../lib/srdb1/db.h"
32 #include "../../core/parser/msg_parser.h"
33 #include "../../core/parser/parse_from.h"
34 #include "../../core/hashes.h"
35
36 #include "rls.h"
37
38 #define CONT_COPYDB(buf, dest, source)\
39 do{ \
40 dest.s= (char*)buf+ size;\
41 memcpy(dest.s, source, strlen(source));\
42 dest.len= strlen(source);\
43 size+= strlen(source); \
44 } while(0)
45
46 /* database connection */
47 extern db1_con_t *rls_db;
48 extern db_func_t rls_dbf;
49
50 extern void update_a_sub(subs_t *subs_copy );
51
52 /******************************************************************************/
53
rls_new_shtable(int hash_size)54 shtable_t rls_new_shtable(int hash_size)
55 {
56 LM_ERR( "rls_new_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
57 return(NULL);
58 }
59
60 /******************************************************************************/
61
rls_destroy_shtable(shtable_t htable,int hash_size)62 void rls_destroy_shtable(shtable_t htable, int hash_size)
63 {
64 LM_ERR( "rls_destroy_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
65 }
66
67 /******************************************************************************/
68
rls_insert_shtable(shtable_t htable,unsigned int hash_code,subs_t * subs)69 int rls_insert_shtable(shtable_t htable,unsigned int hash_code, subs_t* subs)
70 {
71 LM_ERR( "rls_insert_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
72 return(-1);
73 }
74
75 /******************************************************************************/
76
rls_search_shtable(shtable_t htable,str callid,str to_tag,str from_tag,unsigned int hash_code)77 subs_t* rls_search_shtable(shtable_t htable,str callid,str to_tag,
78 str from_tag,unsigned int hash_code)
79 {
80 LM_ERR( "rls_search_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
81 return(NULL);
82 }
83
84 /******************************************************************************/
85
rls_delete_shtable(shtable_t htable,unsigned int hash_code,subs_t * subs)86 int rls_delete_shtable(shtable_t htable,unsigned int hash_code, subs_t* subs)
87 {
88 LM_ERR( "rls_delete_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
89 return(-1);
90 }
91
92 /******************************************************************************/
93
rls_update_shtable(shtable_t htable,unsigned int hash_code,subs_t * subs,int type)94 int rls_update_shtable(shtable_t htable,unsigned int hash_code,
95 subs_t* subs, int type)
96 {
97 LM_ERR( "rls_update_shtable shouldn't be called in RLS_DB_ONLY mode\n" );
98 return(-1);
99 }
100
101 /******************************************************************************/
102
rls_update_db_subs_timer(db1_con_t * db,db_func_t * dbf,shtable_t hash_table,int htable_size,int no_lock,handle_expired_func_t handle_expired_func)103 void rls_update_db_subs_timer(db1_con_t *db,db_func_t *dbf, shtable_t hash_table,
104 int htable_size, int no_lock, handle_expired_func_t handle_expired_func)
105 {
106 LM_ERR( "rls_update_db_subs_timer shouldn't be called in RLS_DB_ONLY mode\n" );
107 }
108
109 /******************************************************************************/
110 /******************************************************************************/
111
delete_expired_subs_rlsdb(void)112 int delete_expired_subs_rlsdb( void )
113
114 {
115 db_key_t query_cols[3], result_cols[3], update_cols[1];
116 db_val_t query_vals[3], update_vals[1], *values;
117 db_op_t query_ops[2];
118 db_row_t *rows;
119 db1_res_t *result = NULL;
120 int n_query_cols = 0, n_result_cols = 0;
121 int r_callid_col = 0, r_to_tag_col = 0, r_from_tag_col = 0;
122 int i, nr_rows;
123 subs_t subs;
124 str rlsubs_did = {0, 0};
125 db_query_f query_fn = rls_dbf.query_lock ? rls_dbf.query_lock : rls_dbf.query;
126
127 if(rls_db == NULL)
128 {
129 LM_ERR("null database connection\n");
130 goto error;
131 }
132
133 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
134 {
135 LM_ERR("use table failed\n");
136 goto error;
137 }
138
139 query_cols[n_query_cols]= &str_expires_col;
140 query_vals[n_query_cols].type = DB1_INT;
141 query_vals[n_query_cols].nul = 0;
142 query_vals[n_query_cols].val.int_val= (int)time(NULL) - rls_expires_offset;
143 query_ops[n_query_cols]= OP_LT;
144 n_query_cols++;
145
146 query_cols[n_query_cols]= &str_updated_col;
147 query_vals[n_query_cols].type = DB1_INT;
148 query_vals[n_query_cols].nul = 0;
149 query_vals[n_query_cols].val.int_val= NO_UPDATE_TYPE;
150 query_ops[n_query_cols]= OP_EQ;
151 n_query_cols++;
152
153 result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
154 result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
155 result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
156
157 if (rls_dbf.start_transaction)
158 {
159 if (rls_dbf.start_transaction(rls_db, DB_LOCKING_WRITE) < 0)
160 {
161 LM_ERR("in start_transaction\n");
162 goto error;
163 }
164 }
165
166 if(query_fn(rls_db, query_cols, query_ops, query_vals, result_cols,
167 n_query_cols, n_result_cols, 0, &result )< 0)
168 {
169 LM_ERR("Can't query db\n");
170 goto error;
171 }
172
173 if(result == NULL) goto error;
174
175 rows = RES_ROWS(result);
176 nr_rows = RES_ROW_N(result);
177
178 for (i = 0; i < nr_rows; i++)
179 {
180 memset(&subs, 0, sizeof(subs_t));
181 values = ROW_VALUES(&rows[i]);
182
183 subs.callid.s = (char *) VAL_STRING(&values[r_callid_col]);
184 subs.callid.len = strlen(subs.callid.s);
185 subs.to_tag.s = (char *) VAL_STRING(&values[r_to_tag_col]);
186 subs.to_tag.len = strlen(subs.to_tag.s);
187 subs.from_tag.s = (char *) VAL_STRING(&values[r_from_tag_col]);
188 subs.from_tag.len = strlen(subs.from_tag.s);
189
190 if (CONSTR_RLSUBS_DID(&subs, &rlsubs_did) < 0)
191 {
192 LM_ERR("cannot build rls subs did\n");
193 goto error;
194 }
195 subs.updated = core_hash(&rlsubs_did, NULL, 0) %
196 (waitn_time * rls_notifier_poll_rate * rls_notifier_processes);
197
198 n_query_cols = 0;
199
200 query_cols[n_query_cols] = &str_callid_col;
201 query_vals[n_query_cols].type = DB1_STR;
202 query_vals[n_query_cols].nul = 0;
203 query_vals[n_query_cols].val.str_val = subs.callid;
204 n_query_cols++;
205
206 query_cols[n_query_cols] = &str_to_tag_col;
207 query_vals[n_query_cols].type = DB1_STR;
208 query_vals[n_query_cols].nul = 0;
209 query_vals[n_query_cols].val.str_val = subs.to_tag;
210 n_query_cols++;
211
212 query_cols[n_query_cols] = &str_from_tag_col;
213 query_vals[n_query_cols].type = DB1_STR;
214 query_vals[n_query_cols].nul = 0;
215 query_vals[n_query_cols].val.str_val = subs.from_tag;
216 n_query_cols++;
217
218 update_cols[0] = &str_updated_col;
219 update_vals[0].type = DB1_INT;
220 update_vals[0].nul = 0;
221 update_vals[0].val.int_val = subs.updated;
222
223 if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
224 update_cols,update_vals,n_query_cols, 1) < 0)
225 {
226 LM_ERR("db update failed for expired subs\n");
227 goto error;
228 }
229
230 pkg_free(rlsubs_did.s);
231 rlsubs_did.s = NULL;
232 }
233
234 rls_dbf.free_result(rls_db, result);
235 result = NULL;
236
237 if (rls_dbf.end_transaction)
238 {
239 if (rls_dbf.end_transaction(rls_db) < 0)
240 {
241 LM_ERR("in end_transaction\n");
242 goto error;
243 }
244 }
245
246 return 1;
247
248 error:
249 if (result) rls_dbf.free_result(rls_db, result);
250 if (rlsubs_did.s) pkg_free(rlsubs_did.s);
251
252 if (rls_dbf.abort_transaction)
253 {
254 if (rls_dbf.abort_transaction(rls_db) < 0)
255 LM_ERR("in abort_transaction\n");
256 }
257
258 return -1;
259 }
260
261 /******************************************************************************/
262
delete_rlsdb(str * callid,str * to_tag,str * from_tag)263 int delete_rlsdb( str *callid, str *to_tag, str *from_tag )
264
265 {
266 int rval;
267 db_key_t query_cols[3];
268 db_val_t query_vals[3];
269 int n_query_cols = 0;
270
271 if(rls_db == NULL)
272 {
273 LM_ERR("null database connection\n");
274 return(-1);
275 }
276
277 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
278 {
279 LM_ERR("use table failed\n");
280 return(-1);
281 }
282
283 query_cols[n_query_cols] = &str_callid_col;
284 query_vals[n_query_cols].type = DB1_STR;
285 query_vals[n_query_cols].nul = 0;
286 query_vals[n_query_cols].val.str_val= *callid;
287 n_query_cols++;
288
289 query_cols[n_query_cols] = &str_to_tag_col;
290 query_vals[n_query_cols].type = DB1_STR;
291 query_vals[n_query_cols].nul = 0;
292 query_vals[n_query_cols].val.str_val= *to_tag;
293 n_query_cols++;
294
295 if (from_tag)
296 {
297 query_cols[n_query_cols] = &str_from_tag_col;
298 query_vals[n_query_cols].type = DB1_STR;
299 query_vals[n_query_cols].nul = 0;
300 query_vals[n_query_cols].val.str_val= *from_tag;
301 n_query_cols++;
302 }
303
304 rval = rls_dbf.delete(rls_db, query_cols, 0, query_vals, n_query_cols);
305
306 if (rval < 0)
307 {
308 LM_ERR("Can't delete in db\n");
309 return(-1);
310 }
311
312 return(1);
313 }
314
315 /******************************************************************************/
316
update_dialog_notify_rlsdb(subs_t * subs)317 int update_dialog_notify_rlsdb(subs_t *subs)
318
319 {
320 db_key_t query_cols[3];
321 db_val_t query_vals[3];
322 db_key_t data_cols[3];
323 db_val_t data_vals[3];
324 int n_query_cols = 0, n_data_cols=0;
325
326 if (subs==NULL) return(-1);
327
328 if(rls_db == NULL)
329 {
330 LM_ERR("null database connection\n");
331 return(-1);
332 }
333
334 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
335 {
336 LM_ERR("use table failed\n");
337 return(-1);
338 }
339
340 subs->local_cseq++;
341 subs->version++;
342
343 query_cols[n_query_cols] = &str_callid_col;
344 query_vals[n_query_cols].type = DB1_STR;
345 query_vals[n_query_cols].nul = 0;
346 query_vals[n_query_cols].val.str_val= subs->callid;
347 n_query_cols++;
348
349 query_cols[n_query_cols] = &str_to_tag_col;
350 query_vals[n_query_cols].type = DB1_STR;
351 query_vals[n_query_cols].nul = 0;
352 query_vals[n_query_cols].val.str_val= subs->to_tag;
353 n_query_cols++;
354
355 query_cols[n_query_cols] = &str_from_tag_col;
356 query_vals[n_query_cols].type = DB1_STR;
357 query_vals[n_query_cols].nul = 0;
358 query_vals[n_query_cols].val.str_val= subs->from_tag;
359 n_query_cols++;
360
361 data_cols[n_data_cols]=&str_local_cseq_col;
362 data_vals[n_data_cols].type = DB1_INT;
363 data_vals[n_data_cols].nul = 0;
364 data_vals[n_data_cols].val.int_val= subs->local_cseq;
365 n_data_cols++;
366
367 data_cols[n_data_cols]=&str_version_col;
368 data_vals[n_data_cols].type = DB1_INT;
369 data_vals[n_data_cols].nul = 0;
370 data_vals[n_data_cols].val.int_val= subs->version;
371 n_data_cols++;
372
373 data_cols[n_data_cols] =&str_status_col;
374 data_vals[n_data_cols].type = DB1_INT;
375 data_vals[n_data_cols].nul = 0;
376 data_vals[n_data_cols].val.int_val= subs->status;
377 n_data_cols++;
378
379 if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
380 data_cols,data_vals,n_query_cols,n_data_cols) < 0)
381 {
382 LM_ERR("Failed update db\n");
383 return(-1);
384 }
385
386 return(0);
387 }
388
389 /******************************************************************************/
390
update_all_subs_rlsdb(str * watcher_user,str * watcher_domain,str * evt)391 int update_all_subs_rlsdb(str *watcher_user, str *watcher_domain, str *evt)
392 {
393 db_key_t query_cols[3];
394 db_val_t query_vals[3];
395 db_key_t result_cols[20];
396 int n_query_cols = 0, n_result_cols=0;
397 int r_pres_uri_col, r_callid_col, r_to_tag_col, r_from_tag_col;
398 int r_event_col, r_expires_col;
399 db1_res_t *result= NULL;
400 db_val_t *values;
401 db_row_t *rows;
402 int nr_rows, size, loop;
403 subs_t *dest;
404 event_t parsed_event;
405
406 if(rls_db == NULL)
407 {
408 LM_ERR("null database connection\n");
409 return(-1);
410 }
411
412 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
413 {
414 LM_ERR("use table failed\n");
415 return(-1);
416 }
417
418 query_cols[n_query_cols] = &str_watcher_username_col;
419 query_vals[n_query_cols].type = DB1_STR;
420 query_vals[n_query_cols].nul = 0;
421 query_vals[n_query_cols].val.str_val= *watcher_user;
422 n_query_cols++;
423
424 query_cols[n_query_cols] = &str_watcher_domain_col;
425 query_vals[n_query_cols].type = DB1_STR;
426 query_vals[n_query_cols].nul = 0;
427 query_vals[n_query_cols].val.str_val= *watcher_domain;
428 n_query_cols++;
429
430 query_cols[n_query_cols] = &str_event_col;
431 query_vals[n_query_cols].type = DB1_STR;
432 query_vals[n_query_cols].nul = 0;
433 query_vals[n_query_cols].val.str_val= *evt;
434 n_query_cols++;
435
436 result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
437 result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
438 result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
439 result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
440 result_cols[r_event_col=n_result_cols++] = &str_event_col;
441 result_cols[r_expires_col=n_result_cols++] = &str_expires_col;
442
443 if(rls_dbf.query(rls_db, query_cols, 0, query_vals, result_cols,
444 n_query_cols, n_result_cols, 0, &result )< 0)
445 {
446 LM_ERR("Can't query db\n");
447 if(result) rls_dbf.free_result(rls_db, result);
448 return(-1);
449 }
450
451 if(result == NULL) return(-1);
452
453 nr_rows = RES_ROW_N(result);
454
455 rows = RES_ROWS(result);
456 /* get the results and fill in return data structure */
457 for (loop=0; loop <nr_rows; loop++)
458 {
459 values = ROW_VALUES(&rows[loop]);
460
461 size= sizeof(subs_t) +
462 ( strlen(VAL_STRING(values+r_pres_uri_col))
463 + strlen(VAL_STRING(values+r_to_tag_col))
464 + strlen(VAL_STRING(values+r_from_tag_col))
465 + strlen(VAL_STRING(values+r_callid_col)))*sizeof(char);
466
467 dest= (subs_t*)pkg_malloc(size);
468
469 if(dest== NULL)
470 {
471 LM_ERR( "Can't allocate memory\n" );
472 rls_dbf.free_result(rls_db, result);
473 return(-1);
474 }
475 memset(dest, 0, size);
476 size= sizeof(subs_t);
477
478 CONT_COPYDB(dest, dest->pres_uri, VAL_STRING(values+r_pres_uri_col));
479 CONT_COPYDB(dest, dest->to_tag, VAL_STRING(values+r_to_tag_col));
480 CONT_COPYDB(dest, dest->from_tag, VAL_STRING(values+r_from_tag_col));
481 CONT_COPYDB(dest, dest->callid, VAL_STRING(values+r_callid_col));
482
483 dest->event = pres_contains_event(evt, &parsed_event);
484 if(dest->event == NULL)
485 {
486 LM_ERR("event not found and set to NULL\n");
487 }
488
489 dest->expires= VAL_INT(values+r_expires_col);
490 dest->watcher_user.s= watcher_user->s;
491 dest->watcher_user.len= watcher_user->len;
492 dest->watcher_domain.s= watcher_domain->s;
493 dest->watcher_domain.len= watcher_domain->len;
494
495 update_a_sub(dest);
496 }
497
498 rls_dbf.free_result(rls_db, result);
499 return(1);
500 }
501
502 /******************************************************************************/
503
update_dialog_subscribe_rlsdb(subs_t * subs)504 int update_dialog_subscribe_rlsdb(subs_t *subs)
505
506 {
507 db_key_t query_cols[3];
508 db_val_t query_vals[3];
509 db_key_t data_cols[3];
510 db_val_t data_vals[3];
511 int n_query_cols = 0, n_data_cols=0;
512
513 if (subs==NULL) return(-1);
514
515 if(rls_db == NULL)
516 {
517 LM_ERR("null database connection\n");
518 return(-1);
519 }
520
521 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
522 {
523 LM_ERR("use table failed\n");
524 return(-1);
525 }
526
527 query_cols[n_query_cols] = &str_callid_col;
528 query_vals[n_query_cols].type = DB1_STR;
529 query_vals[n_query_cols].nul = 0;
530 query_vals[n_query_cols].val.str_val= subs->callid;
531 n_query_cols++;
532
533 query_cols[n_query_cols] = &str_to_tag_col;
534 query_vals[n_query_cols].type = DB1_STR;
535 query_vals[n_query_cols].nul = 0;
536 query_vals[n_query_cols].val.str_val= subs->to_tag;
537 n_query_cols++;
538
539 query_cols[n_query_cols] = &str_from_tag_col;
540 query_vals[n_query_cols].type = DB1_STR;
541 query_vals[n_query_cols].nul = 0;
542 query_vals[n_query_cols].val.str_val= subs->from_tag;
543 n_query_cols++;
544
545 data_cols[n_data_cols] = &str_expires_col;
546 data_vals[n_data_cols].type = DB1_INT;
547 data_vals[n_data_cols].nul = 0;
548 data_vals[n_data_cols].val.int_val = subs->expires + (int)time(NULL);
549 n_data_cols++;
550
551 data_cols[n_data_cols] = &str_remote_cseq_col;
552 data_vals[n_data_cols].type = DB1_INT;
553 data_vals[n_data_cols].nul = 0;
554 data_vals[n_data_cols].val.int_val= subs->remote_cseq;
555 n_data_cols++;
556
557 data_cols[n_data_cols] = &str_updated_col;
558 data_vals[n_data_cols].type = DB1_INT;
559 data_vals[n_data_cols].nul = 0;
560 data_vals[n_data_cols].val.int_val= subs->updated;
561 n_data_cols++;
562
563 if(rls_dbf.update(rls_db, query_cols, 0, query_vals,
564 data_cols,data_vals,n_query_cols,n_data_cols) < 0)
565 {
566 LM_ERR("Failed update db\n");
567 return(-1);
568 }
569
570 return(0);
571 }
572
573 /******************************************************************************/
574
insert_rlsdb(subs_t * s)575 int insert_rlsdb( subs_t *s )
576
577 {
578 db_key_t data_cols[23];
579 db_val_t data_vals[23];
580 int n_data_cols = 0;
581
582 if (s==NULL) return(-1);
583
584 if(rls_db == NULL)
585 {
586 LM_ERR("null database connection\n");
587 return(-1);
588 }
589
590 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
591 {
592 LM_ERR("use table failed\n");
593 return(-1);
594 }
595
596 data_cols[n_data_cols] = &str_presentity_uri_col;
597 data_vals[n_data_cols].type = DB1_STR;
598 data_vals[n_data_cols].nul = 0;
599 data_vals[n_data_cols].val.str_val= s->pres_uri;
600 n_data_cols++;
601
602 data_cols[n_data_cols] = &str_callid_col;
603 data_vals[n_data_cols].type = DB1_STR;
604 data_vals[n_data_cols].nul = 0;
605 data_vals[n_data_cols].val.str_val= s->callid;
606 n_data_cols++;
607
608 data_cols[n_data_cols] = &str_to_tag_col;
609 data_vals[n_data_cols].type = DB1_STR;
610 data_vals[n_data_cols].nul = 0;
611 data_vals[n_data_cols].val.str_val= s->to_tag;
612 n_data_cols++;
613
614 data_cols[n_data_cols] = &str_from_tag_col;
615 data_vals[n_data_cols].type = DB1_STR;
616 data_vals[n_data_cols].nul = 0;
617 data_vals[n_data_cols].val.str_val= s->from_tag;
618 n_data_cols++;
619
620 data_cols[n_data_cols] = &str_to_user_col;
621 data_vals[n_data_cols].type = DB1_STR;
622 data_vals[n_data_cols].nul = 0;
623 data_vals[n_data_cols].val.str_val = s->to_user;
624 n_data_cols++;
625
626 data_cols[n_data_cols] = &str_to_domain_col;
627 data_vals[n_data_cols].type = DB1_STR;
628 data_vals[n_data_cols].nul = 0;
629 data_vals[n_data_cols].val.str_val = s->to_domain;
630 n_data_cols++;
631
632 data_cols[n_data_cols] = &str_from_user_col;
633 data_vals[n_data_cols].type = DB1_STR;
634 data_vals[n_data_cols].nul = 0;
635 data_vals[n_data_cols].val.str_val = s->from_user;
636 n_data_cols++;
637
638 data_cols[n_data_cols] = &str_from_domain_col;
639 data_vals[n_data_cols].type = DB1_STR;
640 data_vals[n_data_cols].nul = 0;
641 data_vals[n_data_cols].val.str_val = s->from_domain;
642 n_data_cols++;
643
644 data_cols[n_data_cols] = &str_watcher_username_col;
645 data_vals[n_data_cols].type = DB1_STR;
646 data_vals[n_data_cols].nul = 0;
647 data_vals[n_data_cols].val.str_val = s->watcher_user;
648 n_data_cols++;
649
650 data_cols[n_data_cols] = &str_watcher_domain_col;
651 data_vals[n_data_cols].type = DB1_STR;
652 data_vals[n_data_cols].nul = 0;
653 data_vals[n_data_cols].val.str_val = s->watcher_domain;
654 n_data_cols++;
655
656 data_cols[n_data_cols] = &str_event_col;
657 data_vals[n_data_cols].type = DB1_STR;
658 data_vals[n_data_cols].nul = 0;
659 data_vals[n_data_cols].val.str_val = s->event->name;
660 n_data_cols++;
661
662 data_cols[n_data_cols] = &str_event_id_col;
663 data_vals[n_data_cols].type = DB1_STR;
664 data_vals[n_data_cols].nul = 0;
665 data_vals[n_data_cols].val.str_val = s->event_id;
666 n_data_cols++;
667
668 data_cols[n_data_cols]=&str_local_cseq_col;
669 data_vals[n_data_cols].type = DB1_INT;
670 data_vals[n_data_cols].nul = 0;
671 data_vals[n_data_cols].val.int_val= s->local_cseq;
672 n_data_cols++;
673
674 data_cols[n_data_cols]=&str_remote_cseq_col;
675 data_vals[n_data_cols].type = DB1_INT;
676 data_vals[n_data_cols].nul = 0;
677 data_vals[n_data_cols].val.int_val= s->remote_cseq;
678 n_data_cols++;
679
680 data_cols[n_data_cols] =&str_expires_col;
681 data_vals[n_data_cols].type = DB1_INT;
682 data_vals[n_data_cols].nul = 0;
683 data_vals[n_data_cols].val.int_val = s->expires + (int)time(NULL);
684 n_data_cols++;
685
686 data_cols[n_data_cols] =&str_status_col;
687 data_vals[n_data_cols].type = DB1_INT;
688 data_vals[n_data_cols].nul = 0;
689 data_vals[n_data_cols].val.int_val= s->status;
690 n_data_cols++;
691
692 data_cols[n_data_cols] =&str_reason_col;
693 data_vals[n_data_cols].type = DB1_STR;
694 data_vals[n_data_cols].nul = 0;
695 data_vals[n_data_cols].val.str_val= s->reason;
696 n_data_cols++;
697
698 data_cols[n_data_cols] =&str_record_route_col;
699 data_vals[n_data_cols].type = DB1_STR;
700 data_vals[n_data_cols].nul = 0;
701 data_vals[n_data_cols].val.str_val = s->record_route;
702 n_data_cols++;
703
704 data_cols[n_data_cols] =&str_contact_col;
705 data_vals[n_data_cols].type = DB1_STR;
706 data_vals[n_data_cols].nul = 0;
707 data_vals[n_data_cols].val.str_val = s->contact;
708 n_data_cols++;
709
710 data_cols[n_data_cols] =&str_local_contact_col;
711 data_vals[n_data_cols].type = DB1_STR;
712 data_vals[n_data_cols].nul = 0;
713 data_vals[n_data_cols].val.str_val = s->local_contact;
714 n_data_cols++;
715
716 data_cols[n_data_cols] =&str_socket_info_col;
717 data_vals[n_data_cols].type = DB1_STR;
718 data_vals[n_data_cols].nul = 0;
719 data_vals[n_data_cols].val.str_val= s->sockinfo_str;
720 n_data_cols++;
721
722 data_cols[n_data_cols]=&str_version_col;
723 data_vals[n_data_cols].type = DB1_INT;
724 data_vals[n_data_cols].nul = 0;
725 data_vals[n_data_cols].val.int_val= s->version;
726 n_data_cols++;
727
728 data_cols[n_data_cols]=&str_updated_col;
729 data_vals[n_data_cols].type = DB1_INT;
730 data_vals[n_data_cols].nul = 0;
731 data_vals[n_data_cols].val.int_val= s->updated;
732 n_data_cols++;
733
734 if(rls_dbf.insert(rls_db, data_cols, data_vals, n_data_cols) < 0)
735 {
736 LM_ERR("db insert failed\n");
737 return(-1);
738 }
739
740 return(0);
741 }
742
743 /******************************************************************************/
744
get_dialog_subscribe_rlsdb(subs_t * subs)745 int get_dialog_subscribe_rlsdb(subs_t *subs)
746
747 {
748 db1_res_t *result= NULL;
749 db_key_t query_cols[3];
750 db_val_t query_vals[3], *values;
751 db_key_t result_cols[5];
752 db_row_t *rows;
753 int n_query_cols = 0, n_result_cols = 0;
754 int pres_uri_col, rcseq_col, lcseq_col, version_col, rroute_col;
755 int nr_rows;
756 int r_remote_cseq, r_local_cseq, r_version;
757 char *r_pres_uri, *r_record_route;
758 db_query_f query_fn = rls_dbf.query_lock ? rls_dbf.query_lock : rls_dbf.query;
759
760 if(rls_db == NULL)
761 {
762 LM_ERR("null database connection\n");
763 return(-1);
764 }
765
766 if (subs == NULL)
767 {
768 LM_ERR("null subscriptions\n");
769 return(-1);
770 }
771
772 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
773 {
774 LM_ERR("use table failed\n");
775 return(-1);
776 }
777
778 query_cols[n_query_cols] = &str_callid_col;
779 query_vals[n_query_cols].type = DB1_STR;
780 query_vals[n_query_cols].nul = 0;
781 query_vals[n_query_cols].val.str_val= subs->callid;
782 n_query_cols++;
783
784 query_cols[n_query_cols] = &str_to_tag_col;
785 query_vals[n_query_cols].type = DB1_STR;
786 query_vals[n_query_cols].nul = 0;
787 query_vals[n_query_cols].val.str_val= subs->to_tag;
788 n_query_cols++;
789
790 query_cols[n_query_cols] = &str_from_tag_col;
791 query_vals[n_query_cols].type = DB1_STR;
792 query_vals[n_query_cols].nul = 0;
793 query_vals[n_query_cols].val.str_val= subs->from_tag;
794 n_query_cols++;
795
796 result_cols[pres_uri_col = n_result_cols++] = &str_presentity_uri_col;
797 result_cols[rcseq_col = n_result_cols++] = &str_remote_cseq_col;
798 result_cols[lcseq_col = n_result_cols++] = &str_local_cseq_col;
799 result_cols[version_col = n_result_cols++] = &str_version_col;
800 result_cols[rroute_col = n_result_cols++] = &str_record_route_col;
801
802 if(query_fn(rls_db, query_cols, 0, query_vals, result_cols,
803 n_query_cols, n_result_cols, 0, &result )< 0)
804 {
805 LM_ERR("Can't query db\n");
806 if(result) rls_dbf.free_result(rls_db, result);
807 return(-1);
808 }
809
810 if(result == NULL) return(-1);
811
812 nr_rows = RES_ROW_N(result);
813
814 if (nr_rows == 0)
815 {
816 /* no match - this error might not be for RLS */
817 LM_INFO( "update_subs_rlsdb: NO MATCH\n" );
818 rls_dbf.free_result(rls_db, result);
819 return(-1);
820 }
821
822 if (nr_rows != 1)
823 {
824 LM_ERR( "update_subs_rlsdb: TOO MANY MATCHES=%d\n", nr_rows);
825 rls_dbf.free_result(rls_db, result);
826 return(-1);
827 }
828
829 /* get the results and fill in return data structure */
830 rows = RES_ROWS(result);
831 values = ROW_VALUES(rows);
832
833 r_pres_uri = (char *)VAL_STRING(&values[pres_uri_col]);
834 r_remote_cseq = VAL_INT(&values[rcseq_col]);
835 r_local_cseq = VAL_INT(&values[lcseq_col]);
836 r_version = VAL_INT(&values[version_col]);
837 r_record_route = (char *)VAL_STRING(&values[rroute_col]);
838
839 if ( r_remote_cseq >= subs->remote_cseq)
840 {
841 LM_DBG("stored cseq= %d\n", r_remote_cseq);
842 rls_dbf.free_result(rls_db, result);
843 return(401); /*stale cseq code */
844 }
845
846 if(strlen(r_pres_uri) > 0)
847 {
848 subs->pres_uri.s =
849 (char*)pkg_malloc(strlen(r_pres_uri) * sizeof(char));
850 if(subs->pres_uri.s==NULL)
851 {
852 LM_ERR( "Out of Memory\n" );
853 rls_dbf.free_result(rls_db, result);
854 return(-1);
855 }
856 memcpy(subs->pres_uri.s,
857 r_pres_uri, strlen(r_pres_uri));
858 subs->pres_uri.len= strlen(r_pres_uri);
859 }
860
861 if(strlen(r_record_route) > 0)
862 {
863 subs->record_route.s =
864 (char*)pkg_malloc(strlen(r_record_route) * sizeof(char));
865 if(subs->record_route.s==NULL)
866 {
867 LM_ERR( "Out of Memory\n" );
868 rls_dbf.free_result(rls_db, result);
869 return(-1);
870 }
871 memcpy(subs->record_route.s,
872 r_record_route, strlen(r_record_route));
873 subs->record_route.len= strlen(r_record_route);
874 }
875
876 subs->local_cseq= r_local_cseq;
877 subs->version= r_version;
878
879 rls_dbf.free_result(rls_db, result);
880 return 1;
881 }
882
883 /******************************************************************************/
884
get_dialog_notify_rlsdb(str callid,str to_tag,str from_tag)885 subs_t *get_dialog_notify_rlsdb(str callid, str to_tag, str from_tag)
886 {
887 db_key_t query_cols[4];
888 db_val_t query_vals[4];
889 db_key_t result_cols[22];
890 int n_query_cols = 0, n_result_cols=0;
891 int r_pres_uri_col,r_to_user_col,r_to_domain_col;
892 int r_from_user_col,r_from_domain_col,r_callid_col;
893 int r_to_tag_col,r_from_tag_col,r_socket_info_col;
894 int r_event_id_col,r_local_contact_col,r_contact_col;
895 int r_record_route_col, r_reason_col, r_event_col;
896 int r_local_cseq_col, r_remote_cseq_col, r_status_col;
897 int r_version_col, r_watcher_user_col, r_watcher_domain_col;
898 int r_expires_col;
899 db1_res_t *result= NULL;
900 db_val_t *values;
901 db_row_t *rows;
902 int nr_rows, size;
903 subs_t *dest;
904 event_t parsed_event;
905 str ev_sname;
906 db_query_f query_fn = rls_dbf.query_lock ? rls_dbf.query_lock : rls_dbf.query;
907
908 if(rls_db == NULL)
909 {
910 LM_ERR("null database connection\n");
911 return(NULL);
912 }
913
914 if(rls_dbf.use_table(rls_db, &rlsubs_table)< 0)
915 {
916 LM_ERR("use table failed\n");
917 return(NULL);
918 }
919
920 query_cols[n_query_cols] = &str_callid_col;
921 query_vals[n_query_cols].type = DB1_STR;
922 query_vals[n_query_cols].nul = 0;
923 query_vals[n_query_cols].val.str_val= callid;
924 n_query_cols++;
925
926 query_cols[n_query_cols] = &str_to_tag_col;
927 query_vals[n_query_cols].type = DB1_STR;
928 query_vals[n_query_cols].nul = 0;
929 query_vals[n_query_cols].val.str_val= to_tag;
930 n_query_cols++;
931
932 query_cols[n_query_cols] = &str_from_tag_col;
933 query_vals[n_query_cols].type = DB1_STR;
934 query_vals[n_query_cols].nul = 0;
935 query_vals[n_query_cols].val.str_val= from_tag;
936 n_query_cols++;
937
938 query_cols[n_query_cols] = &str_updated_col;
939 query_vals[n_query_cols].type = DB1_INT;
940 query_vals[n_query_cols].nul = 0;
941 query_vals[n_query_cols].val.int_val= NO_UPDATE_TYPE;
942 n_query_cols++;
943
944 result_cols[r_pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
945 result_cols[r_to_user_col=n_result_cols++] = &str_to_user_col;
946 result_cols[r_to_domain_col=n_result_cols++] = &str_to_domain_col;
947 result_cols[r_from_user_col=n_result_cols++] = &str_from_user_col;
948 result_cols[r_from_domain_col=n_result_cols++] = &str_from_domain_col;
949 result_cols[r_watcher_user_col=n_result_cols++] = &str_watcher_username_col;
950 result_cols[r_watcher_domain_col=n_result_cols++] = &str_watcher_domain_col;
951 result_cols[r_callid_col=n_result_cols++] = &str_callid_col;
952 result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
953 result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
954 result_cols[r_socket_info_col=n_result_cols++] = &str_socket_info_col;
955 result_cols[r_event_id_col=n_result_cols++] = &str_event_id_col;
956 result_cols[r_local_contact_col=n_result_cols++] = &str_local_contact_col;
957 result_cols[r_contact_col=n_result_cols++] = &str_contact_col;
958 result_cols[r_record_route_col=n_result_cols++] = &str_record_route_col;
959 result_cols[r_reason_col=n_result_cols++] = &str_reason_col;
960 result_cols[r_event_col=n_result_cols++] = &str_event_col;
961 result_cols[r_local_cseq_col=n_result_cols++] = &str_local_cseq_col;
962 result_cols[r_remote_cseq_col=n_result_cols++] = &str_remote_cseq_col;
963 result_cols[r_status_col=n_result_cols++] = &str_status_col;
964 result_cols[r_version_col=n_result_cols++] = &str_version_col;
965 result_cols[r_expires_col=n_result_cols++] = &str_expires_col;
966
967 if(query_fn(rls_db, query_cols, 0, query_vals, result_cols,
968 n_query_cols, n_result_cols, 0, &result )< 0)
969 {
970 LM_ERR("Can't query db\n");
971 if(result) rls_dbf.free_result(rls_db, result);
972 return(NULL);
973 }
974
975 if(result == NULL) return(NULL);
976
977 nr_rows = RES_ROW_N(result);
978
979 if (nr_rows == 0)
980 {
981 /* no match */
982 LM_INFO( "get_dialog_rlsdb No matching records\n" );
983 rls_dbf.free_result(rls_db, result);
984 return(NULL);
985 }
986
987 if (nr_rows != 1)
988 {
989 LM_ERR( "get_dialog_rlsdb multiple matching records\n" );
990 rls_dbf.free_result(rls_db, result);
991 return(NULL);
992 }
993
994 /* get the results and fill in return data structure */
995 rows = RES_ROWS(result);
996 values = ROW_VALUES(rows);
997
998 size= sizeof(subs_t) +
999 ( strlen(VAL_STRING(values+r_pres_uri_col))
1000 + strlen(VAL_STRING(values+r_to_user_col))
1001 + strlen(VAL_STRING(values+r_to_domain_col))
1002 + strlen(VAL_STRING(values+r_from_user_col))
1003 + strlen(VAL_STRING(values+r_from_domain_col))
1004 + strlen(VAL_STRING(values+r_watcher_user_col))
1005 + strlen(VAL_STRING(values+r_watcher_domain_col))
1006 + strlen(VAL_STRING(values+r_to_tag_col))
1007 + strlen(VAL_STRING(values+r_from_tag_col))
1008 + strlen(VAL_STRING(values+r_callid_col))
1009 + strlen(VAL_STRING(values+r_socket_info_col))
1010 + strlen(VAL_STRING(values+r_local_contact_col))
1011 + strlen(VAL_STRING(values+r_contact_col))
1012 + strlen(VAL_STRING(values+r_record_route_col))
1013 + strlen(VAL_STRING(values+r_event_id_col))
1014 + strlen(VAL_STRING(values+r_reason_col)))*sizeof(char);
1015
1016 dest= (subs_t*)pkg_malloc(size);
1017
1018 if(dest== NULL)
1019 {
1020 LM_ERR( "Can't allocate memory\n" );
1021 rls_dbf.free_result(rls_db, result);
1022 return(NULL);
1023 }
1024 memset(dest, 0, size);
1025 size= sizeof(subs_t);
1026
1027 CONT_COPYDB(dest, dest->pres_uri, VAL_STRING(values+r_pres_uri_col));
1028 CONT_COPYDB(dest, dest->to_user, VAL_STRING(values+r_to_user_col));
1029 CONT_COPYDB(dest, dest->to_domain, VAL_STRING(values+r_to_domain_col));
1030 CONT_COPYDB(dest, dest->from_user, VAL_STRING(values+r_from_user_col));
1031 CONT_COPYDB(dest, dest->from_domain, VAL_STRING(values+r_from_domain_col));
1032 CONT_COPYDB(dest, dest->watcher_user, VAL_STRING(values+r_watcher_user_col));
1033 CONT_COPYDB(dest, dest->watcher_domain, VAL_STRING(values+r_watcher_domain_col));
1034 CONT_COPYDB(dest, dest->to_tag, VAL_STRING(values+r_to_tag_col));
1035 CONT_COPYDB(dest, dest->from_tag, VAL_STRING(values+r_from_tag_col));
1036 CONT_COPYDB(dest, dest->callid, VAL_STRING(values+r_callid_col));
1037 CONT_COPYDB(dest, dest->sockinfo_str, VAL_STRING(values+r_socket_info_col));
1038 CONT_COPYDB(dest, dest->local_contact, VAL_STRING(values+r_local_contact_col));
1039 CONT_COPYDB(dest, dest->contact, VAL_STRING(values+r_contact_col));
1040 CONT_COPYDB(dest, dest->record_route, VAL_STRING(values+r_record_route_col));
1041
1042 if(strlen(VAL_STRING(values+r_event_id_col)) > 0)
1043 CONT_COPYDB(dest, dest->event_id, VAL_STRING(values+r_event_id_col));
1044
1045 if(strlen(VAL_STRING(values+r_reason_col)) > 0)
1046 CONT_COPYDB(dest, dest->reason, VAL_STRING(values+r_reason_col));
1047
1048 ev_sname.s= (char *)VAL_STRING(values+r_event_col);
1049 ev_sname.len= strlen(ev_sname.s);
1050
1051 dest->event = pres_contains_event(&ev_sname, &parsed_event);
1052
1053 if(dest->event == NULL)
1054 LM_ERR("event not found and set to NULL\n");
1055
1056 dest->local_cseq= VAL_INT(values+r_local_cseq_col);
1057 dest->remote_cseq= VAL_INT(values+r_remote_cseq_col);
1058 dest->status= VAL_INT(values+r_status_col);
1059 dest->version= VAL_INT(values+r_version_col);
1060 dest->expires= VAL_INT(values+r_expires_col);
1061
1062 rls_dbf.free_result(rls_db, result);
1063
1064 return(dest);
1065 }
1066
1067 /******************************************************************************/
1068
1069