|
@@ -40,6 +40,7 @@
|
|
#include "usrloc.h"
|
|
#include "usrloc.h"
|
|
#include "utime.h"
|
|
#include "utime.h"
|
|
#include "usrloc.h"
|
|
#include "usrloc.h"
|
|
|
|
+#include "ul_callback.h"
|
|
#include "urecord.h"
|
|
#include "urecord.h"
|
|
|
|
|
|
extern int ul_rm_expired_delay;
|
|
extern int ul_rm_expired_delay;
|
|
@@ -886,6 +887,176 @@ done:
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*!
|
|
|
|
+ * \brief call contact expired call back for a domain with db_mode: DB_ONLY
|
|
|
|
+ *
|
|
|
|
+ * call contact expired call back for a domain with db_mode: DB_ONLY since
|
|
|
|
+ * database rows are removed by the timer function: db_timer_udomain
|
|
|
|
+ * \param _c database connection
|
|
|
|
+ * \param _d loaded domain
|
|
|
|
+ * \return 0 on success, -1 on failure
|
|
|
|
+ */
|
|
|
|
+int udomain_contact_expired_cb(db1_con_t* _c, udomain_t* _d)
|
|
|
|
+{
|
|
|
|
+ ucontact_info_t *ci;
|
|
|
|
+ db_row_t *row;
|
|
|
|
+ db_key_t columns[21], query_cols[3];
|
|
|
|
+ db_op_t query_ops[3];
|
|
|
|
+ db_val_t query_vals[3];
|
|
|
|
+ int key_num = 2;
|
|
|
|
+ db1_res_t* res = NULL;
|
|
|
|
+ str user, contact;
|
|
|
|
+ int i;
|
|
|
|
+ int n;
|
|
|
|
+ urecord_t* r;
|
|
|
|
+ ucontact_t* c;
|
|
|
|
+
|
|
|
|
+ if (db_mode!=DB_ONLY) {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ columns[0] = &user_col;
|
|
|
|
+ columns[1] = &contact_col;
|
|
|
|
+ columns[2] = &expires_col;
|
|
|
|
+ columns[3] = &q_col;
|
|
|
|
+ columns[4] = &callid_col;
|
|
|
|
+ columns[5] = &cseq_col;
|
|
|
|
+ columns[6] = &flags_col;
|
|
|
|
+ columns[7] = &cflags_col;
|
|
|
|
+ columns[8] = &user_agent_col;
|
|
|
|
+ columns[9] = &received_col;
|
|
|
|
+ columns[10] = &path_col;
|
|
|
|
+ columns[11] = &sock_col;
|
|
|
|
+ columns[12] = &methods_col;
|
|
|
|
+ columns[13] = &last_mod_col;
|
|
|
|
+ columns[14] = &ruid_col;
|
|
|
|
+ columns[15] = &instance_col;
|
|
|
|
+ columns[16] = ®_id_col;
|
|
|
|
+ columns[17] = &srv_id_col;
|
|
|
|
+ columns[18] = &con_id_col;
|
|
|
|
+ columns[19] = &keepalive_col;
|
|
|
|
+ columns[20] = &domain_col;
|
|
|
|
+
|
|
|
|
+ query_cols[0] = &expires_col;
|
|
|
|
+ query_ops[0] = "<";
|
|
|
|
+ query_vals[0].nul = 0;
|
|
|
|
+ UL_DB_EXPIRES_SET(&query_vals[0], act_time + 1 - ul_rm_expired_delay);
|
|
|
|
+
|
|
|
|
+ query_cols[1] = &expires_col;
|
|
|
|
+ query_ops[1] = OP_NEQ;
|
|
|
|
+ query_vals[1].nul = 0;
|
|
|
|
+ UL_DB_EXPIRES_SET(&query_vals[1], 0);
|
|
|
|
+
|
|
|
|
+ if (ul_db_srvid != 0) {
|
|
|
|
+ query_cols[2] = &srv_id_col;
|
|
|
|
+ query_ops[2] = OP_EQ;
|
|
|
|
+ query_vals[2].type = DB1_INT;
|
|
|
|
+ query_vals[2].nul = 0;
|
|
|
|
+ query_vals[2].val.int_val = server_id;
|
|
|
|
+ key_num = 3;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ul_dbf.use_table(_c, _d->name) < 0) {
|
|
|
|
+ LM_ERR("sql use_table failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifdef EXTRA_DEBUG
|
|
|
|
+ LM_NOTICE("udomain contact-expired start time [%d]\n", (int)time(NULL));
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
|
|
|
|
+ if (ul_dbf.query(_c, query_cols, query_ops, query_vals, columns, key_num, (use_domain)?(21):(20), 0,
|
|
|
|
+ 0) < 0) {
|
|
|
|
+ LM_ERR("db_query (1) failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
|
|
|
|
+ LM_ERR("fetching rows failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ if (ul_dbf.query(_c, query_cols, query_ops, query_vals, columns, key_num, (use_domain)?(21):(20), 0,
|
|
|
|
+ &res) < 0) {
|
|
|
|
+ LM_ERR("db_query failed\n");
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (RES_ROW_N(res) == 0) {
|
|
|
|
+ LM_DBG("no rows to be contact expired\n");
|
|
|
|
+ ul_dbf.free_result(_c, res);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ n = 0;
|
|
|
|
+ do {
|
|
|
|
+ LM_DBG("calling contact expired records - cycle [%d]\n", ++n);
|
|
|
|
+ for(i = 0; i < RES_ROW_N(res); i++) {
|
|
|
|
+ row = RES_ROWS(res) + i;
|
|
|
|
+
|
|
|
|
+ user.s = (char*)VAL_STRING(ROW_VALUES(row));
|
|
|
|
+ if (VAL_NULL(ROW_VALUES(row)) || user.s==0 || user.s[0]==0) {
|
|
|
|
+ LM_CRIT("empty username record in table %s...skipping\n",
|
|
|
|
+ _d->name->s);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ user.len = strlen(user.s);
|
|
|
|
+
|
|
|
|
+ ci = dbrow2info(ROW_VALUES(row)+1, &contact, 0);
|
|
|
|
+ if (ci==0) {
|
|
|
|
+ LM_CRIT("skipping record for %.*s in table %s\n",
|
|
|
|
+ user.len, user.s, _d->name->s);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lock_udomain(_d, &user);
|
|
|
|
+ if (get_urecord(_d, &user, &r) > 0) {
|
|
|
|
+ LM_ERR("failed to get a record\n");
|
|
|
|
+ unlock_udomain(_d, &user);
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( (c=mem_insert_ucontact(r, &contact, ci)) == 0) {
|
|
|
|
+ LM_ERR("inserting contact failed\n");
|
|
|
|
+ free_ucontact(c);
|
|
|
|
+ unlock_udomain(_d, &user);
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Call the contact-expired call-back if it exists for the contact */
|
|
|
|
+ if (exists_ulcb_type(UL_CONTACT_EXPIRE)) {
|
|
|
|
+ run_ul_callbacks( UL_CONTACT_EXPIRE, c);
|
|
|
|
+ }
|
|
|
|
+ c->state = CS_SYNC;
|
|
|
|
+ free_ucontact(c);
|
|
|
|
+ unlock_udomain(_d, &user);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (DB_CAPABILITY(ul_dbf, DB_CAP_FETCH)) {
|
|
|
|
+ if(ul_dbf.fetch_result(_c, &res, ul_fetch_rows)<0) {
|
|
|
|
+ LM_ERR("fetching rows (1) failed\n");
|
|
|
|
+ ul_dbf.free_result(_c, res);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } while(RES_ROW_N(res)>0);
|
|
|
|
+
|
|
|
|
+ ul_dbf.free_result(_c, res);
|
|
|
|
+
|
|
|
|
+#ifdef EXTRA_DEBUG
|
|
|
|
+ LM_NOTICE("udomain contact-expired end time [%d]\n", (int)time(NULL));
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+error:
|
|
|
|
+ ul_dbf.free_result(_c, res);
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
/*!
|
|
/*!
|
|
* \brief Timer function to cleanup expired contacts, db_mode: DB_ONLY
|
|
* \brief Timer function to cleanup expired contacts, db_mode: DB_ONLY
|
|
@@ -900,6 +1071,9 @@ int db_timer_udomain(udomain_t* _d)
|
|
db_val_t vals[3];
|
|
db_val_t vals[3];
|
|
int key_num = 2;
|
|
int key_num = 2;
|
|
|
|
|
|
|
|
+ /* call contact expired call back for a domain before deleting database rows */
|
|
|
|
+ udomain_contact_expired_cb(ul_dbh, _d);
|
|
|
|
+
|
|
keys[0] = &expires_col;
|
|
keys[0] = &expires_col;
|
|
ops[0] = "<";
|
|
ops[0] = "<";
|
|
vals[0].nul = 0;
|
|
vals[0].nul = 0;
|