urecord.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. * $Id: urecord.c 5241 2008-11-21 12:52:25Z henningw $
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * History:
  23. * ---------
  24. * 2003-03-12 added replication mark and zombie state support (nils)
  25. * 2004-03-17 generic callbacks added (bogdan)
  26. * 2004-06-07 updated to the new DB api (andrei)
  27. */
  28. /*! \file
  29. * \brief USRLOC - Usrloc record structure
  30. * \ingroup usrloc
  31. *
  32. * - Module \ref usrloc
  33. */
  34. #include "../usrloc/usrloc.h"
  35. #include "urecord.h"
  36. #include <string.h>
  37. #include "../../mem/shm_mem.h"
  38. #include "../../dprint.h"
  39. #include "../../ut.h"
  40. #include "../../hashes.h"
  41. #include "p_usrloc_mod.h"
  42. #include "utime.h"
  43. #include "../usrloc/ul_callback.h"
  44. #include "ul_db_layer.h"
  45. /*! contact matching mode */
  46. int matching_mode = CONTACT_ONLY;
  47. /*! retransmission detection interval in seconds */
  48. int cseq_delay = 20;
  49. /*!
  50. * \brief Create and initialize new record structure
  51. * \param _dom domain name
  52. * \param _aor address of record
  53. * \param _r pointer to the new record
  54. * \return 0 on success, negative on failure
  55. */
  56. int new_urecord(str* _dom, str* _aor, urecord_t** _r)
  57. {
  58. *_r = (urecord_t*)shm_malloc(sizeof(urecord_t));
  59. if (*_r == 0) {
  60. LM_ERR("no more share memory\n");
  61. return -1;
  62. }
  63. memset(*_r, 0, sizeof(urecord_t));
  64. (*_r)->aor.s = (char*)shm_malloc(_aor->len);
  65. if ((*_r)->aor.s == 0) {
  66. LM_ERR("no more share memory\n");
  67. shm_free(*_r);
  68. *_r = 0;
  69. return -2;
  70. }
  71. memcpy((*_r)->aor.s, _aor->s, _aor->len);
  72. (*_r)->aor.len = _aor->len;
  73. (*_r)->domain = _dom;
  74. (*_r)->aorhash = ul_get_aorhash(_aor);
  75. return 0;
  76. }
  77. /*!
  78. * \brief Free all memory used by the given structure
  79. *
  80. * Free all memory used by the given structure.
  81. * The structure must be removed from all linked
  82. * lists first
  83. * \param _r freed record list
  84. */
  85. void free_urecord(urecord_t* _r)
  86. {
  87. ucontact_t* ptr;
  88. while(_r->contacts) {
  89. ptr = _r->contacts;
  90. _r->contacts = _r->contacts->next;
  91. free_ucontact(ptr);
  92. }
  93. /* if mem cache is not used, the urecord struct is static*/
  94. if (db_mode!=DB_ONLY) {
  95. if (_r->aor.s) shm_free(_r->aor.s);
  96. shm_free(_r);
  97. }
  98. }
  99. /*!
  100. * \brief Print a record, useful for debugging
  101. * \param _f print output
  102. * \param _r printed record
  103. */
  104. void print_urecord(FILE* _f, urecord_t* _r)
  105. {
  106. ucontact_t* ptr;
  107. fprintf(_f, "...Record(%p)...\n", _r);
  108. fprintf(_f, "domain : '%.*s'\n", _r->domain->len, ZSW(_r->domain->s));
  109. fprintf(_f, "aor : '%.*s'\n", _r->aor.len, ZSW(_r->aor.s));
  110. fprintf(_f, "aorhash: '%u'\n", (unsigned)_r->aorhash);
  111. fprintf(_f, "slot: '%d'\n", _r->aorhash&(_r->slot->d->size-1));
  112. if (_r->contacts) {
  113. ptr = _r->contacts;
  114. while(ptr) {
  115. print_ucontact(_f, ptr);
  116. ptr = ptr->next;
  117. }
  118. }
  119. fprintf(_f, ".../Record...\n");
  120. }
  121. /*!
  122. * \brief Add a new contact in memory
  123. *
  124. * Add a new contact in memory, contacts are ordered by:
  125. * 1) q value, 2) descending modification time
  126. * \param _r record this contact belongs to
  127. * \param _c contact
  128. * \param _ci contact information
  129. * \return pointer to new created contact on success, 0 on failure
  130. */
  131. ucontact_t* mem_insert_ucontact(urecord_t* _r, str* _c, ucontact_info_t* _ci)
  132. {
  133. ucontact_t* ptr, *prev = 0;
  134. ucontact_t* c;
  135. if ( (c=new_ucontact(_r->domain, &_r->aor, _c, _ci)) == 0) {
  136. LM_ERR("failed to create new contact\n");
  137. return 0;
  138. }
  139. if_update_stat( _r->slot, _r->slot->d->contacts, 1);
  140. ptr = _r->contacts;
  141. if (!desc_time_order) {
  142. while(ptr) {
  143. if (ptr->q < c->q) break;
  144. prev = ptr;
  145. ptr = ptr->next;
  146. }
  147. }
  148. if (ptr) {
  149. if (!ptr->prev) {
  150. ptr->prev = c;
  151. c->next = ptr;
  152. _r->contacts = c;
  153. } else {
  154. c->next = ptr;
  155. c->prev = ptr->prev;
  156. ptr->prev->next = c;
  157. ptr->prev = c;
  158. }
  159. } else if (prev) {
  160. prev->next = c;
  161. c->prev = prev;
  162. } else {
  163. _r->contacts = c;
  164. }
  165. return c;
  166. }
  167. /*!
  168. * \brief Remove the contact from lists in memory
  169. * \param _r record this contact belongs to
  170. * \param _c removed contact
  171. */
  172. void mem_remove_ucontact(urecord_t* _r, ucontact_t* _c)
  173. {
  174. if (_c->prev) {
  175. _c->prev->next = _c->next;
  176. if (_c->next) {
  177. _c->next->prev = _c->prev;
  178. }
  179. } else {
  180. _r->contacts = _c->next;
  181. if (_c->next) {
  182. _c->next->prev = 0;
  183. }
  184. }
  185. }
  186. /*!
  187. * \brief Remove contact in memory from the list and delete it
  188. * \param _r record this contact belongs to
  189. * \param _c deleted contact
  190. */
  191. void mem_delete_ucontact(urecord_t* _r, ucontact_t* _c)
  192. {
  193. mem_remove_ucontact(_r, _c);
  194. if_update_stat( _r->slot, _r->slot->d->contacts, -1);
  195. free_ucontact(_c);
  196. }
  197. /*!
  198. * \brief Expires timer for NO_DB db_mode
  199. *
  200. * Expires timer for NO_DB db_mode, process all contacts from
  201. * the record, delete the expired ones from memory.
  202. * \param _r processed record
  203. */
  204. static inline void nodb_timer(urecord_t* _r)
  205. {
  206. ucontact_t* ptr, *t;
  207. ptr = _r->contacts;
  208. while(ptr) {
  209. if (!VALID_CONTACT(ptr, act_time)) {
  210. /* run callbacks for EXPIRE event */
  211. if (exists_ulcb_type(UL_CONTACT_EXPIRE))
  212. run_ul_callbacks( UL_CONTACT_EXPIRE, ptr);
  213. LM_DBG("Binding '%.*s','%.*s' has expired\n",
  214. ptr->aor->len, ZSW(ptr->aor->s),
  215. ptr->c.len, ZSW(ptr->c.s));
  216. t = ptr;
  217. ptr = ptr->next;
  218. mem_delete_ucontact(_r, t);
  219. update_stat( _r->slot->d->expires, 1);
  220. } else {
  221. ptr = ptr->next;
  222. }
  223. }
  224. }
  225. /*!
  226. * \brief Write through timer, used for WRITE_THROUGH db_mode
  227. *
  228. * Write through timer, used for WRITE_THROUGH db_mode. Process all
  229. * contacts from the record, delete all expired ones from the DB.
  230. * \param _r processed record
  231. * \note currently unused, this mode is also handled by the wb_timer
  232. */
  233. static inline void wt_timer(urecord_t* _r)
  234. {
  235. ucontact_t* ptr, *t;
  236. ptr = _r->contacts;
  237. while(ptr) {
  238. if (!VALID_CONTACT(ptr, act_time)) {
  239. /* run callbacks for EXPIRE event */
  240. if (exists_ulcb_type(UL_CONTACT_EXPIRE)) {
  241. run_ul_callbacks( UL_CONTACT_EXPIRE, ptr);
  242. }
  243. LM_DBG("Binding '%.*s','%.*s' has expired\n",
  244. ptr->aor->len, ZSW(ptr->aor->s),
  245. ptr->c.len, ZSW(ptr->c.s));
  246. t = ptr;
  247. ptr = ptr->next;
  248. if (db_delete_ucontact(t) < 0) {
  249. LM_ERR("deleting contact from database failed\n");
  250. }
  251. mem_delete_ucontact(_r, t);
  252. update_stat( _r->slot->d->expires, 1);
  253. } else {
  254. ptr = ptr->next;
  255. }
  256. }
  257. }
  258. /*!
  259. * \brief Write-back timer, used for WRITE_BACK db_mode
  260. *
  261. * Write-back timer, used for WRITE_BACK db_mode. Process
  262. * all contacts from the record, delete expired ones from the DB.
  263. * Furthermore it updates changed contacts, and also insert new
  264. * ones in the DB.
  265. * \param _r processed record
  266. */
  267. static inline void wb_timer(urecord_t* _r)
  268. {
  269. ucontact_t* ptr, *t;
  270. cstate_t old_state;
  271. int op;
  272. ptr = _r->contacts;
  273. while(ptr) {
  274. if (!VALID_CONTACT(ptr, act_time)) {
  275. /* run callbacks for EXPIRE event */
  276. if (exists_ulcb_type(UL_CONTACT_EXPIRE)) {
  277. run_ul_callbacks( UL_CONTACT_EXPIRE, ptr);
  278. }
  279. LM_DBG("Binding '%.*s','%.*s' has expired\n",
  280. ptr->aor->len, ZSW(ptr->aor->s),
  281. ptr->c.len, ZSW(ptr->c.s));
  282. update_stat( _r->slot->d->expires, 1);
  283. t = ptr;
  284. ptr = ptr->next;
  285. /* Should we remove the contact from the database ? */
  286. if (st_expired_ucontact(t) == 1) {
  287. if (db_delete_ucontact(t) < 0) {
  288. LM_ERR("failed to delete contact from the database\n");
  289. }
  290. }
  291. mem_delete_ucontact(_r, t);
  292. } else {
  293. /* Determine the operation we have to do */
  294. old_state = ptr->state;
  295. op = st_flush_ucontact(ptr);
  296. switch(op) {
  297. case 0: /* do nothing, contact is synchronized */
  298. break;
  299. case 1: /* insert */
  300. if (db_insert_ucontact(ptr) < 0) {
  301. LM_ERR("inserting contact into database failed\n");
  302. ptr->state = old_state;
  303. }
  304. break;
  305. case 2: /* update */
  306. if (db_update_ucontact(ptr) < 0) {
  307. LM_ERR("updating contact in db failed\n");
  308. ptr->state = old_state;
  309. }
  310. break;
  311. }
  312. ptr = ptr->next;
  313. }
  314. }
  315. }
  316. /*!
  317. * \brief Run timer functions depending on the db_mode setting.
  318. *
  319. * Helper function that run the appropriate timer function, depending
  320. * on the db_mode setting.
  321. * \param _r processed record
  322. */
  323. void timer_urecord(urecord_t* _r)
  324. {
  325. switch(db_mode) {
  326. case NO_DB: nodb_timer(_r);
  327. break;
  328. /* use also the write_back timer routine to handle the failed
  329. * realtime inserts/updates */
  330. case WRITE_THROUGH: wb_timer(_r); /*wt_timer(_r);*/
  331. break;
  332. case WRITE_BACK: wb_timer(_r);
  333. break;
  334. }
  335. }
  336. /*!
  337. * \brief Delete a record from the database
  338. * \param _r deleted record
  339. * \return 0 on success, -1 on failure
  340. */
  341. int db_delete_urecord(udomain_t* _d, urecord_t* _r)
  342. {
  343. db_key_t keys[2];
  344. db_val_t vals[2];
  345. char* dom;
  346. keys[0] = &user_col;
  347. keys[1] = &domain_col;
  348. vals[0].type = DB1_STR;
  349. vals[0].nul = 0;
  350. vals[0].val.str_val.s = _r->aor.s;
  351. vals[0].val.str_val.len = _r->aor.len;
  352. if (use_domain) {
  353. dom = memchr(_r->aor.s, '@', _r->aor.len);
  354. vals[0].val.str_val.len = dom - _r->aor.s;
  355. vals[1].type = DB1_STR;
  356. vals[1].nul = 0;
  357. vals[1].val.str_val.s = dom + 1;
  358. vals[1].val.str_val.len = _r->aor.s + _r->aor.len - dom - 1;
  359. }
  360. if (ul_db_layer_delete(_d, &vals[0].val.str_val, &vals[1].val.str_val, keys, 0, vals, (use_domain) ? (2) : (1)) < 0) {
  361. return -1;
  362. }
  363. return 0;
  364. }
  365. /*!
  366. * \brief Release urecord previously obtained through get_urecord
  367. * \warning Failing to calls this function after get_urecord will
  368. * result in a memory leak when the DB_ONLY mode is used. When
  369. * the records is later deleted, e.g. with delete_urecord, then
  370. * its not necessary, as this function already releases the record.
  371. * \param _r released record
  372. */
  373. void release_urecord(urecord_t* _r)
  374. {
  375. if (db_mode==DB_ONLY) {
  376. free_urecord(_r);
  377. } else if (_r->contacts == 0) {
  378. mem_delete_urecord(_r->slot->d, _r);
  379. }
  380. }
  381. /*!
  382. * \brief Create and insert new contact into urecord
  383. * \param _r record into the new contact should be inserted
  384. * \param _contact contact string
  385. * \param _ci contact information
  386. * \param _c new created contact
  387. * \return 0 on success, -1 on failure
  388. */
  389. int insert_ucontact(urecord_t* _r, str* _contact, ucontact_info_t* _ci,
  390. ucontact_t** _c)
  391. {
  392. if ( ((*_c)=mem_insert_ucontact(_r, _contact, _ci)) == 0) {
  393. LM_ERR("failed to insert contact\n");
  394. return -1;
  395. }
  396. if (exists_ulcb_type(UL_CONTACT_INSERT)) {
  397. run_ul_callbacks( UL_CONTACT_INSERT, *_c);
  398. }
  399. if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
  400. if (db_insert_ucontact(*_c) < 0) {
  401. LM_ERR("failed to insert in database\n");
  402. return -1;
  403. } else {
  404. (*_c)->state = CS_SYNC;
  405. }
  406. }
  407. return 0;
  408. }
  409. /*!
  410. * \brief Delete ucontact from urecord
  411. * \param _r record where the contact belongs to
  412. * \param _c deleted contact
  413. * \return 0 on success, -1 on failure
  414. */
  415. int delete_ucontact(urecord_t* _r, struct ucontact* _c)
  416. {
  417. int ret = 0;
  418. if (exists_ulcb_type(UL_CONTACT_DELETE)) {
  419. run_ul_callbacks( UL_CONTACT_DELETE, _c);
  420. }
  421. if (st_delete_ucontact(_c) > 0) {
  422. if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
  423. if (db_delete_ucontact(_c) < 0) {
  424. LM_ERR("failed to remove contact from database\n");
  425. ret = -1;
  426. }
  427. }
  428. mem_delete_ucontact(_r, _c);
  429. }
  430. return ret;
  431. }
  432. /*!
  433. * \brief Match a contact record to a contact string
  434. * \param ptr contact record
  435. * \param _c contact string
  436. * \return ptr on successfull match, 0 when they not match
  437. */
  438. static inline struct ucontact* contact_match( ucontact_t* ptr, str* _c)
  439. {
  440. while(ptr) {
  441. if ((_c->len == ptr->c.len) && !memcmp(_c->s, ptr->c.s, _c->len)) {
  442. return ptr;
  443. }
  444. ptr = ptr->next;
  445. }
  446. return 0;
  447. }
  448. /*!
  449. * \brief Match a contact record to a contact string and callid
  450. * \param ptr contact record
  451. * \param _c contact string
  452. * \param _callid callid
  453. * \return ptr on successfull match, 0 when they not match
  454. */
  455. static inline struct ucontact* contact_callid_match( ucontact_t* ptr,
  456. str* _c, str *_callid)
  457. {
  458. while(ptr) {
  459. if ( (_c->len==ptr->c.len) && (_callid->len==ptr->callid.len)
  460. && !memcmp(_c->s, ptr->c.s, _c->len)
  461. && !memcmp(_callid->s, ptr->callid.s, _callid->len)
  462. ) {
  463. return ptr;
  464. }
  465. ptr = ptr->next;
  466. }
  467. return 0;
  468. }
  469. /*!
  470. + * \brief Match a contact record to a contact string and path
  471. + * \param ptr contact record
  472. + * \param _c contact string
  473. + * \param _path path
  474. + * \return ptr on successfull match, 0 when they not match
  475. + */
  476. static inline struct ucontact* contact_path_match( ucontact_t* ptr, str* _c, str *_path)
  477. {
  478. /* if no path is preset (in REGISTER request) or use_path is not configured
  479. in registrar module, default to contact_match() */
  480. if( _path == NULL) return contact_match(ptr, _c);
  481. while(ptr) {
  482. if ( (_c->len==ptr->c.len) && (_path->len==ptr->path.len)
  483. && !memcmp(_c->s, ptr->c.s, _c->len)
  484. && !memcmp(_path->s, ptr->path.s, _path->len)
  485. ) {
  486. return ptr;
  487. }
  488. ptr = ptr->next;
  489. }
  490. return 0;
  491. }
  492. /*!
  493. * \brief Get pointer to ucontact with given contact
  494. * \param _r record where to search the contacts
  495. * \param _c contact string
  496. * \param _callid callid
  497. * \param _cseq CSEQ number
  498. * \param _co found contact
  499. * \return 0 - found, 1 - not found, -1 - invalid found,
  500. * -2 - found, but to be skipped (same cseq)
  501. */
  502. int get_ucontact(urecord_t* _r, str* _c, str* _callid, str* _path, int _cseq,
  503. struct ucontact** _co)
  504. {
  505. ucontact_t* ptr;
  506. int no_callid;
  507. ptr = 0;
  508. no_callid = 0;
  509. *_co = 0;
  510. switch (matching_mode) {
  511. case CONTACT_ONLY:
  512. ptr = contact_match( _r->contacts, _c);
  513. break;
  514. case CONTACT_CALLID:
  515. ptr = contact_callid_match( _r->contacts, _c, _callid);
  516. no_callid = 1;
  517. break;
  518. case CONTACT_PATH:
  519. ptr = contact_path_match( _r->contacts, _c, _path);
  520. break;
  521. default:
  522. LM_CRIT("unknown matching_mode %d\n", matching_mode);
  523. return -1;
  524. }
  525. if (ptr) {
  526. /* found -> check callid and cseq */
  527. if ( no_callid || (ptr->callid.len==_callid->len
  528. && memcmp(_callid->s, ptr->callid.s, _callid->len)==0 ) ) {
  529. if (_cseq<ptr->cseq)
  530. return -1;
  531. if (_cseq==ptr->cseq) {
  532. get_act_time();
  533. return (ptr->last_modified+cseq_delay>act_time)?-2:-1;
  534. }
  535. }
  536. *_co = ptr;
  537. return 0;
  538. }
  539. return 1;
  540. }
  541. /*
  542. * Get pointer to ucontact with given info (by address or sip.instance)
  543. */
  544. int get_ucontact_by_instance(urecord_t* _r, str* _c, ucontact_info_t* _ci,
  545. ucontact_t** _co)
  546. {
  547. ucontact_t* ptr;
  548. str i1;
  549. str i2;
  550. if (_ci->instance.s == NULL || _ci->instance.len <= 0) {
  551. return get_ucontact(_r, _c, _ci->callid, _ci->path, _ci->cseq, _co);
  552. }
  553. /* find by instance */
  554. ptr = _r->contacts;
  555. while(ptr) {
  556. if (ptr->instance.len>0 && _ci->reg_id==ptr->reg_id)
  557. {
  558. i1 = _ci->instance;
  559. i2 = ptr->instance;
  560. if(i1.s[0]=='<' && i1.s[i1.len-1]=='>') {
  561. i1.s++;
  562. i1.len-=2;
  563. }
  564. if(i2.s[0]=='<' && i2.s[i2.len-1]=='>') {
  565. i2.s++;
  566. i2.len-=2;
  567. }
  568. if(i1.len==i2.len && memcmp(i1.s, i2.s, i2.len)==0) {
  569. *_co = ptr;
  570. return 0;
  571. }
  572. }
  573. ptr = ptr->next;
  574. }
  575. return 1;
  576. }
  577. unsigned int ul_get_aorhash(str *_aor)
  578. {
  579. return core_hash(_aor, 0, 0);
  580. }