#include "pa_mod.h" #include "async_auth.h" #include "../../timer.h" int async_timer_interval = 1; int max_auth_requests_per_tick = 50; int async_auth_queries = 0; static msg_queue_t *async_mq = NULL; typedef struct { str uid; struct pdomain *d; char buf[1]; } async_auth_query_t; int xcap_get_pres_rules(str *uid, cp_ruleset_t **dst, xcap_query_params_t *xcap) { int res; str *filename = NULL; /* str u; */ if (!is_str_empty(&pres_rules_file)) filename = &pres_rules_file; res = get_pres_rules(uid, filename, xcap, dst); return res; } static inline void query_auth_rules(async_auth_query_t *params) { presence_rules_t *rules; presentity_t *p; lock_pdomain(params->d); if (find_presentity_uid(params->d, ¶ms->uid, &p) == 0) { p->ref_cnt++; } else p = NULL; unlock_pdomain(params->d); if (p) { rules = NULL; /* we can use p->xcap_params because it doesn't change * till the presentity dies */ xcap_get_pres_rules(¶ms->uid, &rules, &p->xcap_params); lock_pdomain(params->d); /*if (rules)*/ set_auth_rules(p, rules); p->ref_cnt--; unlock_pdomain(params->d); } } static void async_timer_cb(unsigned int ticks, void *param) { mq_message_t *msg; async_auth_query_t *params; int cnt = 0; /* TODO: dynamicaly set max_xcap_requests according to * load, free mem, ... */ /* process queries in message queue */ /* the number of processed queries may be limited for one step */ msg = pop_message(async_mq); while (msg) { /* INFO("processing authorization rules query\n"); */ params = (async_auth_query_t*)get_message_data(msg); if (params) query_auth_rules(params); free_message(msg); if (++cnt > max_auth_requests_per_tick) break; msg = pop_message(async_mq); } } int async_auth_timer_init() { if (register_timer(async_timer_cb, NULL, async_timer_interval) < 0) { LOG(L_ERR, "vs_init(): can't register timer\n"); return -1; } async_mq = shm_malloc(sizeof(*async_mq)); if (!async_mq) { ERR("can't allocate memory\n"); return -1; } msg_queue_init(async_mq); return 0; } int ask_auth_rules(presentity_t *p) { int len, res; mq_message_t *msg; async_auth_query_t *params; presence_rules_t *rules = NULL; /* ! call from critical section locked by pdomain mutex ! */ if (pa_auth_params.type != auth_xcap) { return 0; /* don't load anything */ } if (!async_auth_queries) { /* do synchronous query - it is called from locked section, * thus it is not good for performance! */ res = xcap_get_pres_rules(&p->uuid, &rules, &p->xcap_params); if (res == RES_OK) set_auth_rules(p, rules); return res; } /* Ask for authorization rules (only XCAP now). This should be done * asynchronously, at least for time consuming operations like XCAP * queries */ len = sizeof(async_auth_query_t) + p->uuid.len; msg = create_message_ex(len); if (!msg) { ERR("can't allocate memory (%d bytes)\n", len); return -1; } params = (async_auth_query_t*)get_message_data(msg); params->uid.s = params->buf; params->d = p->pdomain; if (!is_str_empty(&p->uuid)) { params->uid.len = p->uuid.len; memcpy(params->uid.s, p->uuid.s, p->uuid.len); } else params->uid.len = 0; push_message(async_mq, msg); /* INFO("asking authorization rules\n"); */ return 0; }