123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- #include "rls_mod.h"
- #include "../../sr_module.h"
- #include "../../timer_ticks.h"
- #include "../../mem/mem.h"
- #include "../../mem/shm_mem.h"
- #include <libxml/parser.h>
- #include <cds/memory.h>
- #include <cds/ptr_vector.h>
- #include <cds/logger.h>
- #include <cds/cds.h>
- #include <presence/qsa.h>
- #include "rl_subscription.h"
- #include "rls_handler.h"
- #include "rpc.h"
- #include "uri_ops.h"
- #include "time_event_manager.h"
- #include <time.h>
- MODULE_VERSION
- int rls_mod_init(void);
- void rls_mod_destroy(void);
- int rls_child_init(int _rank);
- static int rls_subscribe_fixup(void** param, int param_no);
- /* authorization parameters */
- char *auth_type_str = NULL; /* type of authorization: none,implicit,xcap */
- int db_mode = 0; /* 0 -> no DB, 1 -> write through */
- char *db_url = NULL;
- int reduce_xcap_needs = 0;
- /* internal data members */
- /* static ptr_vector_t *xcap_servers = NULL; */
- db_con_t* rls_db = NULL; /* database connection handle */
- db_func_t rls_dbf; /* database functions */
- /* one shot timer for reloading data from DB -
- they can not be reloaded in init or
- child_init due to internal subscriptions
- to other modules (may be not itialised
- yet) */
- static int init_timer_delay = 3;
- /* parameters for optimizations */
- int max_notifications_at_once = 1000000;
- /* timer for processing notifications from QSA */
- int rls_timer_interval = 10;
- /* ignore if NOTIFY times out (don't destroy subscription */
- int rls_ignore_408_on_notify = 0;
- /* maximum nested list level (if 0, no nested lists are possible,
- * if 1 only one nested list level is possible, if 2 it is possible to
- * have lists in lists, ..., unlimited if -1) */
- int max_list_nesting_level = -1;
- /** Exported functions */
- static cmd_export_t cmds[]={
- /* {"handle_r_subscription", handle_r_subscription, 0, subscribe_fixup, REQUEST_ROUTE | FAILURE_ROUTE}, */
- {"handle_rls_subscription", (cmd_function)handle_rls_subscription, 1,
- rls_subscribe_fixup, REQUEST_ROUTE | FAILURE_ROUTE},
- {"is_simple_rls_target", is_simple_rls_target, 1, NULL, REQUEST_ROUTE | FAILURE_ROUTE},
- {"query_rls_services", query_rls_services, 0, NULL, REQUEST_ROUTE | FAILURE_ROUTE},
- {"query_resource_list", query_resource_list, 1, NULL, REQUEST_ROUTE | FAILURE_ROUTE},
- {"have_flat_list", have_flat_list, 0, NULL, REQUEST_ROUTE | FAILURE_ROUTE},
- {0, 0, 0, 0, 0}
- };
- /** Exported parameters */
- static param_export_t params[]={
- {"min_expiration", PARAM_INT, &rls_min_expiration },
- {"max_expiration", PARAM_INT, &rls_max_expiration },
- {"default_expiration", PARAM_INT, &rls_default_expiration },
- {"auth", PARAM_STRING, &auth_type_str }, /* type of authorization: none, implicit, xcap, ... */
- {"db_mode", PARAM_INT, &db_mode },
- {"db_url", PARAM_STRING, &db_url },
- {"reduce_xcap_needs", PARAM_INT, &reduce_xcap_needs },
- {"max_notifications_at_once", PARAM_INT, &max_notifications_at_once },
- {"timer_interval", PARAM_INT, &rls_timer_interval },
- {"max_list_nesting_level", PARAM_INT, &max_list_nesting_level },
- {"expiration_timer_period", PARAM_INT, &rls_expiration_timer_period },
- {"ignore_408_on_notify", PARAM_INT, &rls_ignore_408_on_notify },
- {"init_timer_delay", PARAM_INT, &init_timer_delay }, /* timer for delayed DB reload (due to internal subscriptions can't be reloaded from init or child init) */
-
- {0, 0, 0}
- };
- struct module_exports exports = {
- "rls",
- cmds, /* Exported functions */
- rls_rpc_methods, /* RPC methods */
- params, /* Exported parameters */
- rls_mod_init, /* module initialization function */
- 0, /* response function*/
- rls_mod_destroy, /* pa_destroy, / * destroy function */
- 0, /* oncancel function */
- rls_child_init /* per-child init function */
- };
- struct tm_binds tmb;
- dlg_func_t dlg_func;
- fill_xcap_params_func fill_xcap_params = NULL;
- int use_db = 0;
- int rls_min_expiration = 60;
- int rls_max_expiration = 7200;
- int rls_default_expiration = 3761;
- int rls_expiration_timer_period = 10;
- rls_auth_params_t rls_auth_params; /* structure filled according to parameters (common for all XCAP servers now) */
- char *xcap_server = NULL; /* XCAP server URI */
- /* TODO: settings of other xcap parameters (auth, ssl, ...) */
- static int set_auth_params(rls_auth_params_t *dst, const char *auth_type_str)
- {
- if (!auth_type_str) {
- LOG(L_ERR, "no subscription authorization type given, using \'implicit\'!\n");
- dst->type = rls_auth_none;
- return 0;
- }
- if (strcmp(auth_type_str, "xcap") == 0) {
- dst->type = rls_auth_xcap;
- return 0;
- }
- if (strcmp(auth_type_str, "none") == 0) {
- dst->type = rls_auth_none;
- LOG(L_WARN, "using \'none\' rls-subscription authorization!\n");
- return 0;
- }
- if (strcmp(auth_type_str, "implicit") == 0) {
- dst->type = rls_auth_implicit;
- return 0;
- }
- LOG(L_ERR, "Can't resolve subscription authorization type: \'%s\'."
- " Use one of: none, implicit, xcap.\n", auth_type_str);
- return -1;
- }
- static ticks_t init_timer_cb(ticks_t ticks, struct timer_ln* tl, void* data)
- {
- /* initialization (like read data from database) which can trigger
- * database operations in other modules/... */
- if (use_db && (rls_db)) {
- INFO("reading RLS data from database\n");
- rls_lock();
- db_load_rls();
- rls_unlock();
- }
- if (data) {
- mem_free(data);
- /* ERR("freeing myself!\n"); */
- }
-
- return 0; /* one shot timer */
- }
- int rls_mod_init(void)
- {
- load_tm_f load_tm;
- bind_dlg_mod_f bind_dlg;
- struct timer_ln *i_timer = NULL;
- DEBUG_LOG("RLS module initialization\n");
- /* ??? if other module uses this libraries it might be a problem ??? */
- xmlInitParser();
- DEBUG_LOG(" ... common libraries\n");
- qsa_initialize();
- if (time_event_management_init() != 0) {
- LOG(L_ERR, "rls_mod_init(): Can't initialize time event management!\n");
- return -1;
- }
- if (subscription_management_init() != 0) {
- LOG(L_ERR, "rls_mod_init(): Can't initialize time event management!\n");
- return -1;
- }
- /* import the TM auto-loading function */
- if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {
- LOG(L_ERR, "rls_mod_init(): Can't import tm!\n");
- return -1;
- }
- /* let the auto-loading function load all TM stuff */
- if (load_tm(&tmb)==-1) {
- LOG(L_ERR, "rls_mod_init(): load_tm() failed\n");
- return -1;
- }
- bind_dlg = (bind_dlg_mod_f)find_export("bind_dlg_mod", -1, 0);
- if (!bind_dlg) {
- LOG(L_ERR, "Can't import dlg\n");
- return -1;
- }
- if (bind_dlg(&dlg_func) != 0) {
- return -1;
- }
- if (rls_init() != 0) {
- return -1;
- }
- if (vs_init() != 0) {
- return -1;
- }
- /* xcap_servers = (ptr_vector_t*)mem_alloc(sizeof(ptr_vector_t));
- if (!xcap_servers) {
- LOG(L_ERR, "rls_mod_init(): can't allocate memory for XCAP servers vector\n");
- return -1;
- }
- ptr_vector_init(xcap_servers, 8); */
- /* set authorization type according to requested "auth type name"
- * and other (type specific) parameters */
- if (set_auth_params(&rls_auth_params, auth_type_str) != 0) return -1;
- use_db = 0;
- if (db_mode > 0) {
- int db_url_len = db_url ? strlen(db_url) : 0;
- if (!db_url_len) {
- LOG(L_ERR, "rls_mod_init(): no db_url specified but db_mode > 0\n");
- db_mode = 0;
- }
- }
- if (db_mode > 0) {
- if (bind_dbmod(db_url, &rls_dbf) < 0) {
- LOG(L_ERR, "rls_mod_init(): Can't bind database module via url %s\n", db_url);
- return -1;
- }
- if (!DB_CAPABILITY(rls_dbf, DB_CAP_ALL)) { /* ? */
- LOG(L_ERR, "rls_mod_init(): Database module does not implement all functions needed by the module\n");
- return -1;
- }
- use_db = 1;
- }
- /* once-shot timer for reloading data from DB -
- * needed because it can trigger database operations
- * in other modules and they mostly intialize their
- * database connection in child_init functions */
-
- i_timer = timer_alloc();
- if (!i_timer) {
- ERR("can't allocate memory for DB init timer\n");
- return -1;
- }
- else {
- timer_init(i_timer, init_timer_cb, i_timer, 0);
- timer_add(i_timer, S_TO_TICKS(init_timer_delay));
- }
-
- fill_xcap_params = (fill_xcap_params_func)find_export("fill_xcap_params", 0, -1);
-
- return 0;
- }
- int rls_child_init(int _rank)
- {
- rls_db = NULL;
- if (use_db) {
- if (_rank==PROC_INIT || _rank==PROC_MAIN || _rank==PROC_TCP_MAIN)
- return 0; /* do nothing for the main or tcp_main processes */
- if (rls_dbf.init) rls_db = rls_dbf.init(db_url);
- if (!rls_db) {
- LOG(L_ERR, "ERROR: rls_child_init(%d): "
- "Error while connecting database\n", _rank);
- return -1;
- }
- /* if (_rank == 0) {
- rls_lock();
- db_load_rls();
- rls_unlock();
- } */
- }
- return 0;
- }
- void rls_mod_destroy(void)
- {
- /*int i, cnt;
- char *s;*/
- DEBUG_LOG("RLS module cleanup\n");
- /* destroy used XCAP servers */
- /* DEBUG_LOG(" ... xcap servers\n");
- if (xcap_servers) {
- cnt = ptr_vector_size(xcap_servers);
- DEBUG_LOG(" count = %d\n", cnt);
- for (i = 0; i < cnt; i++) {
- s = ptr_vector_get(xcap_servers, i);
- if (s) {
- DEBUG_LOG(" ... freeing %s (%p)\n", s, s);
- cds_free(s);
- }
- }
- ptr_vector_destroy(xcap_servers);
- mem_free(xcap_servers);
- xcap_servers = NULL;
- } */
- DEBUG_LOG(" ... rls\n");
- rls_destroy();
- DEBUG_LOG(" ... vs\n");
- vs_destroy();
- DEBUG_LOG(" ... time event management\n");
- time_event_management_destroy();
- DEBUG_LOG(" %s: ... db\n", __func__);
- if (use_db) {
- if (rls_db && rls_dbf.close) rls_dbf.close(rls_db);
- rls_db = NULL;
- }
- DEBUG_LOG(" ... common libs\n");
- qsa_cleanup();
- /* ??? if other module uses this libraries it might be a problem ??? */
- /* xmlCleanupParser(); */
- DEBUG_LOG("RLS module cleanup finished\n");
- }
- static int rls_subscribe_fixup(void** param, int param_no)
- {
- /* char *xcap_server = NULL; */
- long send_errors = 0;
- /* if (param_no == 1) {
- if (!param) {
- LOG(L_ERR, "rls_subscribe_fixup(): XCAP server address not set!\n");
- return E_UNSPEC;
- }
- xcap_server = zt_strdup((char *)*param);
- if (!xcap_server) {
- LOG(L_ERR, "rls_subscribe_fixup(): Can't set XCAP server address!\n");
- return E_UNSPEC;
- }
- / * store not only the root string? (create a structure rather?) * /
- ptr_vector_add(xcap_servers, xcap_server);
- DEBUG_LOG("rls_subscribe_fixup(): XCAP server is %s (%p)\n", xcap_server, xcap_server);
- *param = (void*)xcap_server;
- } */
- if (param_no == 1) {
- if (param) {
- if (*param) send_errors = atoi(*param);
- }
- DEBUG_LOG("rls_subscribe_fixup(): send errors: %ld\n", send_errors);
- *param = (void*)send_errors;
- }
- return 0;
- }
|