ucontact.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * $Id: ucontact.c 5272 2008-11-27 12:32:26Z 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 three zombie states (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 contact handling functions
  30. * \ingroup usrloc
  31. *
  32. * - Module: \ref usrloc
  33. */
  34. #include "ucontact.h"
  35. #include <string.h> /* memcpy */
  36. #include "../../mem/shm_mem.h"
  37. #include "../../ut.h"
  38. #include "../../ip_addr.h"
  39. #include "../../socket_info.h"
  40. #include "../../dprint.h"
  41. #include "../../lib/srdb1/db.h"
  42. #include "p_usrloc_mod.h"
  43. #include "../usrloc/ul_callback.h"
  44. #include "urecord.h"
  45. #include "ucontact.h"
  46. #include "ul_db_layer.h"
  47. #include "dlist.h"
  48. /*!
  49. * \brief Create a new contact structure
  50. * \param _dom domain
  51. * \param _aor address of record
  52. * \param _contact contact string
  53. * \param _ci contact informations
  54. * \return new created contact on success, 0 on failure
  55. */
  56. ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _ci)
  57. {
  58. ucontact_t *c;
  59. c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));
  60. if (!c) {
  61. LM_ERR("no more shm memory\n");
  62. return 0;
  63. }
  64. memset(c, 0, sizeof(ucontact_t));
  65. if (shm_str_dup( &c->c, _contact) < 0) goto error;
  66. if (shm_str_dup( &c->callid, _ci->callid) < 0) goto error;
  67. if (shm_str_dup( &c->user_agent, _ci->user_agent) < 0) goto error;
  68. if (_ci->received.s && _ci->received.len) {
  69. if (shm_str_dup( &c->received, &_ci->received) < 0) goto error;
  70. }
  71. if (_ci->path && _ci->path->len) {
  72. if (shm_str_dup( &c->path, _ci->path) < 0) goto error;
  73. }
  74. if (_ci->ruid.s && _ci->ruid.len) {
  75. if (shm_str_dup( &c->ruid, &_ci->ruid) < 0) goto error;
  76. }
  77. if (_ci->instance.s && _ci->instance.len) {
  78. if (shm_str_dup( &c->instance, &_ci->instance) < 0) goto error;
  79. }
  80. c->domain = _dom;
  81. c->aor = _aor;
  82. c->expires = _ci->expires;
  83. c->q = _ci->q;
  84. c->sock = _ci->sock;
  85. c->cseq = _ci->cseq;
  86. c->state = CS_NEW;
  87. c->flags = _ci->flags;
  88. c->cflags = _ci->cflags;
  89. c->methods = _ci->methods;
  90. c->reg_id = _ci->reg_id;
  91. c->last_modified = _ci->last_modified;
  92. return c;
  93. error:
  94. LM_ERR("no more shm memory\n");
  95. if (c->path.s) shm_free(c->path.s);
  96. if (c->received.s) shm_free(c->received.s);
  97. if (c->user_agent.s) shm_free(c->user_agent.s);
  98. if (c->callid.s) shm_free(c->callid.s);
  99. if (c->c.s) shm_free(c->c.s);
  100. if (c->ruid.s) shm_free(c->ruid.s);
  101. if (c->instance.s) shm_free(c->instance.s);
  102. shm_free(c);
  103. return 0;
  104. }
  105. /*!
  106. * \brief Free all memory associated with given contact structure
  107. * \param _c freed contact
  108. */
  109. void free_ucontact(ucontact_t* _c)
  110. {
  111. if (!_c) return;
  112. if (_c->path.s) shm_free(_c->path.s);
  113. if (_c->received.s) shm_free(_c->received.s);
  114. if (_c->user_agent.s) shm_free(_c->user_agent.s);
  115. if (_c->callid.s) shm_free(_c->callid.s);
  116. if (_c->c.s) shm_free(_c->c.s);
  117. if (_c->ruid.s) shm_free(_c->ruid.s);
  118. if (_c->instance.s) shm_free(_c->instance.s);
  119. shm_free( _c );
  120. }
  121. /*!
  122. * \brief Print contact, for debugging purposes only
  123. * \param _f output file
  124. * \param _c printed contact
  125. */
  126. void print_ucontact(FILE* _f, ucontact_t* _c)
  127. {
  128. time_t t = time(0);
  129. char* st;
  130. switch(_c->state) {
  131. case CS_NEW: st = "CS_NEW"; break;
  132. case CS_SYNC: st = "CS_SYNC"; break;
  133. case CS_DIRTY: st = "CS_DIRTY"; break;
  134. default: st = "CS_UNKNOWN"; break;
  135. }
  136. fprintf(_f, "~~~Contact(%p)~~~\n", _c);
  137. fprintf(_f, "domain : '%.*s'\n", _c->domain->len, ZSW(_c->domain->s));
  138. fprintf(_f, "aor : '%.*s'\n", _c->aor->len, ZSW(_c->aor->s));
  139. fprintf(_f, "Contact : '%.*s'\n", _c->c.len, ZSW(_c->c.s));
  140. fprintf(_f, "Expires : ");
  141. if (_c->expires == 0) {
  142. fprintf(_f, "Permanent\n");
  143. } else if (_c->expires == UL_EXPIRED_TIME) {
  144. fprintf(_f, "Deleted\n");
  145. } else if (t > _c->expires) {
  146. fprintf(_f, "Expired\n");
  147. } else {
  148. fprintf(_f, "%u\n", (unsigned int)(_c->expires - t));
  149. }
  150. fprintf(_f, "q : %s\n", q2str(_c->q, 0));
  151. fprintf(_f, "Call-ID : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s));
  152. fprintf(_f, "CSeq : %d\n", _c->cseq);
  153. fprintf(_f, "User-Agent: '%.*s'\n",
  154. _c->user_agent.len, ZSW(_c->user_agent.s));
  155. fprintf(_f, "received : '%.*s'\n",
  156. _c->received.len, ZSW(_c->received.s));
  157. fprintf(_f, "Path : '%.*s'\n",
  158. _c->path.len, ZSW(_c->path.s));
  159. fprintf(_f, "State : %s\n", st);
  160. fprintf(_f, "Flags : %u\n", _c->flags);
  161. if (_c->sock) {
  162. fprintf(_f, "Sock : %.*s (%p)\n",
  163. _c->sock->sock_str.len,_c->sock->sock_str.s,_c->sock);
  164. } else {
  165. fprintf(_f, "Sock : none (null)\n");
  166. }
  167. fprintf(_f, "Methods : %u\n", _c->methods);
  168. fprintf(_f, "ruid : '%.*s'\n",
  169. _c->ruid.len, ZSW(_c->ruid.s));
  170. fprintf(_f, "instance : '%.*s'\n",
  171. _c->instance.len, ZSW(_c->instance.s));
  172. fprintf(_f, "reg-id : %u\n", _c->reg_id);
  173. fprintf(_f, "next : %p\n", _c->next);
  174. fprintf(_f, "prev : %p\n", _c->prev);
  175. fprintf(_f, "~~~/Contact~~~~\n");
  176. }
  177. /*!
  178. * \brief Update existing contact in memory with new values
  179. * \param _c contact
  180. * \param _ci contact informations
  181. * \return 0 on success, -1 on failure
  182. */
  183. int mem_update_ucontact(ucontact_t* _c, ucontact_info_t* _ci)
  184. {
  185. #define update_str(_old,_new) \
  186. do{\
  187. if ((_old)->len < (_new)->len) { \
  188. ptr = (char*)shm_malloc((_new)->len); \
  189. if (ptr == 0) { \
  190. LM_ERR("no more shm memory\n"); \
  191. return -1; \
  192. }\
  193. memcpy(ptr, (_new)->s, (_new)->len);\
  194. if ((_old)->s) shm_free((_old)->s);\
  195. (_old)->s = ptr;\
  196. } else {\
  197. memcpy((_old)->s, (_new)->s, (_new)->len);\
  198. }\
  199. (_old)->len = (_new)->len;\
  200. } while(0)
  201. char* ptr;
  202. /* No need to update Callid as it is constant
  203. * per ucontact (set at insert time) -bogdan */
  204. update_str( &_c->user_agent, _ci->user_agent);
  205. if (_ci->received.s && _ci->received.len) {
  206. update_str( &_c->received, &_ci->received);
  207. } else {
  208. if (_c->received.s) shm_free(_c->received.s);
  209. _c->received.s = 0;
  210. _c->received.len = 0;
  211. }
  212. if (_ci->path) {
  213. update_str( &_c->path, _ci->path);
  214. } else {
  215. if (_c->path.s) shm_free(_c->path.s);
  216. _c->path.s = 0;
  217. _c->path.len = 0;
  218. }
  219. _c->sock = _ci->sock;
  220. _c->expires = _ci->expires;
  221. _c->q = _ci->q;
  222. _c->cseq = _ci->cseq;
  223. _c->methods = _ci->methods;
  224. _c->last_modified = _ci->last_modified;
  225. _c->flags = _ci->flags;
  226. _c->cflags = _ci->cflags;
  227. return 0;
  228. }
  229. /* ================ State related functions =============== */
  230. /*!
  231. * \brief Update state of the contact if we are using write-back scheme
  232. * \param _c updated contact
  233. */
  234. void st_update_ucontact(ucontact_t* _c)
  235. {
  236. switch(_c->state) {
  237. case CS_NEW:
  238. /* Contact is new and is not in the database yet,
  239. * we remain in the same state here because the
  240. * contact must be inserted later in the timer
  241. */
  242. break;
  243. case CS_SYNC:
  244. /* For db mode 1 & 2 a modified contact needs to be
  245. * updated also in the database, so transit into
  246. * CS_DIRTY and let the timer to do the update
  247. * again. For db mode 1 we try to update right
  248. * now and if fails, let the timer to do the job
  249. */
  250. if (db_mode == WRITE_BACK || db_mode == WRITE_THROUGH) {
  251. _c->state = CS_DIRTY;
  252. }
  253. break;
  254. case CS_DIRTY:
  255. /* Modification of dirty contact results in
  256. * dirty contact again, don't change anything
  257. */
  258. break;
  259. }
  260. }
  261. /*!
  262. * \brief Update state of the contact
  263. * \param _c updated contact
  264. * \return 1 if the contact should be deleted from memory immediately, 0 otherwise
  265. */
  266. int st_delete_ucontact(ucontact_t* _c)
  267. {
  268. switch(_c->state) {
  269. case CS_NEW:
  270. /* Contact is new and isn't in the database
  271. * yet, we can delete it from the memory
  272. * safely.
  273. */
  274. return 1;
  275. case CS_SYNC:
  276. case CS_DIRTY:
  277. /* Contact is in the database,
  278. * we cannot remove it from the memory
  279. * directly, but we can set expires to zero
  280. * and the timer will take care of deleting
  281. * the contact from the memory as well as
  282. * from the database
  283. */
  284. if (db_mode == WRITE_BACK) {
  285. _c->expires = UL_EXPIRED_TIME;
  286. return 0;
  287. } else {
  288. /* WRITE_THROUGH or NO_DB -- we can
  289. * remove it from memory immediately and
  290. * the calling function would also remove
  291. * it from the database if needed
  292. */
  293. return 1;
  294. }
  295. }
  296. return 0; /* Makes gcc happy */
  297. }
  298. /*!
  299. * \brief Called when the timer is about to delete an expired contact
  300. * \param _c expired contact
  301. * \return 1 if the contact should be removed from the database and 0 otherwise
  302. */
  303. int st_expired_ucontact(ucontact_t* _c)
  304. {
  305. /* There is no need to change contact
  306. * state, because the contact will
  307. * be deleted anyway
  308. */
  309. switch(_c->state) {
  310. case CS_NEW:
  311. /* Contact is not in the database
  312. * yet, remove it from memory only
  313. */
  314. return 0;
  315. case CS_SYNC:
  316. case CS_DIRTY:
  317. /* Remove from database here */
  318. return 1;
  319. }
  320. return 0; /* Makes gcc happy */
  321. }
  322. /*!
  323. * \brief Called when the timer is about flushing the contact, updates contact state
  324. * \param _c flushed contact
  325. * \return 1 if the contact should be inserted, 2 if update and 0 otherwise
  326. */
  327. int st_flush_ucontact(ucontact_t* _c)
  328. {
  329. switch(_c->state) {
  330. case CS_NEW:
  331. /* Contact is new and is not in
  332. * the database yet so we have
  333. * to insert it
  334. */
  335. _c->state = CS_SYNC;
  336. return 1;
  337. case CS_SYNC:
  338. /* Contact is synchronized, do
  339. * nothing
  340. */
  341. return 0;
  342. case CS_DIRTY:
  343. /* Contact has been modified and
  344. * is in the db already so we
  345. * have to update it
  346. */
  347. _c->state = CS_SYNC;
  348. return 2;
  349. }
  350. return 0; /* Makes gcc happy */
  351. }
  352. /* ============== Database related functions ================ */
  353. /*!
  354. * \brief Insert contact into the database
  355. * \param _c inserted contact
  356. * \return 0 on success, -1 on failure
  357. */
  358. int db_insert_ucontact(ucontact_t* _c)
  359. {
  360. char* dom;
  361. db_key_t keys[18];
  362. db_val_t vals[18];
  363. int nr_cols = 0;
  364. int nr_cols_key = 0;
  365. struct udomain * _d;
  366. str user={0, 0};
  367. str domain={0, 0};
  368. if (_c->flags & FL_MEM) {
  369. return 0;
  370. }
  371. if(register_udomain(_c->domain->s, &_d) < 0){
  372. return -1;
  373. }
  374. LM_INFO("Domain set for contact %.*s\n", _c->domain->len, _c->domain->s);
  375. keys[nr_cols] = &user_col;
  376. vals[nr_cols].type = DB1_STR;
  377. vals[nr_cols].nul = 0;
  378. vals[nr_cols].val.str_val = *_c->aor;
  379. nr_cols++;
  380. keys[nr_cols] = &contact_col;
  381. vals[nr_cols].type = DB1_STR;
  382. vals[nr_cols].nul = 0;
  383. vals[nr_cols].val.str_val = _c->c;
  384. nr_cols++;
  385. if(use_domain) {
  386. keys[nr_cols] = &domain_col;
  387. vals[nr_cols].type = DB1_STR;
  388. vals[nr_cols].nul = 0;
  389. dom = memchr(_c->aor->s, '@', _c->aor->len);
  390. if (dom==0) {
  391. LM_INFO("*** use domain and AOR does not contain @\n");
  392. vals[nr_cols].val.str_val.len = 0;
  393. vals[nr_cols].val.str_val.s = 0;
  394. } else {
  395. vals[0].val.str_val.len = dom - _c->aor->s;
  396. vals[nr_cols].val.str_val.s = dom + 1;
  397. vals[nr_cols].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
  398. }
  399. domain = vals[nr_cols].val.str_val;
  400. LM_INFO("** Username=%.*s Domain=%.*s\n", vals[0].val.str_val.len, vals[0].val.str_val.s,
  401. vals[nr_cols].val.str_val.len, vals[nr_cols].val.str_val.s);
  402. nr_cols++;
  403. }
  404. user = vals[0].val.str_val;
  405. keys[nr_cols] = &expires_col;
  406. vals[nr_cols].type = DB1_DATETIME;
  407. vals[nr_cols].nul = 0;
  408. vals[nr_cols].val.time_val = _c->expires;
  409. nr_cols++;
  410. keys[nr_cols] = &q_col;
  411. vals[nr_cols].type = DB1_DOUBLE;
  412. vals[nr_cols].nul = 0;
  413. vals[nr_cols].val.double_val = q2double(_c->q);
  414. nr_cols++;
  415. keys[nr_cols] = &callid_col;
  416. vals[nr_cols].type = DB1_STR;
  417. vals[nr_cols].nul = 0;
  418. vals[nr_cols].val.str_val = _c->callid;
  419. nr_cols++;
  420. keys[nr_cols] = &cseq_col;
  421. vals[nr_cols].type = DB1_INT;
  422. vals[nr_cols].nul = 0;
  423. vals[nr_cols].val.int_val = _c->cseq;
  424. nr_cols++;
  425. keys[nr_cols] = &flags_col;
  426. vals[nr_cols].type = DB1_INT;
  427. vals[nr_cols].nul = 0;
  428. vals[nr_cols].val.bitmap_val = _c->flags;
  429. nr_cols++;
  430. keys[nr_cols] = &cflags_col;
  431. vals[nr_cols].type = DB1_INT;
  432. vals[nr_cols].nul = 0;
  433. vals[nr_cols].val.bitmap_val = _c->cflags;
  434. nr_cols++;
  435. keys[nr_cols] = &user_agent_col;
  436. vals[nr_cols].type = DB1_STR;
  437. vals[nr_cols].nul = 0;
  438. vals[nr_cols].val.str_val = _c->user_agent;
  439. nr_cols++;
  440. keys[nr_cols] = &received_col;
  441. vals[nr_cols].type = DB1_STR;
  442. if (_c->received.s == 0) {
  443. vals[nr_cols].nul = 1;
  444. } else {
  445. vals[nr_cols].nul = 0;
  446. vals[nr_cols].val.str_val = _c->received;
  447. }
  448. nr_cols++;
  449. keys[nr_cols] = &path_col;
  450. vals[nr_cols].type = DB1_STR;
  451. if (_c->path.s == 0) {
  452. vals[nr_cols].nul = 1;
  453. } else {
  454. vals[nr_cols].nul = 0;
  455. vals[nr_cols].val.str_val = _c->path;
  456. }
  457. nr_cols++;
  458. keys[nr_cols] = &sock_col;
  459. vals[nr_cols].type = DB1_STR;
  460. if (_c->sock) {
  461. vals[nr_cols].val.str_val = _c->sock->sock_str;
  462. vals[nr_cols].nul = 0;
  463. } else {
  464. vals[nr_cols].nul = 1;
  465. }
  466. nr_cols++;
  467. keys[nr_cols] = &methods_col;
  468. vals[nr_cols].type = DB1_BITMAP;
  469. if (_c->methods == 0xFFFFFFFF) {
  470. vals[nr_cols].nul = 1;
  471. } else {
  472. vals[nr_cols].val.bitmap_val = _c->methods;
  473. vals[nr_cols].nul = 0;
  474. }
  475. nr_cols++;
  476. keys[nr_cols] = &last_mod_col;
  477. vals[nr_cols].type = DB1_DATETIME;
  478. vals[nr_cols].nul = 0;
  479. vals[nr_cols].val.time_val = _c->last_modified;
  480. nr_cols++;
  481. keys[nr_cols] = &ruid_col;
  482. if(_c->ruid.len>0)
  483. {
  484. vals[nr_cols].type = DB1_STR;
  485. vals[nr_cols].nul = 0;
  486. vals[nr_cols].val.str_val = _c->ruid;
  487. } else {
  488. vals[nr_cols].nul = 1;
  489. }
  490. nr_cols++;
  491. keys[nr_cols] = &instance_col;
  492. if(_c->instance.len>0)
  493. {
  494. vals[nr_cols].type = DB1_STR;
  495. vals[nr_cols].nul = 0;
  496. vals[nr_cols].val.str_val = _c->instance;
  497. } else {
  498. vals[nr_cols].nul = 1;
  499. }
  500. nr_cols++;
  501. keys[nr_cols] = &reg_id_col;
  502. vals[nr_cols].type = DB1_INT;
  503. vals[nr_cols].nul = 0;
  504. vals[nr_cols].val.int_val = (int)_c->reg_id;
  505. nr_cols++;
  506. nr_cols_key = nr_cols;
  507. /* to prevent errors from the DB because of duplicated entries */
  508. if (ul_db_layer_replace(_d, &user, &domain, keys, vals, nr_cols, nr_cols_key) <0) {
  509. LM_ERR("inserting contact in db failed\n");
  510. return -1;
  511. }
  512. return 0;
  513. }
  514. /*!
  515. * \brief Update contact in the database
  516. * \param _c updated contact
  517. * \return 0 on success, -1 on failure
  518. */
  519. int db_update_ucontact(ucontact_t* _c)
  520. {
  521. char* dom;
  522. db_key_t keys1[4];
  523. db_val_t vals1[4];
  524. db_key_t keys2[14];
  525. db_val_t vals2[14];
  526. if (_c->flags & FL_MEM) {
  527. return 0;
  528. }
  529. struct udomain * _d;
  530. if(register_udomain(_c->domain->s, &_d) < 0){
  531. return -1;
  532. }
  533. keys1[0] = &user_col;
  534. keys1[1] = &contact_col;
  535. keys1[2] = &callid_col;
  536. keys1[3] = &domain_col;
  537. keys2[0] = &expires_col;
  538. keys2[1] = &q_col;
  539. keys2[2] = &cseq_col;
  540. keys2[3] = &flags_col;
  541. keys2[4] = &cflags_col;
  542. keys2[5] = &user_agent_col;
  543. keys2[6] = &received_col;
  544. keys2[7] = &path_col;
  545. keys2[8] = &sock_col;
  546. keys2[9] = &methods_col;
  547. keys2[10] = &last_mod_col;
  548. keys2[11] = &ruid_col;
  549. keys2[12] = &instance_col;
  550. keys2[13] = &reg_id_col;
  551. vals1[0].type = DB1_STR;
  552. vals1[0].nul = 0;
  553. vals1[0].val.str_val = *_c->aor;
  554. vals1[1].type = DB1_STR;
  555. vals1[1].nul = 0;
  556. vals1[1].val.str_val = _c->c;
  557. vals1[2].type = DB1_STR;
  558. vals1[2].nul = 0;
  559. vals1[2].val.str_val = _c->callid;
  560. vals2[0].type = DB1_DATETIME;
  561. vals2[0].nul = 0;
  562. vals2[0].val.time_val = _c->expires;
  563. vals2[1].type = DB1_DOUBLE;
  564. vals2[1].nul = 0;
  565. vals2[1].val.double_val = q2double(_c->q);
  566. vals2[2].type = DB1_INT;
  567. vals2[2].nul = 0;
  568. vals2[2].val.int_val = _c->cseq;
  569. vals2[3].type = DB1_INT;
  570. vals2[3].nul = 0;
  571. vals2[3].val.bitmap_val = _c->flags;
  572. vals2[4].type = DB1_INT;
  573. vals2[4].nul = 0;
  574. vals2[4].val.bitmap_val = _c->cflags;
  575. vals2[5].type = DB1_STR;
  576. vals2[5].nul = 0;
  577. vals2[5].val.str_val = _c->user_agent;
  578. vals2[6].type = DB1_STR;
  579. if (_c->received.s == 0) {
  580. vals2[6].nul = 1;
  581. } else {
  582. vals2[6].nul = 0;
  583. vals2[6].val.str_val = _c->received;
  584. }
  585. vals2[7].type = DB1_STR;
  586. if (_c->path.s == 0) {
  587. vals2[7].nul = 1;
  588. } else {
  589. vals2[7].nul = 0;
  590. vals2[7].val.str_val = _c->path;
  591. }
  592. vals2[8].type = DB1_STR;
  593. if (_c->sock) {
  594. vals2[8].val.str_val = _c->sock->sock_str;
  595. vals2[8].nul = 0;
  596. } else {
  597. vals2[8].nul = 1;
  598. }
  599. vals2[9].type = DB1_BITMAP;
  600. if (_c->methods == 0xFFFFFFFF) {
  601. vals2[9].nul = 1;
  602. } else {
  603. vals2[9].val.bitmap_val = _c->methods;
  604. vals2[9].nul = 0;
  605. }
  606. vals2[10].type = DB1_DATETIME;
  607. vals2[10].nul = 0;
  608. vals2[10].val.time_val = _c->last_modified;
  609. if(_c->ruid.len>0)
  610. {
  611. vals2[11].type = DB1_STR;
  612. vals2[11].nul = 0;
  613. vals2[11].val.str_val = _c->ruid;
  614. } else {
  615. vals2[11].nul = 1;
  616. }
  617. if(_c->instance.len>0)
  618. {
  619. vals2[12].type = DB1_STR;
  620. vals2[12].nul = 0;
  621. vals2[12].val.str_val = _c->instance;
  622. } else {
  623. vals2[12].nul = 1;
  624. }
  625. vals2[13].type = DB1_INT;
  626. vals2[13].nul = 0;
  627. vals2[13].val.int_val = (int)_c->reg_id;
  628. if (use_domain) {
  629. vals1[3].type = DB1_STR;
  630. vals1[3].nul = 0;
  631. dom = memchr(_c->aor->s, '@', _c->aor->len);
  632. if (dom==0) {
  633. vals1[0].val.str_val.len = 0;
  634. vals1[3].val.str_val = *_c->aor;
  635. } else {
  636. vals1[0].val.str_val.len = dom - _c->aor->s;
  637. vals1[3].val.str_val.s = dom + 1;
  638. vals1[3].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
  639. }
  640. }
  641. if (ul_db_layer_update(_d, &vals1[0].val.str_val, &vals1[3].val.str_val, keys1, 0, vals1, keys2, vals2,
  642. (use_domain) ? (4) : (3), 14) < 0) {
  643. LM_ERR("updating database failed\n");
  644. return -1;
  645. }
  646. return 0;
  647. }
  648. /*!
  649. * \brief Delete contact from the database
  650. * \param _c deleted contact
  651. * \return 0 on success, -1 on failure
  652. */
  653. int db_delete_ucontact(ucontact_t* _c)
  654. {
  655. char* dom;
  656. db_key_t keys[4];
  657. db_val_t vals[4];
  658. if (_c->flags & FL_MEM) {
  659. return 0;
  660. }
  661. struct udomain * _d;
  662. if(register_udomain(_c->domain->s, &_d) < 0){
  663. return -1;
  664. }
  665. keys[0] = &user_col;
  666. keys[1] = &contact_col;
  667. keys[2] = &callid_col;
  668. keys[3] = &domain_col;
  669. vals[0].type = DB1_STR;
  670. vals[0].nul = 0;
  671. vals[0].val.str_val = *_c->aor;
  672. vals[1].type = DB1_STR;
  673. vals[1].nul = 0;
  674. vals[1].val.str_val = _c->c;
  675. vals[2].type = DB1_STR;
  676. vals[2].nul = 0;
  677. vals[2].val.str_val = _c->callid;
  678. if (use_domain) {
  679. vals[3].type = DB1_STR;
  680. vals[3].nul = 0;
  681. dom = memchr(_c->aor->s, '@', _c->aor->len);
  682. if (dom==0) {
  683. vals[0].val.str_val.len = 0;
  684. vals[3].val.str_val = *_c->aor;
  685. } else {
  686. vals[0].val.str_val.len = dom - _c->aor->s;
  687. vals[3].val.str_val.s = dom + 1;
  688. vals[3].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
  689. }
  690. }
  691. if (ul_db_layer_delete(_d, &vals[0].val.str_val, &vals[3].val.str_val, keys, 0, vals, (use_domain) ? (4) : (3)) < 0) {
  692. LM_ERR("deleting from database failed\n");
  693. return -1;
  694. }
  695. return 0;
  696. }
  697. /*!
  698. * \brief Remove a contact from list belonging to a certain record
  699. * \param _r record the contact belongs
  700. * \param _c removed contact
  701. */
  702. static inline void unlink_contact(struct urecord* _r, ucontact_t* _c)
  703. {
  704. if (_c->prev) {
  705. _c->prev->next = _c->next;
  706. if (_c->next) {
  707. _c->next->prev = _c->prev;
  708. }
  709. } else {
  710. _r->contacts = _c->next;
  711. if (_c->next) {
  712. _c->next->prev = 0;
  713. }
  714. }
  715. }
  716. /*!
  717. * \brief Insert a new contact into the list at the correct position
  718. * \param _r record that holds the sorted contacts
  719. * \param _c new contact
  720. */
  721. static inline void update_contact_pos(struct urecord* _r, ucontact_t* _c)
  722. {
  723. ucontact_t *pos, *ppos;
  724. if (desc_time_order) {
  725. /* order by time - first the newest */
  726. if (_c->prev==0)
  727. return;
  728. unlink_contact(_r, _c);
  729. /* insert it at the beginning */
  730. _c->next = _r->contacts;
  731. _c->prev = 0;
  732. _r->contacts->prev = _c;
  733. _r->contacts = _c;
  734. } else {
  735. /* order by q - first the smaller q */
  736. if ( (_c->prev==0 || _c->q<=_c->prev->q)
  737. && (_c->next==0 || _c->q>=_c->next->q) )
  738. return;
  739. /* need to move , but where? */
  740. unlink_contact(_r, _c);
  741. _c->next = _c->prev = 0;
  742. for(pos=_r->contacts,ppos=0;pos&&pos->q<_c->q;ppos=pos,pos=pos->next);
  743. if (pos) {
  744. if (!pos->prev) {
  745. pos->prev = _c;
  746. _c->next = pos;
  747. _r->contacts = _c;
  748. } else {
  749. _c->next = pos;
  750. _c->prev = pos->prev;
  751. pos->prev->next = _c;
  752. pos->prev = _c;
  753. }
  754. } else if (ppos) {
  755. ppos->next = _c;
  756. _c->prev = ppos;
  757. } else {
  758. _r->contacts = _c;
  759. }
  760. }
  761. }
  762. /*!
  763. * \brief Update ucontact with new values
  764. * \param _r record the contact belongs to
  765. * \param _c updated contact
  766. * \param _ci new contact informations
  767. * \return 0 on success, -1 on failure
  768. */
  769. int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
  770. {
  771. /* we have to update memory in any case, but database directly
  772. * only in db_mode 1 */
  773. if (mem_update_ucontact( _c, _ci) < 0) {
  774. LM_ERR("failed to update memory\n");
  775. return -1;
  776. }
  777. /* run callbacks for UPDATE event */
  778. if (exists_ulcb_type(UL_CONTACT_UPDATE))
  779. {
  780. LM_DBG("exists callback for type= UL_CONTACT_UPDATE\n");
  781. run_ul_callbacks( UL_CONTACT_UPDATE, _c);
  782. }
  783. if (_r && db_mode!=DB_ONLY)
  784. update_contact_pos( _r, _c);
  785. st_update_ucontact(_c);
  786. if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
  787. /*
  788. * prevent problems when we're in a failover situation: the first DB contains
  789. * the complete location entries, the other misses some of them. Before the
  790. * update it checks for a entry in the first DB, this is ok. But the update
  791. * in the second DB will not work. Thus the expire mechanism don't work, it
  792. * takes too long until both DBs have the same number of entries again.
  793. */
  794. if (db_insert_ucontact(_c) < 0) {
  795. LM_ERR("failed to insert_update database\n");
  796. return -1;
  797. } else {
  798. _c->state = CS_SYNC;
  799. }
  800. }
  801. return 0;
  802. }