async_auth.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "pa_mod.h"
  2. #include "async_auth.h"
  3. #include "../../timer.h"
  4. int async_timer_interval = 1;
  5. int max_auth_requests_per_tick = 50;
  6. int async_auth_queries = 0;
  7. static msg_queue_t *async_mq = NULL;
  8. typedef struct {
  9. str uid;
  10. struct pdomain *d;
  11. char buf[1];
  12. } async_auth_query_t;
  13. int xcap_get_pres_rules(str *uid, cp_ruleset_t **dst, xcap_query_params_t *xcap)
  14. {
  15. int res;
  16. str *filename = NULL;
  17. /* str u; */
  18. if (!is_str_empty(&pres_rules_file)) filename = &pres_rules_file;
  19. res = get_pres_rules(uid, filename, xcap, dst);
  20. return res;
  21. }
  22. static inline void query_auth_rules(async_auth_query_t *params)
  23. {
  24. presence_rules_t *rules;
  25. presentity_t *p;
  26. lock_pdomain(params->d);
  27. if (find_presentity_uid(params->d, &params->uid, &p) == 0) {
  28. p->ref_cnt++;
  29. }
  30. else p = NULL;
  31. unlock_pdomain(params->d);
  32. if (p) {
  33. rules = NULL;
  34. /* we can use p->xcap_params because it doesn't change
  35. * till the presentity dies */
  36. xcap_get_pres_rules(&params->uid, &rules, &p->xcap_params);
  37. lock_pdomain(params->d);
  38. /*if (rules)*/ set_auth_rules(p, rules);
  39. p->ref_cnt--;
  40. unlock_pdomain(params->d);
  41. }
  42. }
  43. static void async_timer_cb(unsigned int ticks, void *param)
  44. {
  45. mq_message_t *msg;
  46. async_auth_query_t *params;
  47. int cnt = 0;
  48. /* TODO: dynamicaly set max_xcap_requests according to
  49. * load, free mem, ... */
  50. /* process queries in message queue */
  51. /* the number of processed queries may be limited for one step */
  52. msg = pop_message(async_mq);
  53. while (msg) {
  54. /* INFO("processing authorization rules query\n"); */
  55. params = (async_auth_query_t*)get_message_data(msg);
  56. if (params) query_auth_rules(params);
  57. free_message(msg);
  58. if (++cnt > max_auth_requests_per_tick) break;
  59. msg = pop_message(async_mq);
  60. }
  61. }
  62. int async_auth_timer_init()
  63. {
  64. if (register_timer(async_timer_cb, NULL, async_timer_interval) < 0) {
  65. LOG(L_ERR, "vs_init(): can't register timer\n");
  66. return -1;
  67. }
  68. async_mq = shm_malloc(sizeof(*async_mq));
  69. if (!async_mq) {
  70. ERR("can't allocate memory\n");
  71. return -1;
  72. }
  73. msg_queue_init(async_mq);
  74. return 0;
  75. }
  76. int ask_auth_rules(presentity_t *p)
  77. {
  78. int len, res;
  79. mq_message_t *msg;
  80. async_auth_query_t *params;
  81. presence_rules_t *rules = NULL;
  82. /* ! call from critical section locked by pdomain mutex ! */
  83. if (pa_auth_params.type != auth_xcap) {
  84. return 0; /* don't load anything */
  85. }
  86. if (!async_auth_queries) {
  87. /* do synchronous query - it is called from locked section,
  88. * thus it is not good for performance! */
  89. res = xcap_get_pres_rules(&p->uuid, &rules, &p->xcap_params);
  90. if (res == RES_OK)
  91. set_auth_rules(p, rules);
  92. return res;
  93. }
  94. /* Ask for authorization rules (only XCAP now). This should be done
  95. * asynchronously, at least for time consuming operations like XCAP
  96. * queries */
  97. len = sizeof(async_auth_query_t) + p->uuid.len;
  98. msg = create_message_ex(len);
  99. if (!msg) {
  100. ERR("can't allocate memory (%d bytes)\n", len);
  101. return -1;
  102. }
  103. params = (async_auth_query_t*)get_message_data(msg);
  104. params->uid.s = params->buf;
  105. params->d = p->pdomain;
  106. if (!is_str_empty(&p->uuid)) {
  107. params->uid.len = p->uuid.len;
  108. memcpy(params->uid.s, p->uuid.s, p->uuid.len);
  109. }
  110. else params->uid.len = 0;
  111. push_message(async_mq, msg);
  112. /* INFO("asking authorization rules\n"); */
  113. return 0;
  114. }