00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "../../ut.h"
00036 #include "../../usr_avp.h"
00037 #include "../../data_lump_rpl.h"
00038 #include "../../parser/parse_expires.h"
00039 #include "../../parser/parse_event.h"
00040 #include "../../parser/contact/parse_contact.h"
00041 #include "presence.h"
00042 #include "subscribe.h"
00043 #include "utils_func.h"
00044 #include "notify.h"
00045 #include "../pua/hash.h"
00046
00047 int get_stored_info(struct sip_msg* msg, subs_t* subs, int* error_ret,
00048 str* reply_str);
00049 int get_database_info(struct sip_msg* msg, subs_t* subs, int* error_ret,
00050 str* reply_str);
00051 int get_db_subs_auth(subs_t* subs, int* found);
00052 int insert_db_subs_auth(subs_t* subs);
00053
00054 static str su_200_rpl = str_init("OK");
00055 static str pu_481_rpl = str_init("Subscription does not exist");
00056 static str pu_400_rpl = str_init("Bad request");
00057 static str pu_500_rpl = str_init("Server Internal Error");
00058 static str pu_489_rpl = str_init("Bad Event");
00059
00060
00061 int send_2XX_reply(struct sip_msg * msg, int reply_code, int lexpire,
00062 str* local_contact)
00063 {
00064 str hdr_append = {0, 0};
00065 str tmp;
00066 char *t = NULL;
00067
00068 tmp.s = int2str((unsigned long)lexpire, &tmp.len);
00069 hdr_append.len = 9 + tmp.len + CRLF_LEN
00070 + 10 + local_contact->len + 16 + CRLF_LEN;
00071 hdr_append.s = (char *)pkg_malloc(sizeof(char)*(hdr_append.len+1));
00072 if(hdr_append.s == NULL)
00073 {
00074 ERR_MEM(PKG_MEM_STR);
00075 }
00076 strncpy(hdr_append.s, "Expires: ", 9);
00077 strncpy(hdr_append.s+9, tmp.s, tmp.len);
00078 tmp.s = hdr_append.s+9+tmp.len;
00079 strncpy(tmp.s, CRLF, CRLF_LEN);
00080 tmp.s += CRLF_LEN;
00081 strncpy(tmp.s, "Contact: <", 10);
00082 tmp.s += 10;
00083 strncpy(tmp.s, local_contact->s, local_contact->len);
00084 tmp.s[local_contact->len] = '\0';
00085 t = strstr(tmp.s, ";transport=");
00086 tmp.s += local_contact->len;
00087 if(t==NULL)
00088 {
00089 switch (msg->rcv.proto)
00090 {
00091 case PROTO_TCP:
00092 strncpy(tmp.s, ";transport=tcp", 14);
00093 tmp.s += 14;
00094 hdr_append.len -= 1;
00095 break;
00096 case PROTO_TLS:
00097 strncpy(tmp.s, ";transport=tls", 14);
00098 tmp.s += 14;
00099 hdr_append.len -= 1;
00100 break;
00101 case PROTO_SCTP:
00102 strncpy(tmp.s, ";transport=sctp", 15);
00103 tmp.s += 15;
00104 break;
00105 default:
00106 hdr_append.len -= 15;
00107 }
00108 } else {
00109 hdr_append.len -= 15;
00110 }
00111 *tmp.s = '>';
00112 strncpy(tmp.s+1, CRLF, CRLF_LEN);
00113
00114 hdr_append.s[hdr_append.len]= '\0';
00115
00116 if (add_lump_rpl( msg, hdr_append.s, hdr_append.len, LUMP_RPL_HDR)==0 )
00117 {
00118 LM_ERR("unable to add lump_rl\n");
00119 goto error;
00120 }
00121
00122 if( slb.send_reply(msg, reply_code, &su_200_rpl)== -1)
00123 {
00124 LM_ERR("sending reply\n");
00125 goto error;
00126 }
00127
00128 pkg_free(hdr_append.s);
00129 return 0;
00130
00131 error:
00132
00133 if(hdr_append.s!=NULL)
00134 pkg_free(hdr_append.s);
00135 return -1;
00136 }
00137
00138
00139 int delete_db_subs(str pres_uri, str ev_stored_name, str to_tag)
00140 {
00141 db_key_t query_cols[5];
00142 db_val_t query_vals[5];
00143 int n_query_cols= 0;
00144
00145 query_cols[n_query_cols] = &str_presentity_uri_col;
00146 query_vals[n_query_cols].type = DB_STR;
00147 query_vals[n_query_cols].nul = 0;
00148 query_vals[n_query_cols].val.str_val = pres_uri;
00149 n_query_cols++;
00150
00151 query_cols[n_query_cols] = &str_event_col;
00152 query_vals[n_query_cols].type = DB_STR;
00153 query_vals[n_query_cols].nul = 0;
00154 query_vals[n_query_cols].val.str_val = ev_stored_name;
00155 n_query_cols++;
00156
00157 query_cols[n_query_cols] = &str_to_tag_col;
00158 query_vals[n_query_cols].type = DB_STR;
00159 query_vals[n_query_cols].nul = 0;
00160 query_vals[n_query_cols].val.str_val = to_tag;
00161 n_query_cols++;
00162
00163 if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0)
00164 {
00165 LM_ERR("in use table sql operation\n");
00166 return -1;
00167 }
00168
00169 if(pa_dbf.delete(pa_db, query_cols, 0, query_vals,
00170 n_query_cols)< 0 )
00171 {
00172 LM_ERR("sql delete failed\n");
00173 return -1;
00174 }
00175
00176 return 0;
00177 }
00178
00179 int update_subs_db(subs_t* subs, int type)
00180 {
00181 db_key_t query_cols[22], update_keys[7];
00182 db_val_t query_vals[22], update_vals[7];
00183 int n_update_cols= 0;
00184 int n_query_cols = 0;
00185
00186 query_cols[n_query_cols] = &str_presentity_uri_col;
00187 query_vals[n_query_cols].type = DB_STR;
00188 query_vals[n_query_cols].nul = 0;
00189 query_vals[n_query_cols].val.str_val = subs->pres_uri;
00190 n_query_cols++;
00191
00192 query_cols[n_query_cols] = &str_watcher_username_col;
00193 query_vals[n_query_cols].type = DB_STR;
00194 query_vals[n_query_cols].nul = 0;
00195 query_vals[n_query_cols].val.str_val = subs->from_user;
00196 n_query_cols++;
00197
00198 query_cols[n_query_cols] = &str_watcher_domain_col;
00199 query_vals[n_query_cols].type = DB_STR;
00200 query_vals[n_query_cols].nul = 0;
00201 query_vals[n_query_cols].val.str_val = subs->from_domain;
00202 n_query_cols++;
00203
00204 query_cols[n_query_cols] = &str_event_col;
00205 query_vals[n_query_cols].type = DB_STR;
00206 query_vals[n_query_cols].nul = 0;
00207 query_vals[n_query_cols].val.str_val = subs->event->name;
00208 n_query_cols++;
00209
00210 if(subs->event_id.s)
00211 {
00212 query_cols[n_query_cols] = &str_event_id_col;
00213 query_vals[n_query_cols].type = DB_STR;
00214 query_vals[n_query_cols].nul = 0;
00215 query_vals[n_query_cols].val.str_val = subs->event_id;
00216 n_query_cols++;
00217 }
00218 query_cols[n_query_cols] = &str_callid_col;
00219 query_vals[n_query_cols].type = DB_STR;
00220 query_vals[n_query_cols].nul = 0;
00221 query_vals[n_query_cols].val.str_val = subs->callid;
00222 n_query_cols++;
00223
00224 query_cols[n_query_cols] = &str_to_tag_col;
00225 query_vals[n_query_cols].type = DB_STR;
00226 query_vals[n_query_cols].nul = 0;
00227 query_vals[n_query_cols].val.str_val = subs->to_tag;
00228 n_query_cols++;
00229
00230 query_cols[n_query_cols] = &str_from_tag_col;
00231 query_vals[n_query_cols].type = DB_STR;
00232 query_vals[n_query_cols].nul = 0;
00233 query_vals[n_query_cols].val.str_val = subs->from_tag;
00234 n_query_cols++;
00235
00236 if(type & REMOTE_TYPE)
00237 {
00238 update_keys[n_update_cols] = &str_expires_col;
00239 update_vals[n_update_cols].type = DB_INT;
00240 update_vals[n_update_cols].nul = 0;
00241 update_vals[n_update_cols].val.int_val = subs->expires + (int)time(NULL);
00242 n_update_cols++;
00243
00244 update_keys[n_update_cols] = &str_remote_cseq_col;
00245 update_vals[n_update_cols].type = DB_INT;
00246 update_vals[n_update_cols].nul = 0;
00247 update_vals[n_update_cols].val.int_val = subs->remote_cseq;
00248 n_update_cols++;
00249 }
00250 else
00251 {
00252 update_keys[n_update_cols] = &str_local_cseq_col;
00253 update_vals[n_update_cols].type = DB_INT;
00254 update_vals[n_update_cols].nul = 0;
00255 update_vals[n_update_cols].val.int_val = subs->local_cseq+ 1;
00256 n_update_cols++;
00257
00258 update_keys[n_update_cols] = &str_version_col;
00259 update_vals[n_update_cols].type = DB_INT;
00260 update_vals[n_update_cols].nul = 0;
00261 update_vals[n_update_cols].val.int_val = subs->version+ 1;
00262 n_update_cols++;
00263 }
00264
00265 update_keys[n_update_cols] = &str_status_col;
00266 update_vals[n_update_cols].type = DB_INT;
00267 update_vals[n_update_cols].nul = 0;
00268 update_vals[n_update_cols].val.int_val = subs->status;
00269 n_update_cols++;
00270
00271 update_keys[n_update_cols] = &str_reason_col;
00272 update_vals[n_update_cols].type = DB_STR;
00273 update_vals[n_update_cols].nul = 0;
00274 update_vals[n_update_cols].val.str_val = subs->reason;
00275 n_update_cols++;
00276
00277 if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0)
00278 {
00279 LM_ERR("in use table sql operation\n");
00280 return -1;
00281 }
00282
00283 if( pa_dbf.update( pa_db,query_cols, 0, query_vals,
00284 update_keys, update_vals, n_query_cols,n_update_cols)<0)
00285 {
00286 LM_ERR("updating presence information\n");
00287 return -1;
00288 }
00289 return 0;
00290 }
00291
00292 int update_subscription(struct sip_msg* msg, subs_t* subs, int to_tag_gen,
00293 int* sent_reply)
00294 {
00295 unsigned int hash_code;
00296
00297 printf_subs(subs);
00298
00299 *sent_reply= 0;
00300
00301 hash_code= core_hash(&subs->pres_uri, &subs->event->name, shtable_size);
00302
00303 if( to_tag_gen ==0)
00304 {
00305 if(subs->expires == 0)
00306 {
00307 LM_DBG("expires =0 -> deleting record\n");
00308
00309 if( delete_db_subs(subs->pres_uri,
00310 subs->event->name, subs->to_tag)< 0)
00311 {
00312 LM_ERR("deleting subscription record from database\n");
00313 goto error;
00314 }
00315
00316
00317 subs->local_cseq= delete_shtable(subs_htable,hash_code,
00318 subs->to_tag);
00319
00320 if(subs->event->type & PUBL_TYPE)
00321 {
00322 if( send_2XX_reply(msg, 202, subs->expires,
00323 &subs->local_contact) <0)
00324 {
00325 LM_ERR("sending 202 OK\n");
00326 goto error;
00327 }
00328 *sent_reply= 1;
00329 if(subs->event->wipeer)
00330 {
00331 if(query_db_notify(&subs->pres_uri,
00332 subs->event->wipeer, NULL)< 0)
00333 {
00334 LM_ERR("Could not send notify for winfo\n");
00335 goto error;
00336 }
00337 }
00338
00339 }
00340 else
00341 {
00342 if( send_2XX_reply(msg, 200, subs->expires,
00343 &subs->local_contact) <0)
00344 {
00345 LM_ERR("sending 200 OK reply\n");
00346 goto error;
00347 }
00348 *sent_reply= 1;
00349 }
00350
00351 if(notify(subs, NULL, NULL, 0)< 0)
00352 {
00353 LM_ERR("Could not send notify\n");
00354 goto error;
00355 }
00356 return 1;
00357 }
00358
00359 if(update_shtable(subs_htable, hash_code, subs, REMOTE_TYPE)< 0)
00360 {
00361 if(fallback2db)
00362 {
00363
00364 if(update_subs_db(subs, REMOTE_TYPE)< 0)
00365 {
00366 LM_ERR("updating subscription in database table\n");
00367 goto error;
00368 }
00369 }
00370 else
00371 {
00372 LM_ERR("updating subscription record in hash table\n");
00373 goto error;
00374 }
00375 }
00376 }
00377 else
00378 {
00379 if(subs->expires!= 0)
00380 {
00381 if(insert_shtable(subs_htable,hash_code,subs)< 0)
00382 {
00383 LM_ERR("inserting new record in subs_htable\n");
00384 goto error;
00385 }
00386 }
00387
00388
00389 }
00390
00391
00392
00393 if(subs->event->type & PUBL_TYPE)
00394 {
00395 if(send_2XX_reply(msg, 202, subs->expires,
00396 &subs->local_contact)<0)
00397 {
00398 LM_ERR("sending 202 OK reply\n");
00399 goto error;
00400 }
00401 *sent_reply= 1;
00402
00403 if(subs->expires!= 0 && subs->event->wipeer)
00404 {
00405 LM_DBG("send Notify with winfo\n");
00406 if(query_db_notify(&subs->pres_uri, subs->event->wipeer, subs)< 0)
00407 {
00408 LM_ERR("Could not send notify winfo\n");
00409 goto error;
00410 }
00411 if(subs->send_on_cback== 0)
00412 {
00413 if(notify(subs, NULL, NULL, 0)< 0)
00414 {
00415 LM_ERR("Could not send notify\n");
00416 goto error;
00417 }
00418 }
00419 }
00420 else
00421 {
00422 if(notify(subs, NULL, NULL, 0)< 0)
00423 {
00424 LM_ERR("Could not send notify\n");
00425 goto error;
00426 }
00427 }
00428
00429 }
00430 else
00431 {
00432 if( send_2XX_reply(msg, 200, subs->expires,
00433 &subs->local_contact)<0)
00434 {
00435 LM_ERR("sending 200 OK reply\n");
00436 goto error;
00437 }
00438 *sent_reply= 1;
00439
00440 if(notify(subs, NULL, NULL, 0 )< 0)
00441 {
00442 LM_ERR("sending notify request\n");
00443 goto error;
00444 }
00445 }
00446 return 0;
00447
00448 error:
00449
00450 LM_ERR("occured\n");
00451 return -1;
00452
00453 }
00454
00455 void msg_watchers_clean(unsigned int ticks,void *param)
00456 {
00457 db_key_t db_keys[3], result_cols[1];
00458 db_val_t db_vals[3];
00459 db_op_t db_ops[3] ;
00460 db_res_t *result= NULL;
00461
00462 LM_DBG("cleaning pending subscriptions\n");
00463
00464 db_keys[0] = &str_inserted_time_col;
00465 db_ops[0] = OP_LT;
00466 db_vals[0].type = DB_INT;
00467 db_vals[0].nul = 0;
00468 db_vals[0].val.int_val = (int)time(NULL)- 24*3600 ;
00469
00470 db_keys[1] = &str_status_col;
00471 db_ops [1] = OP_EQ;
00472 db_vals[1].type = DB_INT;
00473 db_vals[1].nul = 0;
00474 db_vals[1].val.int_val = PENDING_STATUS;
00475
00476 result_cols[0]= &str_id_col;
00477
00478 if (pa_dbf.use_table(pa_db, &watchers_table) < 0)
00479 {
00480 LM_ERR("unsuccessful use table sql operation\n");
00481 return ;
00482 }
00483
00484 if(pa_dbf.query(pa_db, db_keys, db_ops, db_vals, result_cols, 2, 1, 0, &result )< 0)
00485 {
00486 LM_ERR("querying database for expired messages\n");
00487 if(result)
00488 pa_dbf.free_result(pa_db, result);
00489 return;
00490 }
00491 if(result == NULL)
00492 return;
00493 if(result->n <= 0)
00494 {
00495 pa_dbf.free_result(pa_db, result);
00496 return;
00497 }
00498 pa_dbf.free_result(pa_db, result);
00499
00500 if (pa_dbf.delete(pa_db, db_keys, db_ops, db_vals, 2) < 0)
00501 LM_ERR("cleaning pending subscriptions\n");
00502 }
00503
00504 int handle_subscribe(struct sip_msg* msg, char* str1, char* str2)
00505 {
00506 int to_tag_gen = 0;
00507 subs_t subs;
00508 pres_ev_t* event= NULL;
00509 event_t* parsed_event= NULL;
00510 param_t* ev_param= NULL;
00511 int found;
00512 str reason= {0, 0};
00513 struct sip_uri uri;
00514 int reply_code;
00515 str reply_str;
00516 int sent_reply= 0;
00517
00518
00519 counter++;
00520
00521 memset(&subs, 0, sizeof(subs_t));
00522
00523 reply_code= 500;
00524 reply_str= pu_500_rpl;
00525
00526 if( parse_headers(msg,HDR_EOH_F, 0)==-1 )
00527 {
00528 LM_ERR("parsing headers\n");
00529 reply_code= 400;
00530 reply_str= pu_400_rpl;
00531 goto error;
00532 }
00533
00534
00535 if(msg->event && msg->event->body.len > 0)
00536 {
00537 if (!msg->event->parsed && (parse_event(msg->event) < 0))
00538 {
00539 reply_code= 400;
00540 reply_str= pu_400_rpl;
00541 goto error;
00542 }
00543 if(((event_t*)msg->event->parsed)->parsed == EVENT_OTHER)
00544 {
00545 goto bad_event;
00546 }
00547 }
00548 else
00549 goto bad_event;
00550
00551
00552 parsed_event= (event_t*)msg->event->parsed;
00553 event= search_event(parsed_event);
00554 if(event== NULL)
00555 {
00556 goto bad_event;
00557 }
00558 subs.event= event;
00559
00560
00561 ev_param= parsed_event->params;
00562 while(ev_param)
00563 {
00564 if(ev_param->name.len== 2 && strncmp(ev_param->name.s, "id", 2)== 0)
00565 {
00566 subs.event_id= ev_param->body;
00567 break;
00568 }
00569 ev_param= ev_param->next;
00570 }
00571
00572 if(extract_sdialog_info(&subs, msg, max_expires, &to_tag_gen,
00573 server_address)< 0)
00574 {
00575 LM_ERR("failed to extract dialog information\n");
00576 goto error;
00577 }
00578
00579
00580 if(to_tag_gen)
00581 {
00582 if(parsed_event->parsed!= EVENT_DIALOG_SLA)
00583 {
00584 if( parse_sip_msg_uri(msg)< 0)
00585 {
00586 LM_ERR("failed to parse R-URI\n");
00587 return -1;
00588 }
00589 if(uandd_to_uri(msg->parsed_uri.user, msg->parsed_uri.host,
00590 &subs.pres_uri)< 0)
00591 {
00592 LM_ERR("failed to construct uri from user and domain\n");
00593 goto error;
00594 }
00595 }
00596 }
00597 else
00598 {
00599 if(get_stored_info(msg, &subs, &reply_code, &reply_str )< 0)
00600 {
00601 LM_ERR("getting stored info\n");
00602 goto error;
00603 }
00604 reason= subs.reason;
00605 }
00606
00607
00608 if(event->evs_subs_handl)
00609 {
00610 if(event->evs_subs_handl(msg)< 0)
00611 {
00612 LM_ERR("in event specific subscription handling\n");
00613 goto error;
00614 }
00615 }
00616
00617
00618
00619 if(to_tag_gen)
00620 {
00621 if(!event->req_auth)
00622 subs.status = ACTIVE_STATUS;
00623 else
00624 {
00625
00626 if(get_db_subs_auth(&subs, &found)< 0)
00627 {
00628 LM_ERR("getting subscription status from watchers table\n");
00629 goto error;
00630 }
00631 if(found== 0)
00632 {
00633
00634 subs.status= PENDING_STATUS;
00635 subs.reason.s= NULL;
00636 subs.reason.len= 0;
00637
00638
00639 if(parse_uri(subs.pres_uri.s, subs.pres_uri.len, &uri)< 0)
00640 {
00641 LM_ERR("parsing uri\n");
00642 goto error;
00643
00644 }
00645 if(subs.event->get_rules_doc(&uri.user, &uri.host, &subs.auth_rules_doc)< 0)
00646 {
00647 LM_ERR("getting rules doc\n");
00648 goto error;
00649 }
00650
00651 if(subs.event->get_auth_status(&subs)< 0)
00652 {
00653 LM_ERR("in event specific function is_watcher_allowed\n");
00654 goto error;
00655 }
00656 if(get_status_str(subs.status)== NULL)
00657 {
00658 LM_ERR("wrong status= %d\n", subs.status);
00659 goto error;
00660 }
00661
00662 if(insert_db_subs_auth(&subs)< 0)
00663 {
00664 LM_ERR("while inserting record in watchers table\n");
00665 goto error;
00666 }
00667 }
00668 else
00669 {
00670 reason= subs.reason;
00671 }
00672 }
00673 }
00674
00675
00676 if(get_status_str(subs.status)== NULL)
00677 {
00678 LM_ERR("wrong status\n");
00679 goto error;
00680 }
00681 LM_DBG("subscription status= %s - %s\n", get_status_str(subs.status),
00682 found==0?"inserted":"found in watcher table");
00683
00684 if(update_subscription(msg, &subs, to_tag_gen, &sent_reply) <0)
00685 {
00686 LM_ERR("in update_subscription\n");
00687 goto error;
00688 }
00689 if(subs.auth_rules_doc)
00690 {
00691 pkg_free(subs.auth_rules_doc->s);
00692 pkg_free(subs.auth_rules_doc);
00693 }
00694 if(reason.s)
00695 pkg_free(reason.s);
00696
00697 if(subs.pres_uri.s)
00698 pkg_free(subs.pres_uri.s);
00699
00700 if((!server_address.s) || (server_address.len== 0))
00701 {
00702 pkg_free(subs.local_contact.s);
00703 }
00704 if(subs.record_route.s)
00705 pkg_free(subs.record_route.s);
00706
00707 return 1;
00708
00709 bad_event:
00710
00711 LM_ERR("Missing or unsupported event header field value\n");
00712
00713 if(parsed_event && parsed_event->text.s)
00714 LM_ERR("\tevent= %.*s\n",parsed_event->text.len,parsed_event->text.s);
00715
00716 reply_code= BAD_EVENT_CODE;
00717 reply_str= pu_489_rpl;
00718
00719 error:
00720
00721 if(sent_reply== 0)
00722 {
00723 if(send_error_reply(msg, reply_code, reply_str)< 0)
00724 {
00725 LM_ERR("failed to send reply on error case\n");
00726 }
00727 }
00728
00729 if(subs.pres_uri.s)
00730 pkg_free(subs.pres_uri.s);
00731
00732 if(subs.auth_rules_doc)
00733 {
00734 if(subs.auth_rules_doc->s)
00735 pkg_free(subs.auth_rules_doc->s);
00736 pkg_free(subs.auth_rules_doc);
00737 }
00738 if(reason.s)
00739 pkg_free(reason.s);
00740
00741 if(((!server_address.s) ||(server_address.len== 0))&& subs.local_contact.s)
00742 {
00743 pkg_free(subs.local_contact.s);
00744 }
00745 if(subs.record_route.s)
00746 pkg_free(subs.record_route.s);
00747
00748 return -1;
00749
00750 }
00751
00752
00753 int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
00754 int* to_tag_gen, str scontact)
00755 {
00756 str rec_route= {0, 0};
00757 int rt = 0;
00758 str* contact= NULL;
00759 contact_body_t *b;
00760 struct to_body *pto, *pfrom = NULL, TO;
00761 int lexpire;
00762 str rtag_value;
00763 struct sip_uri uri;
00764
00765
00766 if(msg->expires && msg->expires->body.len > 0)
00767 {
00768 if (!msg->expires->parsed && (parse_expires(msg->expires) < 0))
00769 {
00770 LM_ERR("cannot parse Expires header\n");
00771 goto error;
00772 }
00773 lexpire = ((exp_body_t*)msg->expires->parsed)->val;
00774 LM_DBG("'Expires' header found, value= %d\n", lexpire);
00775
00776 }
00777 else
00778 {
00779 LM_DBG("'expires' not found; default=%d\n",subs->event->default_expires);
00780 lexpire = subs->event->default_expires;
00781 }
00782 if(lexpire > mexp)
00783 lexpire = mexp;
00784
00785 subs->expires = lexpire;
00786
00787 if( msg->to==NULL || msg->to->body.s==NULL)
00788 {
00789 LM_ERR("cannot parse TO header\n");
00790 goto error;
00791 }
00792
00793 if(msg->to->parsed != NULL)
00794 {
00795 pto = (struct to_body*)msg->to->parsed;
00796 LM_DBG("'To' header ALREADY PARSED: <%.*s>\n",pto->uri.len,pto->uri.s);
00797 }
00798 else
00799 {
00800 memset( &TO , 0, sizeof(TO) );
00801 if( !parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO));
00802 {
00803 LM_DBG("'To' header NOT parsed\n");
00804 goto error;
00805 }
00806 pto = &TO;
00807 }
00808
00809 if( pto->parsed_uri.user.s && pto->parsed_uri.host.s &&
00810 pto->parsed_uri.user.len && pto->parsed_uri.host.len)
00811 {
00812 subs->to_user = pto->parsed_uri.user;
00813 subs->to_domain = pto->parsed_uri.host;
00814 }
00815 else
00816 {
00817 if(parse_uri(pto->uri.s, pto->uri.len, &uri)< 0)
00818 {
00819 LM_ERR("while parsing uri\n");
00820 goto error;
00821 }
00822 subs->to_user = uri.user;
00823 subs->to_domain = uri.host;
00824 }
00825
00826
00827 if (!msg->from || !msg->from->body.s)
00828 {
00829 LM_DBG("cannot find 'from' header!\n");
00830 goto error;
00831 }
00832 if (msg->from->parsed == NULL)
00833 {
00834 LM_DBG("'From' header not parsed\n");
00835
00836 if ( parse_from_header( msg )<0 )
00837 {
00838 LM_DBG("cannot parse From header\n");
00839 goto error;
00840 }
00841 }
00842 pfrom = (struct to_body*)msg->from->parsed;
00843
00844 if( pfrom->parsed_uri.user.s && pfrom->parsed_uri.host.s &&
00845 pfrom->parsed_uri.user.len && pfrom->parsed_uri.host.len)
00846 {
00847 subs->from_user = pfrom->parsed_uri.user;
00848 subs->from_domain = pfrom->parsed_uri.host;
00849 }
00850 else
00851 {
00852 if(parse_uri(pfrom->uri.s, pfrom->uri.len, &uri)< 0)
00853 {
00854 LM_ERR("while parsing uri\n");
00855 goto error;
00856 }
00857 subs->from_user = uri.user;
00858 subs->from_domain = uri.host;
00859 }
00860
00861
00862 if (pto->tag_value.s==NULL || pto->tag_value.len==0 )
00863 {
00864 LM_DBG("generating to_tag\n");
00865 *to_tag_gen = 1;
00866 rtag_value.len = 0;
00867 if(slb.get_reply_totag(msg, &rtag_value)<0 || rtag_value.len <= 0)
00868 {
00869 LM_ERR("while creating to_tag\n");
00870 goto error;
00871 }
00872 }
00873 else
00874 {
00875 *to_tag_gen = 0;
00876 rtag_value=pto->tag_value;
00877 }
00878 subs->to_tag = rtag_value;
00879
00880 if( msg->callid==NULL || msg->callid->body.s==NULL)
00881 {
00882 LM_ERR("cannot parse callid header\n");
00883 goto error;
00884 }
00885 subs->callid = msg->callid->body;
00886
00887 if( msg->cseq==NULL || msg->cseq->body.s==NULL)
00888 {
00889 LM_ERR("cannot parse cseq header\n");
00890 goto error;
00891 }
00892 if (str2int( &(get_cseq(msg)->number), &subs->remote_cseq)!=0 )
00893 {
00894 LM_ERR("cannot parse cseq number\n");
00895 goto error;
00896 }
00897 if( msg->contact==NULL || msg->contact->body.s==NULL)
00898 {
00899 LM_ERR("cannot parse contact header\n");
00900 goto error;
00901 }
00902 if( parse_contact(msg->contact) <0 )
00903 {
00904 LM_ERR(" cannot parse contact"
00905 " header\n");
00906 goto error;
00907 }
00908 b= (contact_body_t* )msg->contact->parsed;
00909
00910 if(b == NULL)
00911 {
00912 LM_ERR("cannot parse contact header\n");
00913 goto error;
00914 }
00915 subs->contact = b->contacts->uri;
00916
00917 LM_DBG("subs->contact= %.*s - len = %d\n",subs->contact.len,
00918 subs->contact.s, subs->contact.len);
00919
00920 if(subs->event->evp->parsed== EVENT_DIALOG_SLA)
00921 {
00922
00923 if(parse_uri(subs->contact.s, subs->contact.len, &uri)< 0)
00924 {
00925 LM_ERR("failed to parse contact uri\n");
00926 goto error;
00927 }
00928 if(uandd_to_uri(uri.user, subs->from_domain, &subs->pres_uri)< 0)
00929 {
00930 LM_ERR("failed to construct uri\n");
00931 goto error;
00932 }
00933 LM_DBG("&&&&&&&&&&&&&&& dialog pres_uri= %.*s\n",subs->pres_uri.len, subs->pres_uri.s);
00934 }
00935
00936
00937
00938 if(*to_tag_gen && msg->record_route!=NULL)
00939 {
00940 rt = print_rr_body(msg->record_route, &rec_route, 0, 0);
00941 if(rt != 0)
00942 {
00943 LM_ERR("processing the record route [%d]\n", rt);
00944 rec_route.s=NULL;
00945 rec_route.len=0;
00946
00947 }
00948 }
00949 subs->record_route = rec_route;
00950
00951 subs->sockinfo_str= msg->rcv.bind_address->sock_str;
00952
00953 if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0)
00954 {
00955 LM_ERR("no from tag value present\n");
00956 goto error;
00957 }
00958 subs->from_tag = pfrom->tag_value;
00959
00960 subs->version = 0;
00961
00962 if((!scontact.s) || (scontact.len== 0))
00963 {
00964 contact= get_local_contact(msg);
00965 if(contact== NULL)
00966 {
00967 LM_ERR("in function get_local_contact\n");
00968 goto error;
00969 }
00970 subs->local_contact= *contact;
00971 }
00972 else
00973 subs->local_contact= scontact;
00974
00975 return 0;
00976
00977 error:
00978
00979 return -1;
00980 }
00981
00982
00983 int get_stored_info(struct sip_msg* msg, subs_t* subs, int* reply_code,
00984 str* reply_str)
00985 {
00986 str pres_uri= {0, 0}, reason={0, 0};
00987 subs_t* s;
00988 int i;
00989 unsigned int hash_code;
00990
00991
00992
00993 if(subs->pres_uri.s == NULL)
00994 {
00995 uandd_to_uri(subs->to_user, subs->to_domain, &pres_uri);
00996 if(pres_uri.s== NULL)
00997 {
00998 LM_ERR("creating uri from user and domain\n");
00999 return -1;
01000 }
01001 }
01002 else
01003 pres_uri = subs->pres_uri;
01004
01005 hash_code= core_hash(&pres_uri, &subs->event->name, shtable_size);
01006 lock_get(&subs_htable[hash_code].lock);
01007 i= hash_code;
01008 s= search_shtable(subs_htable, subs->callid, subs->to_tag,
01009 subs->from_tag, hash_code);
01010 if(s)
01011 {
01012 goto found_rec;
01013 }
01014 lock_release(&subs_htable[hash_code].lock);
01015
01016 if(subs->pres_uri.s)
01017 goto not_found;
01018
01019 pkg_free(pres_uri.s);
01020 pres_uri.s= NULL;
01021
01022
01023 LM_DBG("record not found using R-URI search iteratively\n");
01024
01025 for(i= 0; i< shtable_size; i++)
01026 {
01027 lock_get(&subs_htable[i].lock);
01028 s= search_shtable(subs_htable, subs->callid,subs->to_tag,subs->from_tag, i);
01029 if(s && s->event->evp->parsed!= EVENT_DIALOG_SLA)
01030 {
01031 pres_uri.s= (char*)pkg_malloc(s->pres_uri.len* sizeof(char));
01032 if(pres_uri.s== NULL)
01033 {
01034 lock_release(&subs_htable[i].lock);
01035 ERR_MEM(PKG_MEM_STR);
01036 }
01037 memcpy(pres_uri.s, s->pres_uri.s, s->pres_uri.len);
01038 pres_uri.len= s->pres_uri.len;
01039 goto found_rec;
01040 }
01041 lock_release(&subs_htable[i].lock);
01042 }
01043
01044 if(fallback2db)
01045 {
01046 return get_database_info(msg, subs, reply_code, reply_str);
01047 }
01048
01049 not_found:
01050
01051 LM_ERR("record not found in hash_table\n");
01052 *reply_code= 481;
01053 *reply_str= pu_481_rpl;
01054
01055 return -1;
01056
01057 found_rec:
01058
01059 LM_DBG("Record found in hash_table\n");
01060
01061 if(s->event->evp->parsed!= EVENT_DIALOG_SLA)
01062 subs->pres_uri= pres_uri;
01063
01064 subs->version = s->version;
01065 subs->status= s->status;
01066 if(s->reason.s && s->reason.len)
01067 {
01068 reason.s= (char*)pkg_malloc(s->reason.len* sizeof(char));
01069 if(reason.s== NULL)
01070 {
01071 lock_release(&subs_htable[i].lock);
01072 ERR_MEM(PKG_MEM_STR);
01073 }
01074 memcpy(reason.s, s->reason.s, s->reason.len);
01075 reason.len= s->reason.len;
01076 subs->reason= reason;
01077 }
01078 if(s->record_route.s && s->record_route.len)
01079 {
01080 subs->record_route.s= (char*)pkg_malloc
01081 (s->record_route.len* sizeof(char));
01082 if(subs->record_route.s== NULL)
01083 {
01084 ERR_MEM(PKG_MEM_STR);
01085 }
01086 memcpy(subs->record_route.s, s->record_route.s, s->record_route.len);
01087 subs->record_route.len= s->record_route.len;
01088 }
01089
01090 subs->local_cseq= s->local_cseq;
01091
01092 if(subs->remote_cseq<= s->remote_cseq)
01093 {
01094 LM_ERR("wrong sequence number;received: %d - stored: %d\n",
01095 subs->remote_cseq, s->remote_cseq);
01096
01097 *reply_code= 400;
01098 *reply_str= pu_400_rpl;
01099
01100 lock_release(&subs_htable[i].lock);
01101 goto error;
01102 }
01103 lock_release(&subs_htable[i].lock);
01104
01105 return 0;
01106
01107 error:
01108 if(subs->reason.s)
01109 pkg_free(subs->reason.s);
01110 subs->reason.s= NULL;
01111 if(subs->record_route.s)
01112 pkg_free(subs->record_route.s);
01113 subs->record_route.s= NULL;
01114 return -1;
01115 }
01116
01117 int get_database_info(struct sip_msg* msg, subs_t* subs, int* reply_code, str* reply_str)
01118 {
01119 db_key_t query_cols[10];
01120 db_val_t query_vals[10];
01121 db_key_t result_cols[9];
01122 db_res_t *result= NULL;
01123 db_row_t *row ;
01124 db_val_t *row_vals ;
01125 int n_query_cols = 0;
01126 int n_result_cols = 0;
01127 int remote_cseq_col= 0, local_cseq_col= 0, status_col, reason_col;
01128 int record_route_col, version_col;
01129 int pres_uri_col;
01130 unsigned int remote_cseq;
01131 str pres_uri, record_route;
01132 str reason;
01133
01134 query_cols[n_query_cols] = &str_to_user_col;
01135 query_vals[n_query_cols].type = DB_STR;
01136 query_vals[n_query_cols].nul = 0;
01137 query_vals[n_query_cols].val.str_val = subs->to_user;
01138 n_query_cols++;
01139
01140 query_cols[n_query_cols] = &str_to_domain_col;
01141 query_vals[n_query_cols].type = DB_STR;
01142 query_vals[n_query_cols].nul = 0;
01143 query_vals[n_query_cols].val.str_val = subs->to_domain;
01144 n_query_cols++;
01145
01146 query_cols[n_query_cols] = &str_watcher_username_col;
01147 query_vals[n_query_cols].type = DB_STR;
01148 query_vals[n_query_cols].nul = 0;
01149 query_vals[n_query_cols].val.str_val = subs->from_user;
01150 n_query_cols++;
01151
01152 query_cols[n_query_cols] = &str_watcher_domain_col;
01153 query_vals[n_query_cols].type = DB_STR;
01154 query_vals[n_query_cols].nul = 0;
01155 query_vals[n_query_cols].val.str_val = subs->from_domain;
01156 n_query_cols++;
01157
01158 query_cols[n_query_cols] = &str_event_col;
01159 query_vals[n_query_cols].type = DB_STR;
01160 query_vals[n_query_cols].nul = 0;
01161 query_vals[n_query_cols].val.str_val = subs->event->name;
01162 n_query_cols++;
01163
01164 query_cols[n_query_cols] = &str_event_id_col;
01165 query_vals[n_query_cols].type = DB_STR;
01166 query_vals[n_query_cols].nul = 0;
01167 if( subs->event_id.s != NULL)
01168 {
01169 query_vals[n_query_cols].val.str_val.s = subs->event_id.s;
01170 query_vals[n_query_cols].val.str_val.len = subs->event_id.len;
01171 } else {
01172 query_vals[n_query_cols].val.str_val.s = "";
01173 query_vals[n_query_cols].val.str_val.len = 0;
01174 }
01175 n_query_cols++;
01176
01177 query_cols[n_query_cols] = &str_callid_col;
01178 query_vals[n_query_cols].type = DB_STR;
01179 query_vals[n_query_cols].nul = 0;
01180 query_vals[n_query_cols].val.str_val = subs->callid;
01181 n_query_cols++;
01182
01183 query_cols[n_query_cols] = &str_to_tag_col;
01184 query_vals[n_query_cols].type = DB_STR;
01185 query_vals[n_query_cols].nul = 0;
01186 query_vals[n_query_cols].val.str_val = subs->to_tag;
01187 n_query_cols++;
01188
01189 query_cols[n_query_cols] = &str_from_tag_col;
01190 query_vals[n_query_cols].type = DB_STR;
01191 query_vals[n_query_cols].nul = 0;
01192 query_vals[n_query_cols].val.str_val = subs->from_tag;
01193 n_query_cols++;
01194
01195 result_cols[pres_uri_col=n_result_cols++] = &str_presentity_uri_col;
01196 result_cols[remote_cseq_col=n_result_cols++] = &str_remote_cseq_col;
01197 result_cols[local_cseq_col=n_result_cols++] = &str_local_cseq_col;
01198 result_cols[status_col=n_result_cols++] = &str_status_col;
01199 result_cols[reason_col=n_result_cols++] = &str_reason_col;
01200 result_cols[record_route_col=n_result_cols++] = &str_record_route_col;
01201 result_cols[version_col=n_result_cols++] = &str_version_col;
01202
01203 if (pa_dbf.use_table(pa_db, &active_watchers_table) < 0)
01204 {
01205 LM_ERR("unsuccessful use_table sql operation\n");
01206 return -1;
01207 }
01208
01209 if (pa_dbf.query (pa_db, query_cols, 0, query_vals,
01210 result_cols, n_query_cols, n_result_cols, 0, &result) < 0)
01211 {
01212 LM_ERR("querying subscription dialog\n");
01213 if(result)
01214 pa_dbf.free_result(pa_db, result);
01215 return -1;
01216 }
01217 if(result== NULL)
01218 return -1;
01219
01220 if(result && result->n <=0)
01221 {
01222 LM_ERR("No matching subscription dialog found in database\n");
01223
01224 pa_dbf.free_result(pa_db, result);
01225 *reply_code= 481;
01226 *reply_str= pu_481_rpl;
01227
01228 return -1;
01229 }
01230
01231 row = &result->rows[0];
01232 row_vals = ROW_VALUES(row);
01233 remote_cseq= row_vals[remote_cseq_col].val.int_val;
01234
01235 if(subs->remote_cseq<= remote_cseq)
01236 {
01237 LM_ERR("wrong sequence number received: %d - stored: %d\n",
01238 subs->remote_cseq, remote_cseq);
01239 *reply_code= 400;
01240 *reply_str= pu_400_rpl;
01241 pa_dbf.free_result(pa_db, result);
01242 return -1;
01243 }
01244
01245 subs->status= row_vals[status_col].val.int_val;
01246 reason.s= (char*)row_vals[reason_col].val.string_val;
01247 if(reason.s)
01248 {
01249 reason.len= strlen(reason.s);
01250 subs->reason.s= (char*)pkg_malloc(reason.len* sizeof(char));
01251 if(subs->reason.s== NULL)
01252 {
01253 ERR_MEM(PKG_MEM_STR);
01254 }
01255 memcpy(subs->reason.s, reason.s, reason.len);
01256 subs->reason.len= reason.len;
01257 }
01258
01259 subs->local_cseq= row_vals[local_cseq_col].val.int_val;
01260 subs->version= row_vals[version_col].val.int_val;
01261
01262 if(subs->event->evp->parsed!= EVENT_DIALOG_SLA)
01263 {
01264 pres_uri.s= (char*)row_vals[pres_uri_col].val.string_val;
01265 pres_uri.len= strlen(pres_uri.s);
01266 subs->pres_uri.s= (char*)pkg_malloc(pres_uri.len* sizeof(char));
01267 if(subs->pres_uri.s== NULL)
01268 {
01269 if(subs->reason.s)
01270 pkg_free(subs->reason.s);
01271 ERR_MEM(PKG_MEM_STR);
01272 }
01273 memcpy(subs->pres_uri.s, pres_uri.s, pres_uri.len);
01274 subs->pres_uri.len= pres_uri.len;
01275 }
01276
01277 record_route.s= (char*)row_vals[record_route_col].val.string_val;
01278 if(record_route.s)
01279 {
01280 record_route.len= strlen(record_route.s);
01281 subs->record_route.s= (char*)pkg_malloc(record_route.len*sizeof(char));
01282 if(subs->record_route.s== NULL)
01283 {
01284 ERR_MEM(PKG_MEM_STR);
01285 }
01286 memcpy(subs->record_route.s, record_route.s, record_route.len);
01287 subs->record_route.len= record_route.len;
01288 }
01289
01290 pa_dbf.free_result(pa_db, result);
01291 result= NULL;
01292
01293 return 0;
01294 error:
01295 if(result)
01296 pa_dbf.free_result(pa_db, result);
01297
01298 return -1;
01299
01300 }
01301
01302
01303 int handle_expired_subs(subs_t* s)
01304 {
01305
01306
01307 s->status= TERMINATED_STATUS;
01308 s->reason.s= "timeout";
01309 s->reason.len= 7;
01310 s->expires= 0;
01311
01312 if(send_notify_request(s, NULL, NULL, 1)< 0)
01313 {
01314 LM_ERR("send Notify not successful\n");
01315 return -1;
01316 }
01317
01318 return 0;
01319
01320 }
01321
01322 void timer_db_update(unsigned int ticks,void *param)
01323 {
01324 int no_lock=0;
01325
01326 if(ticks== 0 && param == NULL)
01327 no_lock= 1;
01328
01329 if(pa_dbf.use_table(pa_db, &active_watchers_table)< 0)
01330 {
01331 LM_ERR("sql use table failed\n");
01332 return;
01333 }
01334
01335 update_db_subs(pa_db, pa_dbf, subs_htable,
01336 shtable_size, no_lock, handle_expired_subs);
01337
01338 }
01339
01340 void update_db_subs(db_con_t *db,db_func_t dbf, shtable_t hash_table,
01341 int htable_size, int no_lock, handle_expired_func_t handle_expired_func)
01342 {
01343 db_key_t query_cols[22], update_cols[7];
01344 db_val_t query_vals[22], update_vals[7];
01345 db_op_t update_ops[1];
01346 subs_t* del_s;
01347 int pres_uri_col, to_user_col, to_domain_col, from_user_col, from_domain_col,
01348 callid_col, totag_col, fromtag_col, event_col,status_col, event_id_col,
01349 local_cseq_col, remote_cseq_col, expires_col, record_route_col,
01350 contact_col, local_contact_col, version_col,socket_info_col,reason_col;
01351 int u_expires_col, u_local_cseq_col, u_remote_cseq_col, u_version_col,
01352 u_reason_col, u_status_col;
01353 int i;
01354 subs_t* s= NULL, *prev_s= NULL;
01355 int n_query_cols= 0, n_update_cols= 0;
01356 int n_query_update;
01357
01358 query_cols[pres_uri_col= n_query_cols] =&str_presentity_uri_col;
01359 query_vals[pres_uri_col].type = DB_STR;
01360 query_vals[pres_uri_col].nul = 0;
01361 n_query_cols++;
01362
01363 query_cols[callid_col= n_query_cols] =&str_callid_col;
01364 query_vals[callid_col].type = DB_STR;
01365 query_vals[callid_col].nul = 0;
01366 n_query_cols++;
01367
01368 query_cols[totag_col= n_query_cols] =&str_to_tag_col;
01369 query_vals[totag_col].type = DB_STR;
01370 query_vals[totag_col].nul = 0;
01371 n_query_cols++;
01372
01373 query_cols[fromtag_col= n_query_cols] =&str_from_tag_col;
01374 query_vals[fromtag_col].type = DB_STR;
01375 query_vals[fromtag_col].nul = 0;
01376 n_query_cols++;
01377
01378 n_query_update= n_query_cols;
01379
01380 query_cols[to_user_col= n_query_cols] =&str_to_user_col;
01381 query_vals[to_user_col].type = DB_STR;
01382 query_vals[to_user_col].nul = 0;
01383 n_query_cols++;
01384
01385 query_cols[to_domain_col= n_query_cols] =&str_to_domain_col;
01386 query_vals[to_domain_col].type = DB_STR;
01387 query_vals[to_domain_col].nul = 0;
01388 n_query_cols++;
01389
01390 query_cols[from_user_col= n_query_cols] =&str_watcher_username_col;
01391 query_vals[from_user_col].type = DB_STR;
01392 query_vals[from_user_col].nul = 0;
01393 n_query_cols++;
01394
01395 query_cols[from_domain_col= n_query_cols] =&str_watcher_domain_col;
01396 query_vals[from_domain_col].type = DB_STR;
01397 query_vals[from_domain_col].nul = 0;
01398 n_query_cols++;
01399
01400 query_cols[event_col= n_query_cols] =&str_event_col;
01401 query_vals[event_col].type = DB_STR;
01402 query_vals[event_col].nul = 0;
01403 n_query_cols++;
01404
01405 query_cols[event_id_col= n_query_cols] =&str_event_id_col;
01406 query_vals[event_id_col].type = DB_STR;
01407 query_vals[event_id_col].nul = 0;
01408 n_query_cols++;
01409
01410 query_cols[local_cseq_col= n_query_cols]=&str_local_cseq_col;
01411 query_vals[local_cseq_col].type = DB_INT;
01412 query_vals[local_cseq_col].nul = 0;
01413 n_query_cols++;
01414
01415 query_cols[remote_cseq_col= n_query_cols]=&str_remote_cseq_col;
01416 query_vals[remote_cseq_col].type = DB_INT;
01417 query_vals[remote_cseq_col].nul = 0;
01418 n_query_cols++;
01419
01420 query_cols[expires_col= n_query_cols] =&str_expires_col;
01421 query_vals[expires_col].type = DB_INT;
01422 query_vals[expires_col].nul = 0;
01423 n_query_cols++;
01424
01425 query_cols[status_col= n_query_cols] =&str_status_col;
01426 query_vals[status_col].type = DB_INT;
01427 query_vals[status_col].nul = 0;
01428 n_query_cols++;
01429
01430 query_cols[reason_col= n_query_cols] =&str_reason_col;
01431 query_vals[reason_col].type = DB_STR;
01432 query_vals[reason_col].nul = 0;
01433 n_query_cols++;
01434
01435 query_cols[record_route_col= n_query_cols] =&str_record_route_col;
01436 query_vals[record_route_col].type = DB_STR;
01437 query_vals[record_route_col].nul = 0;
01438 n_query_cols++;
01439
01440 query_cols[contact_col= n_query_cols] =&str_contact_col;
01441 query_vals[contact_col].type = DB_STR;
01442 query_vals[contact_col].nul = 0;
01443 n_query_cols++;
01444
01445 query_cols[local_contact_col= n_query_cols] =&str_local_contact_col;
01446 query_vals[local_contact_col].type = DB_STR;
01447 query_vals[local_contact_col].nul = 0;
01448 n_query_cols++;
01449
01450 query_cols[socket_info_col= n_query_cols] =&str_socket_info_col;
01451 query_vals[socket_info_col].type = DB_STR;
01452 query_vals[socket_info_col].nul = 0;
01453 n_query_cols++;
01454
01455 query_cols[version_col= n_query_cols]=&str_version_col;
01456 query_vals[version_col].type = DB_INT;
01457 query_vals[version_col].nul = 0;
01458 n_query_cols++;
01459
01460
01461 update_cols[u_expires_col= n_update_cols]= &str_expires_col;
01462 update_vals[u_expires_col].type = DB_INT;
01463 update_vals[u_expires_col].nul = 0;
01464 n_update_cols++;
01465
01466 update_cols[u_status_col= n_update_cols]= &str_status_col;
01467 update_vals[u_status_col].type = DB_INT;
01468 update_vals[u_status_col].nul = 0;
01469 n_update_cols++;
01470
01471 update_cols[u_reason_col= n_update_cols]= &str_reason_col;
01472 update_vals[u_reason_col].type = DB_STR;
01473 update_vals[u_reason_col].nul = 0;
01474 n_update_cols++;
01475
01476 update_cols[u_remote_cseq_col= n_update_cols]= &str_remote_cseq_col;
01477 update_vals[u_remote_cseq_col].type = DB_INT;
01478 update_vals[u_remote_cseq_col].nul = 0;
01479 n_update_cols++;
01480
01481 update_cols[u_local_cseq_col= n_update_cols]= &str_local_cseq_col;
01482 update_vals[u_local_cseq_col].type = DB_INT;
01483 update_vals[u_local_cseq_col].nul = 0;
01484 n_update_cols++;
01485
01486 update_cols[u_version_col= n_update_cols]= &str_version_col;
01487 update_vals[u_version_col].type = DB_INT;
01488 update_vals[u_version_col].nul = 0;
01489 n_update_cols++;
01490
01491
01492 if(db== NULL)
01493 {
01494 LM_ERR("null database connection\n");
01495 return;
01496 }
01497 for(i=0; i<htable_size; i++)
01498 {
01499 if(!no_lock)
01500 lock_get(&hash_table[i].lock);
01501
01502 prev_s= hash_table[i].entries;
01503 s= prev_s->next;
01504
01505 while(s)
01506 {
01507 printf_subs(s);
01508 if(s->expires < (int)time(NULL)- 50)
01509 {
01510 LM_DBG("Found expired record\n");
01511 if(!no_lock)
01512 {
01513 if(handle_expired_func(s)< 0)
01514 {
01515 LM_ERR("in function handle_expired_record\n");
01516 if(!no_lock)
01517 lock_release(&hash_table[i].lock);
01518 return ;
01519 }
01520 }
01521 del_s= s;
01522 s= s->next;
01523 prev_s->next= s;
01524
01525
01526 if (del_s->contact.s)
01527 shm_free(del_s->contact.s);
01528
01529 shm_free(del_s);
01530 continue;
01531 }
01532 switch(s->db_flag)
01533 {
01534 case NO_UPDATEDB_FLAG:
01535 {
01536 LM_DBG("NO_UPDATEDB_FLAG\n");
01537 break;
01538 }
01539 case UPDATEDB_FLAG:
01540 {
01541 LM_DBG("UPDATEDB_FLAG\n");
01542
01543 query_vals[pres_uri_col].val.str_val= s->pres_uri;
01544 query_vals[callid_col].val.str_val= s->callid;
01545 query_vals[totag_col].val.str_val= s->to_tag;
01546 query_vals[fromtag_col].val.str_val= s->from_tag;
01547
01548 update_vals[u_expires_col].val.int_val= s->expires;
01549 update_vals[u_local_cseq_col].val.int_val= s->local_cseq;
01550 update_vals[u_remote_cseq_col].val.int_val= s->remote_cseq;
01551 update_vals[u_version_col].val.int_val= s->version;
01552 update_vals[u_status_col].val.int_val= s->status;
01553 update_vals[u_reason_col].val.str_val= s->reason;
01554
01555 if(dbf.update(db, query_cols, 0, query_vals, update_cols,
01556 update_vals, n_query_update, n_update_cols)< 0)
01557 {
01558 LM_ERR("updating in database\n");
01559 if(!no_lock)
01560 lock_release(&hash_table[i].lock);
01561 return ;
01562 }
01563 break;
01564 }
01565 case INSERTDB_FLAG:
01566 {
01567 LM_DBG("INSERTDB_FLAG\n");
01568
01569 query_vals[pres_uri_col].val.str_val= s->pres_uri;
01570 query_vals[callid_col].val.str_val= s->callid;
01571 query_vals[totag_col].val.str_val= s->to_tag;
01572 query_vals[fromtag_col].val.str_val= s->from_tag;
01573 query_vals[to_user_col].val.str_val = s->to_user;
01574 query_vals[to_domain_col].val.str_val = s->to_domain;
01575 query_vals[from_user_col].val.str_val = s->from_user;
01576 query_vals[from_domain_col].val.str_val = s->from_domain;
01577 query_vals[event_col].val.str_val = s->event->name;
01578 query_vals[event_id_col].val.str_val = s->event_id;
01579 query_vals[local_cseq_col].val.int_val= s->local_cseq;
01580 query_vals[remote_cseq_col].val.int_val= s->remote_cseq;
01581 query_vals[expires_col].val.int_val = s->expires;
01582 query_vals[record_route_col].val.str_val = s->record_route;
01583 query_vals[contact_col].val.str_val = s->contact;
01584 query_vals[local_contact_col].val.str_val = s->local_contact;
01585 query_vals[version_col].val.int_val= s->version;
01586 query_vals[status_col].val.int_val= s->status;
01587 query_vals[reason_col].val.str_val= s->reason;
01588 query_vals[socket_info_col].val.str_val= s->sockinfo_str;
01589
01590 if(dbf.insert(db,query_cols,query_vals,n_query_cols )<0)
01591 {
01592 LM_ERR("unsuccessful sql insert\n");
01593 if(!no_lock)
01594 lock_release(&hash_table[i].lock);
01595 return ;
01596 }
01597 break;
01598 }
01599
01600 }
01601 s->db_flag= NO_UPDATEDB_FLAG;
01602 prev_s= s;
01603 s= s->next;
01604 }
01605 if(!no_lock)
01606 lock_release(&hash_table[i].lock);
01607 }
01608
01609 update_vals[0].val.int_val= (int)time(NULL)- 10;
01610 update_ops[0]= OP_LT;
01611 if(dbf.delete(db, update_cols, update_ops, update_vals, 1) < 0)
01612 {
01613 LM_ERR("deleting expired information from database\n");
01614 }
01615
01616 }
01617
01618 int restore_db_subs(void)
01619 {
01620 db_key_t result_cols[22];
01621 db_res_t *res= NULL;
01622 db_row_t *row = NULL;
01623 db_val_t *row_vals= NULL;
01624 int i;
01625 int n_result_cols= 0;
01626 int pres_uri_col, expires_col, from_user_col, from_domain_col,to_user_col;
01627 int callid_col,totag_col,fromtag_col,to_domain_col,sockinfo_col,reason_col;
01628 int event_col,contact_col,record_route_col, event_id_col, status_col;
01629 int remote_cseq_col, local_cseq_col, local_contact_col, version_col;
01630 subs_t s;
01631 str ev_sname;
01632 pres_ev_t* event= NULL;
01633 event_t parsed_event;
01634 unsigned int expires;
01635 unsigned int hash_code;
01636
01637 result_cols[pres_uri_col=n_result_cols++] =&str_presentity_uri_col;
01638 result_cols[expires_col=n_result_cols++]=&str_expires_col;
01639 result_cols[event_col=n_result_cols++] =&str_event_col;
01640 result_cols[event_id_col=n_result_cols++]=&str_event_id_col;
01641 result_cols[to_user_col=n_result_cols++] =&str_to_user_col;
01642 result_cols[to_domain_col=n_result_cols++] =&str_to_domain_col;
01643 result_cols[from_user_col=n_result_cols++] =&str_watcher_username_col;
01644 result_cols[from_domain_col=n_result_cols++]=&str_watcher_domain_col;
01645 result_cols[callid_col=n_result_cols++] =&str_callid_col;
01646 result_cols[totag_col=n_result_cols++] =&str_to_tag_col;
01647 result_cols[fromtag_col=n_result_cols++]=&str_from_tag_col;
01648 result_cols[local_cseq_col= n_result_cols++] =&str_local_cseq_col;
01649 result_cols[remote_cseq_col= n_result_cols++] =&str_remote_cseq_col;
01650 result_cols[record_route_col= n_result_cols++] =&str_record_route_col;
01651 result_cols[sockinfo_col= n_result_cols++] =&str_socket_info_col;
01652 result_cols[contact_col= n_result_cols++] =&str_contact_col;
01653 result_cols[local_contact_col= n_result_cols++] =&str_local_contact_col;
01654 result_cols[version_col= n_result_cols++] =&str_version_col;
01655 result_cols[status_col= n_result_cols++] =&str_status_col;
01656 result_cols[reason_col= n_result_cols++] =&str_reason_col;
01657
01658 if(!pa_db)
01659 {
01660 LM_ERR("null database connection\n");
01661 return -1;
01662 }
01663
01664 if(pa_dbf.use_table(pa_db, &active_watchers_table)< 0)
01665 {
01666 LM_ERR("in use table\n");
01667 return -1;
01668 }
01669
01670 if(pa_dbf.query(pa_db,0, 0, 0, result_cols,0, n_result_cols, 0,&res)< 0)
01671 {
01672 LM_ERR("while querrying table\n");
01673 if(res)
01674 {
01675 pa_dbf.free_result(pa_db, res);
01676 res = NULL;
01677 }
01678 return -1;
01679 }
01680 if(res== NULL)
01681 return -1;
01682
01683 if(res->n<=0)
01684 {
01685 LM_INFO("The query returned no result\n");
01686 pa_dbf.free_result(pa_db, res);
01687 res = NULL;
01688 return 0;
01689 }
01690
01691 LM_DBG("found %d db entries\n", res->n);
01692
01693 for(i =0 ; i< res->n ; i++)
01694 {
01695 row = &res->rows[i];
01696 row_vals = ROW_VALUES(row);
01697 memset(&s, 0, sizeof(subs_t));
01698
01699 expires= row_vals[expires_col].val.int_val;
01700
01701 if(expires< (int)time(NULL))
01702 continue;
01703
01704 s.pres_uri.s= (char*)row_vals[pres_uri_col].val.string_val;
01705 s.pres_uri.len= strlen(s.pres_uri.s);
01706
01707 s.to_user.s=(char*)row_vals[to_user_col].val.string_val;
01708 s.to_user.len= strlen(s.to_user.s);
01709
01710 s.to_domain.s=(char*)row_vals[to_domain_col].val.string_val;
01711 s.to_domain.len= strlen(s.to_domain.s);
01712
01713 s.from_user.s=(char*)row_vals[from_user_col].val.string_val;
01714 s.from_user.len= strlen(s.from_user.s);
01715
01716 s.from_domain.s=(char*)row_vals[from_domain_col].val.string_val;
01717 s.from_domain.len= strlen(s.from_domain.s);
01718
01719 s.to_tag.s=(char*)row_vals[totag_col].val.string_val;
01720 s.to_tag.len= strlen(s.to_tag.s);
01721
01722 s.from_tag.s=(char*)row_vals[fromtag_col].val.string_val;
01723 s.from_tag.len= strlen(s.from_tag.s);
01724
01725 s.callid.s=(char*)row_vals[callid_col].val.string_val;
01726 s.callid.len= strlen(s.callid.s);
01727
01728 ev_sname.s= (char*)row_vals[event_col].val.string_val;
01729 ev_sname.len= strlen(ev_sname.s);
01730
01731 event= contains_event(&ev_sname, &parsed_event);
01732 if(event== NULL)
01733 {
01734 LM_DBG("insert a new event structure in the list waiting"
01735 " to be filled in\n");
01736
01737
01738 event= (pres_ev_t*)shm_malloc(sizeof(pres_ev_t));
01739 if(event== NULL)
01740 {
01741 free_event_params(parsed_event.params, PKG_MEM_TYPE);
01742 ERR_MEM(SHM_MEM_STR);
01743 }
01744 memset(event, 0, sizeof(pres_ev_t));
01745 event->name.s= (char*)shm_malloc(ev_sname.len* sizeof(char));
01746 if(event->name.s== NULL)
01747 {
01748 free_event_params(parsed_event.params, PKG_MEM_TYPE);
01749 ERR_MEM(SHM_MEM_STR);
01750 }
01751 memcpy(event->name.s,ev_sname.s, ev_sname.len);
01752 event->name.len= ev_sname.len;
01753
01754 event->evp= shm_copy_event(&parsed_event);
01755 if(event->evp== NULL)
01756 {
01757 LM_ERR("ERROR copying event_t structure\n");
01758 free_event_params(parsed_event.params, PKG_MEM_TYPE);
01759 goto error;
01760 }
01761 event->next= EvList->events;
01762 EvList->events= event;
01763 }
01764
01765 free_event_params(parsed_event.params, PKG_MEM_TYPE);
01766
01767 s.event= event;
01768
01769 s.event_id.s=(char*)row_vals[event_id_col].val.string_val;
01770 if(s.event_id.s)
01771 s.event_id.len= strlen(s.event_id.s);
01772
01773 s.remote_cseq= row_vals[remote_cseq_col].val.int_val;
01774 s.local_cseq= row_vals[local_cseq_col].val.int_val;
01775 s.version= row_vals[version_col].val.int_val;
01776
01777 s.expires= expires- (int)time(NULL);
01778 s.status= row_vals[status_col].val.int_val;
01779
01780 s.reason.s= (char*)row_vals[reason_col].val.string_val;
01781 if(s.reason.s)
01782 s.reason.len= strlen(s.reason.s);
01783
01784 s.contact.s=(char*)row_vals[contact_col].val.string_val;
01785 s.contact.len= strlen(s.contact.s);
01786
01787 s.local_contact.s=(char*)row_vals[local_contact_col].val.string_val;
01788 s.local_contact.len= strlen(s.local_contact.s);
01789
01790 s.record_route.s=(char*)row_vals[record_route_col].val.string_val;
01791 if(s.record_route.s)
01792 s.record_route.len= strlen(s.record_route.s);
01793
01794 s.sockinfo_str.s=(char*)row_vals[sockinfo_col].val.string_val;
01795 s.sockinfo_str.len= strlen(s.sockinfo_str.s);
01796
01797 hash_code= core_hash(&s.pres_uri, &s.event->name, shtable_size);
01798 if(insert_shtable(subs_htable, hash_code, &s)< 0)
01799 {
01800 LM_ERR("adding new record in hash table\n");
01801 goto error;
01802 }
01803 }
01804
01805 pa_dbf.free_result(pa_db, res);
01806
01807
01808 if(pa_dbf.delete(pa_db, 0,0,0,0)< 0)
01809 {
01810 LM_ERR("deleting all records from database table\n");
01811 return -1;
01812 }
01813
01814 return 0;
01815
01816 error:
01817 if(res)
01818 pa_dbf.free_result(pa_db, res);
01819 return -1;
01820
01821 }
01822
01823 int refresh_watcher(str* pres_uri, str* watcher_uri, str* event,
01824 int status, str* reason)
01825 {
01826 unsigned int hash_code;
01827 subs_t* s, *s_copy;
01828 pres_ev_t* ev;
01829 struct sip_uri uri;
01830 str user, domain;
01831
01832
01833 ev= contains_event(event, NULL);
01834 if(ev== NULL)
01835 {
01836 LM_ERR("while searching event in list\n");
01837 return -1;
01838 }
01839
01840 if(parse_uri(watcher_uri->s, watcher_uri->len, &uri)< 0)
01841 {
01842 LM_ERR("parsing uri\n");
01843 return -1;
01844 }
01845 user= uri.user;
01846 domain= uri.host;
01847
01848 hash_code= core_hash(pres_uri, event, shtable_size);
01849
01850 lock_get(&subs_htable[hash_code].lock);
01851
01852 s= subs_htable[hash_code].entries->next;
01853
01854 while(s)
01855 {
01856 if(s->event== ev && s->pres_uri.len== pres_uri->len &&
01857 strncmp(s->pres_uri.s, pres_uri->s, pres_uri->len)== 0 &&
01858 s->from_user.len==user.len && strncmp(s->from_user.s,user.s, user.len)==0 &&
01859 s->from_domain.len== domain.len &&
01860 strncmp(s->from_domain.s, domain.s, domain.len)== 0)
01861 {
01862 s->status= status;
01863 if(reason)
01864 s->reason= *reason;
01865
01866 s_copy= mem_copy_subs(s, PKG_MEM_TYPE);
01867 if(s_copy== NULL)
01868 {
01869 LM_ERR("copying subs_t\n");
01870 lock_release(&subs_htable[hash_code].lock);
01871 return -1;
01872 }
01873 lock_release(&subs_htable[hash_code].lock);
01874 if(notify(s_copy, NULL, NULL, 0)< 0)
01875 {
01876 LM_ERR("in notify function\n");
01877 pkg_free(s_copy);
01878 return -1;
01879 }
01880 pkg_free(s_copy);
01881 lock_get(&subs_htable[hash_code].lock);
01882 }
01883 s= s->next;
01884 }
01885 return 0;
01886 }
01887
01888 int get_db_subs_auth(subs_t* subs, int* found)
01889 {
01890 db_key_t db_keys[5];
01891 db_val_t db_vals[5];
01892 int n_query_cols= 0;
01893 db_key_t result_cols[3];
01894 db_res_t *result = NULL;
01895 db_row_t *row ;
01896 db_val_t *row_vals ;
01897
01898 db_keys[n_query_cols] =&str_presentity_uri_col;
01899 db_vals[n_query_cols].type = DB_STR;
01900 db_vals[n_query_cols].nul = 0;
01901 db_vals[n_query_cols].val.str_val= subs->pres_uri;
01902 n_query_cols++;
01903
01904 db_keys[n_query_cols] =&str_watcher_username_col;
01905 db_vals[n_query_cols].type = DB_STR;
01906 db_vals[n_query_cols].nul = 0;
01907 db_vals[n_query_cols].val.str_val = subs->from_user;
01908 n_query_cols++;
01909
01910 db_keys[n_query_cols] =&str_watcher_domain_col;
01911 db_vals[n_query_cols].type = DB_STR;
01912 db_vals[n_query_cols].nul = 0;
01913 db_vals[n_query_cols].val.str_val = subs->from_domain;
01914 n_query_cols++;
01915
01916 db_keys[n_query_cols] =&str_event_col;
01917 db_vals[n_query_cols].type = DB_STR;
01918 db_vals[n_query_cols].nul = 0;
01919 db_vals[n_query_cols].val.str_val = subs->event->name;
01920 n_query_cols++;
01921
01922 result_cols[0] = &str_status_col;
01923 result_cols[1] = &str_reason_col;
01924
01925 if(pa_dbf.use_table(pa_db, &watchers_table)< 0)
01926 {
01927 LM_ERR("in use table\n");
01928 return -1;
01929 }
01930
01931 if(pa_dbf.query(pa_db, db_keys, 0, db_vals, result_cols,
01932 n_query_cols, 2, 0, &result )< 0)
01933 {
01934 LM_ERR("while querying watchers table\n");
01935 if(result)
01936 pa_dbf.free_result(pa_db, result);
01937 return -1;
01938 }
01939 if(result== NULL)
01940 return -1;
01941
01942 if(result->n<= 0)
01943 {
01944 *found= 0;
01945 pa_dbf.free_result(pa_db, result);
01946 return 0;
01947 }
01948
01949 *found= 1;
01950 row = &result->rows[0];
01951 row_vals = ROW_VALUES(row);
01952 subs->status= row_vals[0].val.int_val;
01953
01954 if(row_vals[1].val.string_val)
01955 {
01956
01957 subs->reason.len= strlen(row_vals[1].val.string_val);
01958 if(subs->reason.len== 0)
01959 subs->reason.s= NULL;
01960 else
01961 {
01962 subs->reason.s= (char*)pkg_malloc(subs->reason.len*sizeof(char));
01963 if(subs->reason.s== NULL)
01964 {
01965 pa_dbf.free_result(pa_db, result);
01966 ERR_MEM(PKG_MEM_STR);
01967 }
01968 memcpy(subs->reason.s, row_vals[1].val.string_val, subs->reason.len);
01969 }
01970 }
01971
01972 pa_dbf.free_result(pa_db, result);
01973 return 0;
01974 error:
01975 return -1;
01976 }
01977
01978 int insert_db_subs_auth(subs_t* subs)
01979 {
01980 db_key_t db_keys[10];
01981 db_val_t db_vals[10];
01982 int n_query_cols= 0;
01983
01984 db_keys[n_query_cols] =&str_presentity_uri_col;
01985 db_vals[n_query_cols].type = DB_STR;
01986 db_vals[n_query_cols].nul = 0;
01987 db_vals[n_query_cols].val.str_val= subs->pres_uri;
01988 n_query_cols++;
01989
01990 db_keys[n_query_cols] =&str_watcher_username_col;
01991 db_vals[n_query_cols].type = DB_STR;
01992 db_vals[n_query_cols].nul = 0;
01993 db_vals[n_query_cols].val.str_val = subs->from_user;
01994 n_query_cols++;
01995
01996 db_keys[n_query_cols] =&str_watcher_domain_col;
01997 db_vals[n_query_cols].type = DB_STR;
01998 db_vals[n_query_cols].nul = 0;
01999 db_vals[n_query_cols].val.str_val = subs->from_domain;
02000 n_query_cols++;
02001
02002 db_keys[n_query_cols] =&str_event_col;
02003 db_vals[n_query_cols].type = DB_STR;
02004 db_vals[n_query_cols].nul = 0;
02005 db_vals[n_query_cols].val.str_val = subs->event->name;
02006 n_query_cols++;
02007
02008 db_keys[n_query_cols] =&str_status_col;
02009 db_vals[n_query_cols].type = DB_INT;
02010 db_vals[n_query_cols].nul = 0;
02011 db_vals[n_query_cols].val.int_val = subs->status;
02012 n_query_cols++;
02013
02014 db_keys[n_query_cols] = &str_inserted_time_col;
02015 db_vals[n_query_cols].type = DB_INT;
02016 db_vals[n_query_cols].nul = 0;
02017 db_vals[n_query_cols].val.int_val= (int)time(NULL);
02018 n_query_cols++;
02019
02020 if(subs->reason.s && subs->reason.len)
02021 {
02022 db_keys[n_query_cols] =&str_reason_col;
02023 db_vals[n_query_cols].type = DB_STR;
02024 db_vals[n_query_cols].nul = 0;
02025 db_vals[n_query_cols].val.str_val = subs->reason;
02026 n_query_cols++;
02027 }
02028
02029 if (pa_dbf.use_table(pa_db, &watchers_table) < 0)
02030 {
02031 LM_ERR("in use_table\n");
02032 return -1;
02033 }
02034
02035 if(pa_dbf.insert(pa_db, db_keys, db_vals, n_query_cols )< 0)
02036 {
02037 LM_ERR("in sql insert\n");
02038 return -1;
02039 }
02040
02041 return 0;
02042 }