reg_avps.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include "reg_avps.h"
  2. #include "dlist.h"
  3. #include "ul_mod.h"
  4. #include "../../ut.h"
  5. #include "../../sr_module.h"
  6. static avp_flags_t reg_avp_flag = 0;
  7. /* ************************************************************** */
  8. /* utility functions */
  9. /* FIXME - ugly */
  10. extern avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val);
  11. void trace_avp(const char *prolog, avp_t *avp)
  12. {
  13. str *s;
  14. s = get_avp_name(avp);
  15. if (s) INFO("%s: \"%.*s\" (flags = %d)\n", prolog, s->len, s->s, avp->flags);
  16. else INFO("%s: unnamed AVP (flags = %d)\n", prolog, avp->flags);
  17. }
  18. int use_reg_avps()
  19. {
  20. return (reg_avp_flag != 0);
  21. }
  22. /* ************************************************************** */
  23. /* internal functions for storing/restoring AVPs into ucontact */
  24. static inline avp_t *avp_dup(avp_t *avp)
  25. {
  26. avp_value_t val;
  27. avp_name_t name;
  28. str *s;
  29. if (avp) {
  30. get_avp_val(avp, &val);
  31. if (avp->flags & AVP_NAME_STR) {
  32. s = get_avp_name(avp);
  33. if (s) name.s = *s;
  34. else {
  35. name.s.s = NULL;
  36. name.s.len = 0;
  37. }
  38. }
  39. else name.n = avp->id;
  40. return create_avp(avp->flags, name, val);
  41. }
  42. return NULL;
  43. }
  44. static void reg_destroy_avps(avp_t *avp)
  45. {
  46. avp_t *n;
  47. while (avp) {
  48. n = avp->next;
  49. shm_free(avp); /* FIXME: really ?? */
  50. avp = n;
  51. }
  52. }
  53. static void remove_avps(avp_t *avp)
  54. {
  55. struct search_state ss;
  56. avp_name_t name;
  57. avp_t *a;
  58. str *s;
  59. if (avp->flags & AVP_NAME_STR) {
  60. s = get_avp_name(avp);
  61. if (s) name.s = *s;
  62. else {
  63. name.s.s = NULL;
  64. name.s.len = 0;
  65. }
  66. }
  67. else name.n = avp->id;
  68. a = search_first_avp(avp->flags, name, 0, &ss);
  69. while(a) {
  70. destroy_avp(a);
  71. a = search_next_avp(&ss, 0);
  72. }
  73. }
  74. static int save_reg_avps_impl(struct ucontact *c)
  75. {
  76. int i;
  77. struct usr_avp *avp, *dup;
  78. avp_t *first, *last;
  79. static unsigned short lists[] = {
  80. AVP_CLASS_USER | AVP_TRACK_FROM,
  81. AVP_CLASS_USER | AVP_TRACK_TO,
  82. AVP_CLASS_URI | AVP_TRACK_FROM,
  83. AVP_CLASS_URI | AVP_TRACK_TO,
  84. 0
  85. };
  86. /* destroy old AVPs */
  87. /* if (c->avps) db_delete_reg_avps(c); */
  88. reg_destroy_avps(c->avps);
  89. last = NULL;
  90. first = NULL;
  91. for (i = 0; lists[i]; i++) {
  92. for (avp = get_avp_list(lists[i]); avp; avp = avp->next) {
  93. /* trace_avp("trying to save avp", avp); */
  94. if ((avp->flags & reg_avp_flag) == 0) continue;
  95. /* trace_avp("saving avp", avp); */
  96. dup = avp_dup(avp);
  97. if (dup) {
  98. /* add AVP into list */
  99. if (last) last->next = dup;
  100. else first = dup;
  101. last = dup;
  102. }
  103. }
  104. }
  105. c->avps = first;
  106. /* if (c->avps) db_save_reg_avps(c); */
  107. return 0;
  108. }
  109. static int restore_reg_avps(struct ucontact *info)
  110. {
  111. avp_t *avp;
  112. avp_value_t val;
  113. avp_name_t name;
  114. str *s;
  115. /* remove all these AVPs ? */
  116. avp = info->avps;
  117. while (avp) {
  118. remove_avps(avp);
  119. avp = avp->next;
  120. }
  121. /* add stored AVPs */
  122. avp = info->avps;
  123. while (avp) {
  124. get_avp_val(avp, &val);
  125. if (avp->flags & AVP_NAME_STR) {
  126. s = get_avp_name(avp);
  127. if (s) name.s = *s;
  128. else {
  129. name.s.s = NULL;
  130. name.s.len = 0;
  131. }
  132. }
  133. else name.n = avp->id;
  134. /* trace_avp("restoring avp", avp); */
  135. /* modify flags here? */
  136. add_avp(avp->flags, name, val);
  137. avp = avp->next;
  138. }
  139. return 0;
  140. }
  141. static int delete_reg_avps_impl(struct ucontact *info)
  142. {
  143. /* db_delete_reg_avps(info); */
  144. if (info->avps) reg_destroy_avps(info->avps);
  145. info->avps = NULL;
  146. return 0;
  147. }
  148. /* ************************************************************** */
  149. int set_reg_avpflag_name(char *name)
  150. {
  151. reg_avp_flag = 0;
  152. if (name) {
  153. if (!(*name)) return 0; /* -> don't use reg AVPs when zero length */
  154. reg_avp_flag = register_avpflag(name);
  155. if (!reg_avp_flag) {
  156. ERR("can't register AVP flag %s\n", name);
  157. return -1;
  158. }
  159. } /* else not use reg AVPs */
  160. return 0;
  161. }
  162. /*
  163. * Take AVPS from the current lists and store them in the contact
  164. * structure as registration AVPs. Existing registration AVPs will
  165. * be destroyed.
  166. */
  167. int save_reg_avps(struct ucontact *contact)
  168. {
  169. /* no locking here! */
  170. if (!use_reg_avps()) return 0;
  171. /* INFO("saving registration AVP flags\n"); */
  172. return save_reg_avps_impl(contact);
  173. }
  174. /*
  175. * Delete registration AVPs from the contact
  176. */
  177. int delete_reg_avps(struct ucontact* c)
  178. {
  179. /* no locking here! */
  180. if (!use_reg_avps()) return 0;
  181. /*INFO("removing registration AVP flags\n");*/
  182. return delete_reg_avps_impl(c);
  183. }
  184. /*
  185. * Take registration AVPs from the contact and copy
  186. * them to the current AVP lists
  187. */
  188. int load_reg_avps(struct ucontact *contact)
  189. {
  190. /* lock udomain here! */
  191. if (!use_reg_avps()) return 0;
  192. /* INFO("loading registration AVP flags\n"); */
  193. return restore_reg_avps(contact);
  194. }
  195. int read_reg_avps_fixup(void** param, int param_no)
  196. {
  197. udomain_t* d;
  198. switch (param_no) {
  199. case 1:
  200. if (register_udomain((char*)*param, &d) < 0) {
  201. ERR("Error while registering domain\n");
  202. return -1;
  203. }
  204. *param = (void*)d;
  205. break;
  206. case 2:
  207. return fixup_var_str_2(param, param_no);
  208. }
  209. return 0;
  210. }
  211. int read_reg_avps(struct sip_msg *m, char* _domain, char* fp)
  212. {
  213. urecord_t* r = NULL;
  214. struct ucontact *contact = NULL;
  215. udomain_t *d;
  216. str uid;
  217. if (!use_reg_avps()) return 1;
  218. d = (udomain_t*)_domain;
  219. if (get_str_fparam(&uid, m, (fparam_t*)fp) < 0) {
  220. ERR("invalid parameter\n");
  221. return -1;
  222. }
  223. /* INFO("reading avps for uid=%.*s\n", uid.len, ZSW(uid.s)); */
  224. lock_udomain(d);
  225. if (get_urecord(d, &uid, &r) != 0) {
  226. unlock_udomain(d);
  227. WARN("urecord not found\n");
  228. return -1;
  229. }
  230. if (get_ucontact(r, &m->new_uri, &contact) != 0) {
  231. unlock_udomain(d);
  232. WARN("ucontact not found\n");
  233. return -1;
  234. }
  235. load_reg_avps(contact);
  236. unlock_udomain(d);
  237. return 1;
  238. }
  239. int dup_reg_avps(struct ucontact *dst, struct ucontact *src)
  240. {
  241. struct usr_avp *avp, *dup;
  242. avp_t *first, *last;
  243. /* no locking here! TODO: do it in package memory !!! */
  244. if (!use_reg_avps()) return 0; /* don't use reg avps */
  245. /* destroy old AVPs */
  246. /* if (dst->avps) db_delete_reg_avps(dst); */
  247. reg_destroy_avps(dst->avps);
  248. last = NULL;
  249. first = NULL;
  250. avp = src->avps;
  251. while (avp) {
  252. dup = avp_dup(avp);
  253. if (dup) {
  254. /* add AVP into list */
  255. if (last) last->next = dup;
  256. else first = dup;
  257. last = dup;
  258. }
  259. avp = avp->next;
  260. }
  261. dst->avps = first;
  262. /* if (dst->avps) db_save_reg_avps(dst); */
  263. return 0;
  264. }