ucontact.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704
  1. /*
  2. * $Id$
  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 "ul_mod.h"
  43. #include "ul_callback.h"
  44. #include "usrloc.h"
  45. #include "urecord.h"
  46. #include "ucontact.h"
  47. #include "usrloc.h"
  48. extern int ul_db_insert_null;
  49. static int ul_xavp_contact_clone = 1;
  50. void ul_set_xavp_contact_clone(int v)
  51. {
  52. ul_xavp_contact_clone = v;
  53. }
  54. #ifdef WITH_XAVP
  55. /*!
  56. * \brief Store xavp list per contact
  57. * \param _c contact structure
  58. */
  59. void ucontact_xavp_store(ucontact_t *_c)
  60. {
  61. sr_xavp_t *xavp;
  62. if(_c==NULL)
  63. return;
  64. if(ul_xavp_contact_clone == 0)
  65. return;
  66. if(ul_xavp_contact_name.s==NULL)
  67. return;
  68. /* remove old list if it is set -- update case */
  69. if (_c->xavp) xavp_destroy_list(&_c->xavp);
  70. xavp = xavp_get(&ul_xavp_contact_name, NULL);
  71. if(xavp==NULL)
  72. return;
  73. /* clone the xavp found in core */
  74. LM_DBG("trying to clone per contact xavps\n");
  75. _c->xavp = xavp_clone_level_nodata(xavp);
  76. return;
  77. }
  78. #endif
  79. /*!
  80. * \brief Create a new contact structure
  81. * \param _dom domain
  82. * \param _aor address of record
  83. * \param _contact contact string
  84. * \param _ci contact informations
  85. * \return new created contact on success, 0 on failure
  86. */
  87. ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _ci)
  88. {
  89. ucontact_t *c;
  90. if(unlikely(_ci->ruid.len<=0)) {
  91. LM_ERR("no ruid for aor: %.*s\n", _aor->len, ZSW(_aor->s));
  92. return 0;
  93. }
  94. c = (ucontact_t*)shm_malloc(sizeof(ucontact_t));
  95. if (!c) {
  96. LM_ERR("no more shm memory\n");
  97. return 0;
  98. }
  99. memset(c, 0, sizeof(ucontact_t));
  100. if (shm_str_dup( &c->c, _contact) < 0) goto error;
  101. if (shm_str_dup( &c->callid, _ci->callid) < 0) goto error;
  102. if (shm_str_dup( &c->user_agent, _ci->user_agent) < 0) goto error;
  103. if (_ci->received.s && _ci->received.len) {
  104. if (shm_str_dup( &c->received, &_ci->received) < 0) goto error;
  105. }
  106. if (_ci->path && _ci->path->len) {
  107. if (shm_str_dup( &c->path, _ci->path) < 0) goto error;
  108. }
  109. if (_ci->ruid.s && _ci->ruid.len) {
  110. if (shm_str_dup( &c->ruid, &_ci->ruid) < 0) goto error;
  111. }
  112. if (_ci->instance.s && _ci->instance.len) {
  113. if (shm_str_dup( &c->instance, &_ci->instance) < 0) goto error;
  114. }
  115. c->domain = _dom;
  116. c->aor = _aor;
  117. c->expires = _ci->expires;
  118. c->q = _ci->q;
  119. c->sock = _ci->sock;
  120. c->cseq = _ci->cseq;
  121. c->state = CS_NEW;
  122. c->flags = _ci->flags;
  123. c->cflags = _ci->cflags;
  124. c->methods = _ci->methods;
  125. c->reg_id = _ci->reg_id;
  126. c->last_modified = _ci->last_modified;
  127. c->last_keepalive = _ci->last_modified;
  128. c->tcpconn_id = _ci->tcpconn_id;
  129. #ifdef WITH_XAVP
  130. ucontact_xavp_store(c);
  131. #endif
  132. return c;
  133. error:
  134. LM_ERR("no more shm memory\n");
  135. if (c->path.s) shm_free(c->path.s);
  136. if (c->received.s) shm_free(c->received.s);
  137. if (c->user_agent.s) shm_free(c->user_agent.s);
  138. if (c->callid.s) shm_free(c->callid.s);
  139. if (c->c.s) shm_free(c->c.s);
  140. if (c->ruid.s) shm_free(c->ruid.s);
  141. if (c->instance.s) shm_free(c->instance.s);
  142. #ifdef WITH_XAVP
  143. if (c->xavp) xavp_destroy_list(&c->xavp);
  144. #endif
  145. shm_free(c);
  146. return 0;
  147. }
  148. /*!
  149. * \brief Free all memory associated with given contact structure
  150. * \param _c freed contact
  151. */
  152. void free_ucontact(ucontact_t* _c)
  153. {
  154. if (!_c) return;
  155. if (_c->path.s) shm_free(_c->path.s);
  156. if (_c->received.s) shm_free(_c->received.s);
  157. if (_c->user_agent.s) shm_free(_c->user_agent.s);
  158. if (_c->callid.s) shm_free(_c->callid.s);
  159. if (_c->c.s) shm_free(_c->c.s);
  160. if (_c->ruid.s) shm_free(_c->ruid.s);
  161. if (_c->instance.s) shm_free(_c->instance.s);
  162. #ifdef WITH_XAVP
  163. if (_c->xavp) xavp_destroy_list(&_c->xavp);
  164. #endif
  165. shm_free( _c );
  166. }
  167. /*!
  168. * \brief Print contact, for debugging purposes only
  169. * \param _f output file
  170. * \param _c printed contact
  171. */
  172. void print_ucontact(FILE* _f, ucontact_t* _c)
  173. {
  174. time_t t = time(0);
  175. char* st;
  176. switch(_c->state) {
  177. case CS_NEW: st = "CS_NEW"; break;
  178. case CS_SYNC: st = "CS_SYNC"; break;
  179. case CS_DIRTY: st = "CS_DIRTY"; break;
  180. default: st = "CS_UNKNOWN"; break;
  181. }
  182. fprintf(_f, "~~~Contact(%p)~~~\n", _c);
  183. fprintf(_f, "domain : '%.*s'\n", _c->domain->len, ZSW(_c->domain->s));
  184. fprintf(_f, "aor : '%.*s'\n", _c->aor->len, ZSW(_c->aor->s));
  185. fprintf(_f, "Contact : '%.*s'\n", _c->c.len, ZSW(_c->c.s));
  186. fprintf(_f, "Expires : ");
  187. if (_c->expires == 0) {
  188. fprintf(_f, "Permanent\n");
  189. } else if (_c->expires == UL_EXPIRED_TIME) {
  190. fprintf(_f, "Deleted\n");
  191. } else if (t > _c->expires) {
  192. fprintf(_f, "Expired\n");
  193. } else {
  194. fprintf(_f, "%u\n", (unsigned int)(_c->expires - t));
  195. }
  196. fprintf(_f, "q : %s\n", q2str(_c->q, 0));
  197. fprintf(_f, "Call-ID : '%.*s'\n", _c->callid.len, ZSW(_c->callid.s));
  198. fprintf(_f, "CSeq : %d\n", _c->cseq);
  199. fprintf(_f, "User-Agent: '%.*s'\n",
  200. _c->user_agent.len, ZSW(_c->user_agent.s));
  201. fprintf(_f, "received : '%.*s'\n",
  202. _c->received.len, ZSW(_c->received.s));
  203. fprintf(_f, "Path : '%.*s'\n",
  204. _c->path.len, ZSW(_c->path.s));
  205. fprintf(_f, "State : %s\n", st);
  206. fprintf(_f, "Flags : %u\n", _c->flags);
  207. if (_c->sock) {
  208. fprintf(_f, "Sock : %.*s (%p)\n",
  209. _c->sock->sock_str.len,_c->sock->sock_str.s,_c->sock);
  210. } else {
  211. fprintf(_f, "Sock : none (null)\n");
  212. }
  213. fprintf(_f, "Methods : %u\n", _c->methods);
  214. fprintf(_f, "ruid : '%.*s'\n",
  215. _c->ruid.len, ZSW(_c->ruid.s));
  216. fprintf(_f, "instance : '%.*s'\n",
  217. _c->instance.len, ZSW(_c->instance.s));
  218. fprintf(_f, "reg-id : %u\n", _c->reg_id);
  219. fprintf(_f, "next : %p\n", _c->next);
  220. fprintf(_f, "prev : %p\n", _c->prev);
  221. fprintf(_f, "~~~/Contact~~~~\n");
  222. }
  223. /*!
  224. * \brief Update existing contact in memory with new values
  225. * \param _c contact
  226. * \param _ci contact informations
  227. * \return 0 on success, -1 on failure
  228. */
  229. int mem_update_ucontact(ucontact_t* _c, ucontact_info_t* _ci)
  230. {
  231. #define update_str(_old,_new) \
  232. do{\
  233. if ((_old)->len < (_new)->len) { \
  234. ptr = (char*)shm_malloc((_new)->len); \
  235. if (ptr == 0) { \
  236. LM_ERR("no more shm memory\n"); \
  237. return -1; \
  238. }\
  239. memcpy(ptr, (_new)->s, (_new)->len);\
  240. if ((_old)->s) shm_free((_old)->s);\
  241. (_old)->s = ptr;\
  242. } else {\
  243. memcpy((_old)->s, (_new)->s, (_new)->len);\
  244. }\
  245. (_old)->len = (_new)->len;\
  246. } while(0)
  247. char* ptr;
  248. if(_ci->instance.s!=NULL && _ci->instance.len>0)
  249. {
  250. /* when we have instance set, update contact address */
  251. if(_ci->c!=NULL && _ci->c->s!=NULL && _ci->c->len>0)
  252. update_str( &_c->c, _ci->c);
  253. }
  254. /* refresh call-id */
  255. if(_ci->callid!=NULL && _ci->callid->s!=NULL && _ci->callid->len>0)
  256. update_str( &_c->callid, _ci->callid);
  257. update_str( &_c->user_agent, _ci->user_agent);
  258. if (_ci->received.s && _ci->received.len) {
  259. update_str( &_c->received, &_ci->received);
  260. } else {
  261. if (_c->received.s) shm_free(_c->received.s);
  262. _c->received.s = 0;
  263. _c->received.len = 0;
  264. }
  265. if (_ci->path) {
  266. update_str( &_c->path, _ci->path);
  267. } else {
  268. if (_c->path.s) shm_free(_c->path.s);
  269. _c->path.s = 0;
  270. _c->path.len = 0;
  271. }
  272. #ifdef WITH_XAVP
  273. ucontact_xavp_store(_c);
  274. #endif
  275. _c->sock = _ci->sock;
  276. _c->expires = _ci->expires;
  277. _c->q = _ci->q;
  278. _c->cseq = _ci->cseq;
  279. _c->methods = _ci->methods;
  280. _c->last_modified = _ci->last_modified;
  281. _c->last_keepalive = _ci->last_modified;
  282. _c->flags = _ci->flags;
  283. _c->cflags = _ci->cflags;
  284. _c->tcpconn_id = _ci->tcpconn_id;
  285. return 0;
  286. }
  287. /* ================ State related functions =============== */
  288. /*!
  289. * \brief Update state of the contact if we are using write-back scheme
  290. * \param _c updated contact
  291. */
  292. void st_update_ucontact(ucontact_t* _c)
  293. {
  294. switch(_c->state) {
  295. case CS_NEW:
  296. /* Contact is new and is not in the database yet,
  297. * we remain in the same state here because the
  298. * contact must be inserted later in the timer
  299. */
  300. break;
  301. case CS_SYNC:
  302. /* For db mode 1 & 2 a modified contact needs to be
  303. * updated also in the database, so transit into
  304. * CS_DIRTY and let the timer to do the update
  305. * again. For db mode 1 we try to update right
  306. * now and if fails, let the timer to do the job
  307. */
  308. if (db_mode == WRITE_BACK || db_mode == WRITE_THROUGH) {
  309. _c->state = CS_DIRTY;
  310. }
  311. break;
  312. case CS_DIRTY:
  313. /* Modification of dirty contact results in
  314. * dirty contact again, don't change anything
  315. */
  316. break;
  317. }
  318. }
  319. /*!
  320. * \brief Update state of the contact
  321. * \param _c updated contact
  322. * \return 1 if the contact should be deleted from memory immediately, 0 otherwise
  323. */
  324. int st_delete_ucontact(ucontact_t* _c)
  325. {
  326. switch(_c->state) {
  327. case CS_NEW:
  328. /* Contact is new and isn't in the database
  329. * yet, we can delete it from the memory
  330. * safely.
  331. */
  332. return 1;
  333. case CS_SYNC:
  334. case CS_DIRTY:
  335. /* Contact is in the database,
  336. * we cannot remove it from the memory
  337. * directly, but we can set expires to zero
  338. * and the timer will take care of deleting
  339. * the contact from the memory as well as
  340. * from the database
  341. */
  342. if (db_mode == WRITE_BACK) {
  343. _c->expires = UL_EXPIRED_TIME;
  344. return 0;
  345. } else {
  346. /* WRITE_THROUGH or NO_DB -- we can
  347. * remove it from memory immediately and
  348. * the calling function would also remove
  349. * it from the database if needed
  350. */
  351. return 1;
  352. }
  353. }
  354. return 0; /* Makes gcc happy */
  355. }
  356. /*!
  357. * \brief Called when the timer is about to delete an expired contact
  358. * \param _c expired contact
  359. * \return 1 if the contact should be removed from the database and 0 otherwise
  360. */
  361. int st_expired_ucontact(ucontact_t* _c)
  362. {
  363. /* There is no need to change contact
  364. * state, because the contact will
  365. * be deleted anyway
  366. */
  367. switch(_c->state) {
  368. case CS_NEW:
  369. /* Contact is not in the database
  370. * yet, remove it from memory only
  371. */
  372. return 0;
  373. case CS_SYNC:
  374. case CS_DIRTY:
  375. /* Remove from database here */
  376. return 1;
  377. }
  378. return 0; /* Makes gcc happy */
  379. }
  380. /*!
  381. * \brief Called when the timer is about flushing the contact, updates contact state
  382. * \param _c flushed contact
  383. * \return 1 if the contact should be inserted, 2 if update and 0 otherwise
  384. */
  385. int st_flush_ucontact(ucontact_t* _c)
  386. {
  387. switch(_c->state) {
  388. case CS_NEW:
  389. /* Contact is new and is not in
  390. * the database yet so we have
  391. * to insert it
  392. */
  393. _c->state = CS_SYNC;
  394. return 1;
  395. case CS_SYNC:
  396. /* Contact is synchronized, do
  397. * nothing
  398. */
  399. return 0;
  400. case CS_DIRTY:
  401. /* Contact has been modified and
  402. * is in the db already so we
  403. * have to update it
  404. */
  405. _c->state = CS_SYNC;
  406. return 2;
  407. }
  408. return 0; /* Makes gcc happy */
  409. }
  410. /* ============== Database related functions ================ */
  411. /*!
  412. * \brief Insert contact into the database
  413. * \param _c inserted contact
  414. * \return 0 on success, -1 on failure
  415. */
  416. int db_insert_ucontact(ucontact_t* _c)
  417. {
  418. char* dom;
  419. db_key_t keys[18];
  420. db_val_t vals[18];
  421. int nr_cols;
  422. if (_c->flags & FL_MEM) {
  423. return 0;
  424. }
  425. if(unlikely(_c->ruid.len<=0)) {
  426. LM_ERR("invalid ruid for aor: %.*s\n",
  427. _c->aor->len, ZSW(_c->aor->s));
  428. return -1;
  429. }
  430. keys[0] = &user_col;
  431. vals[0].type = DB1_STR;
  432. vals[0].nul = 0;
  433. vals[0].val.str_val.s = _c->aor->s;
  434. vals[0].val.str_val.len = _c->aor->len;
  435. keys[1] = &contact_col;
  436. vals[1].type = DB1_STR;
  437. vals[1].nul = 0;
  438. vals[1].val.str_val.s = _c->c.s;
  439. vals[1].val.str_val.len = _c->c.len;
  440. keys[2] = &expires_col;
  441. vals[2].nul = 0;
  442. UL_DB_EXPIRES_SET(&vals[2], _c->expires);
  443. keys[3] = &q_col;
  444. vals[3].type = DB1_DOUBLE;
  445. vals[3].nul = 0;
  446. vals[3].val.double_val = q2double(_c->q);
  447. keys[4] = &callid_col;
  448. vals[4].type = DB1_STR;
  449. vals[4].nul = 0;
  450. vals[4].val.str_val.s = _c->callid.s;
  451. vals[4].val.str_val.len = _c->callid.len;
  452. keys[5] = &cseq_col;
  453. vals[5].type = DB1_INT;
  454. vals[5].nul = 0;
  455. vals[5].val.int_val = _c->cseq;
  456. keys[6] = &flags_col;
  457. vals[6].type = DB1_INT;
  458. vals[6].nul = 0;
  459. vals[6].val.bitmap_val = _c->flags;
  460. keys[7] = &cflags_col;
  461. vals[7].type = DB1_INT;
  462. vals[7].nul = 0;
  463. vals[7].val.bitmap_val = _c->cflags;
  464. keys[8] = &user_agent_col;
  465. vals[8].type = DB1_STR;
  466. vals[8].nul = 0;
  467. vals[8].val.str_val.s = _c->user_agent.s;
  468. vals[8].val.str_val.len = _c->user_agent.len;
  469. nr_cols = 9;
  470. if (_c->received.s) {
  471. keys[nr_cols] = &received_col;
  472. vals[nr_cols].type = DB1_STR;
  473. vals[nr_cols].nul = 0;
  474. vals[nr_cols].val.str_val.s = _c->received.s;
  475. vals[nr_cols].val.str_val.len = _c->received.len;
  476. nr_cols++;
  477. } else if(ul_db_insert_null!=0) {
  478. keys[nr_cols] = &received_col;
  479. vals[nr_cols].type = DB1_STR;
  480. vals[nr_cols].nul = 1;
  481. nr_cols++;
  482. }
  483. if (_c->path.s) {
  484. keys[nr_cols] = &path_col;
  485. vals[nr_cols].type = DB1_STR;
  486. vals[nr_cols].nul = 0;
  487. vals[nr_cols].val.str_val.s = _c->path.s;
  488. vals[nr_cols].val.str_val.len = _c->path.len;
  489. nr_cols++;
  490. } else if(ul_db_insert_null!=0) {
  491. keys[nr_cols] = &path_col;
  492. vals[nr_cols].type = DB1_STR;
  493. vals[nr_cols].nul = 1;
  494. nr_cols++;
  495. }
  496. if (_c->sock) {
  497. keys[nr_cols] = &sock_col;
  498. vals[nr_cols].type = DB1_STR;
  499. vals[nr_cols].val.str_val = _c->sock->sock_str;
  500. vals[nr_cols].nul = 0;
  501. nr_cols++;
  502. } else if(ul_db_insert_null!=0) {
  503. keys[nr_cols] = &sock_col;
  504. vals[nr_cols].type = DB1_STR;
  505. vals[nr_cols].nul = 1;
  506. nr_cols++;
  507. }
  508. if (_c->methods != 0xFFFFFFFF) {
  509. keys[nr_cols] = &methods_col;
  510. vals[nr_cols].type = DB1_BITMAP;
  511. vals[nr_cols].val.bitmap_val = _c->methods;
  512. vals[nr_cols].nul = 0;
  513. nr_cols++;
  514. } else if(ul_db_insert_null!=0) {
  515. keys[nr_cols] = &methods_col;
  516. vals[nr_cols].type = DB1_BITMAP;
  517. vals[nr_cols].nul = 1;
  518. nr_cols++;
  519. }
  520. keys[nr_cols] = &last_mod_col;
  521. vals[nr_cols].nul = 0;
  522. UL_DB_EXPIRES_SET(&vals[nr_cols], _c->last_modified);
  523. nr_cols++;
  524. if(_c->ruid.len>0)
  525. {
  526. keys[nr_cols] = &ruid_col;
  527. vals[nr_cols].type = DB1_STR;
  528. vals[nr_cols].nul = 0;
  529. vals[nr_cols].val.str_val = _c->ruid;
  530. nr_cols++;
  531. } else if(ul_db_insert_null!=0) {
  532. keys[nr_cols] = &ruid_col;
  533. vals[nr_cols].type = DB1_STR;
  534. vals[nr_cols].nul = 1;
  535. nr_cols++;
  536. }
  537. if(_c->instance.len>0)
  538. {
  539. keys[nr_cols] = &instance_col;
  540. vals[nr_cols].type = DB1_STR;
  541. vals[nr_cols].nul = 0;
  542. vals[nr_cols].val.str_val = _c->instance;
  543. nr_cols++;
  544. } else if(ul_db_insert_null!=0) {
  545. keys[nr_cols] = &instance_col;
  546. vals[nr_cols].type = DB1_STR;
  547. vals[nr_cols].nul = 1;
  548. nr_cols++;
  549. }
  550. keys[nr_cols] = &reg_id_col;
  551. vals[nr_cols].type = DB1_INT;
  552. vals[nr_cols].nul = 0;
  553. vals[nr_cols].val.int_val = (int)_c->reg_id;
  554. nr_cols++;
  555. if (use_domain) {
  556. keys[nr_cols] = &domain_col;
  557. vals[nr_cols].type = DB1_STR;
  558. vals[nr_cols].nul = 0;
  559. dom = memchr(_c->aor->s, '@', _c->aor->len);
  560. if (dom==0) {
  561. vals[0].val.str_val.len = 0;
  562. vals[nr_cols].val.str_val = *_c->aor;
  563. } else {
  564. vals[0].val.str_val.len = dom - _c->aor->s;
  565. vals[nr_cols].val.str_val.s = dom + 1;
  566. vals[nr_cols].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
  567. }
  568. nr_cols++;
  569. }
  570. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  571. LM_ERR("sql use_table failed\n");
  572. return -1;
  573. }
  574. if (ul_dbf.insert(ul_dbh, keys, vals, nr_cols) < 0) {
  575. LM_ERR("inserting contact in db failed\n");
  576. return -1;
  577. }
  578. if (ul_xavp_contact_name.s) {
  579. uldb_insert_attrs(_c->domain, &vals[0].val.str_val,
  580. &vals[nr_cols-1].val.str_val,
  581. &_c->ruid, _c->xavp);
  582. }
  583. return 0;
  584. }
  585. /*!
  586. * \brief Update contact in the database by address
  587. * \param _c updated contact
  588. * \return 0 on success, -1 on failure
  589. */
  590. int db_update_ucontact_addr(ucontact_t* _c)
  591. {
  592. char* dom;
  593. db_key_t keys1[4];
  594. db_val_t vals1[4];
  595. int n1;
  596. db_key_t keys2[15];
  597. db_val_t vals2[15];
  598. int nr_cols2;
  599. if (_c->flags & FL_MEM) {
  600. return 0;
  601. }
  602. keys2[0] = &expires_col;
  603. keys2[1] = &q_col;
  604. keys2[2] = &cseq_col;
  605. keys2[3] = &flags_col;
  606. keys2[4] = &cflags_col;
  607. keys2[5] = &user_agent_col;
  608. keys2[6] = &received_col;
  609. keys2[7] = &path_col;
  610. keys2[8] = &sock_col;
  611. keys2[9] = &methods_col;
  612. keys2[10] = &last_mod_col;
  613. keys2[11] = &ruid_col;
  614. keys2[12] = &instance_col;
  615. keys2[13] = &reg_id_col;
  616. n1 = 0;
  617. keys1[n1] = &user_col;
  618. vals1[n1].type = DB1_STR;
  619. vals1[n1].nul = 0;
  620. vals1[n1].val.str_val = *_c->aor;
  621. LM_DBG("aor:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  622. n1++;
  623. keys1[n1] = &contact_col;
  624. vals1[n1].type = DB1_STR;
  625. vals1[n1].nul = 0;
  626. vals1[n1].val.str_val = _c->c;
  627. LM_DBG("contact:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  628. n1++;
  629. keys1[n1] = &callid_col;
  630. vals1[n1].type = DB1_STR;
  631. vals1[n1].nul = 0;
  632. vals1[n1].val.str_val = _c->callid;
  633. LM_DBG("callid:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  634. n1++;
  635. vals2[0].nul = 0;
  636. UL_DB_EXPIRES_SET(&vals2[0], _c->expires);
  637. vals2[1].type = DB1_DOUBLE;
  638. vals2[1].nul = 0;
  639. vals2[1].val.double_val = q2double(_c->q);
  640. vals2[2].type = DB1_INT;
  641. vals2[2].nul = 0;
  642. vals2[2].val.int_val = _c->cseq;
  643. vals2[3].type = DB1_INT;
  644. vals2[3].nul = 0;
  645. vals2[3].val.bitmap_val = _c->flags;
  646. vals2[4].type = DB1_INT;
  647. vals2[4].nul = 0;
  648. vals2[4].val.bitmap_val = _c->cflags;
  649. vals2[5].type = DB1_STR;
  650. vals2[5].nul = 0;
  651. vals2[5].val.str_val = _c->user_agent;
  652. vals2[6].type = DB1_STR;
  653. if (_c->received.s == 0) {
  654. vals2[6].nul = 1;
  655. } else {
  656. vals2[6].nul = 0;
  657. vals2[6].val.str_val = _c->received;
  658. }
  659. vals2[7].type = DB1_STR;
  660. if (_c->path.s == 0) {
  661. vals2[7].nul = 1;
  662. } else {
  663. vals2[7].nul = 0;
  664. vals2[7].val.str_val = _c->path;
  665. }
  666. vals2[8].type = DB1_STR;
  667. if (_c->sock) {
  668. vals2[8].val.str_val = _c->sock->sock_str;
  669. vals2[8].nul = 0;
  670. } else {
  671. vals2[8].nul = 1;
  672. }
  673. vals2[9].type = DB1_BITMAP;
  674. if (_c->methods == 0xFFFFFFFF) {
  675. vals2[9].nul = 1;
  676. } else {
  677. vals2[9].val.bitmap_val = _c->methods;
  678. vals2[9].nul = 0;
  679. }
  680. vals2[10].nul = 0;
  681. UL_DB_EXPIRES_SET(&vals2[10], _c->last_modified);
  682. nr_cols2 = 11;
  683. if(_c->ruid.len>0)
  684. {
  685. vals2[nr_cols2].type = DB1_STR;
  686. vals2[nr_cols2].nul = 0;
  687. vals2[nr_cols2].val.str_val = _c->ruid;
  688. } else {
  689. vals2[nr_cols2].nul = 1;
  690. }
  691. nr_cols2++;
  692. if(_c->instance.len>0)
  693. {
  694. vals2[nr_cols2].type = DB1_STR;
  695. vals2[nr_cols2].nul = 0;
  696. vals2[nr_cols2].val.str_val = _c->instance;
  697. } else {
  698. vals2[nr_cols2].nul = 1;
  699. }
  700. nr_cols2++;
  701. vals2[nr_cols2].type = DB1_INT;
  702. vals2[nr_cols2].nul = 0;
  703. vals2[nr_cols2].val.int_val = (int)_c->reg_id;
  704. nr_cols2++;
  705. keys2[nr_cols2] = &contact_col;
  706. vals2[nr_cols2].type = DB1_STR;
  707. vals2[nr_cols2].nul = 0;
  708. vals2[nr_cols2].val.str_val = _c->c;
  709. LM_DBG("contact:%.*s\n", vals2[nr_cols2].val.str_val.len, vals2[nr_cols2].val.str_val.s);
  710. nr_cols2++;
  711. if (use_domain) {
  712. keys1[n1] = &domain_col;
  713. vals1[n1].type = DB1_STR;
  714. vals1[n1].nul = 0;
  715. dom = memchr(_c->aor->s, '@', _c->aor->len);
  716. if (dom==0) {
  717. vals1[0].val.str_val.len = 0;
  718. vals1[n1].val.str_val = *_c->aor;
  719. } else {
  720. vals1[0].val.str_val.len = dom - _c->aor->s;
  721. vals1[n1].val.str_val.s = dom + 1;
  722. vals1[n1].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
  723. }
  724. n1++;
  725. }
  726. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  727. LM_ERR("sql use_table failed\n");
  728. return -1;
  729. }
  730. if (ul_dbf.update(ul_dbh, keys1, 0, vals1, keys2, vals2, n1,
  731. nr_cols2) < 0) {
  732. LM_ERR("updating database failed\n");
  733. return -1;
  734. }
  735. if (ul_db_check_update==1 && ul_dbf.affected_rows) {
  736. /* supposed to be an UPDATE, but if affected rows is 0, then try
  737. * to do an INSERT */
  738. if(ul_dbf.affected_rows(ul_dbh)==0) {
  739. LM_DBG("affected rows by UPDATE was 0, doing an INSERT\n");
  740. if(db_insert_ucontact(_c)<0)
  741. return -1;
  742. }
  743. }
  744. /* delete old db attrs and add the current list */
  745. if (ul_xavp_contact_name.s) {
  746. if (use_domain) {
  747. uldb_delete_attrs(_c->domain, &vals1[0].val.str_val,
  748. &vals1[n1-1].val.str_val, &_c->ruid);
  749. uldb_insert_attrs(_c->domain, &vals1[0].val.str_val,
  750. &vals1[n1-1].val.str_val,
  751. &_c->ruid, _c->xavp);
  752. } else {
  753. uldb_delete_attrs(_c->domain, &vals1[0].val.str_val,
  754. NULL, &_c->ruid);
  755. uldb_insert_attrs(_c->domain, &vals1[0].val.str_val,
  756. NULL, &_c->ruid, _c->xavp);
  757. }
  758. }
  759. return 0;
  760. }
  761. /*!
  762. * \brief Update contact in the database by ruid
  763. * \param _c updated contact
  764. * \return 0 on success, -1 on failure
  765. */
  766. int db_update_ucontact_ruid(ucontact_t* _c)
  767. {
  768. str auser;
  769. str adomain;
  770. db_key_t keys1[1];
  771. db_val_t vals1[1];
  772. int n1;
  773. db_key_t keys2[15];
  774. db_val_t vals2[15];
  775. int n2;
  776. if (_c->flags & FL_MEM) {
  777. return 0;
  778. }
  779. if(_c->ruid.len<=0) {
  780. LM_ERR("updating record in database failed - empty ruid\n");
  781. return -1;
  782. }
  783. n1 = 0;
  784. keys1[n1] = &ruid_col;
  785. vals1[n1].type = DB1_STR;
  786. vals1[n1].nul = 0;
  787. vals1[n1].val.str_val = _c->ruid;
  788. LM_DBG("ruid:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  789. n1++;
  790. n2 = 0;
  791. keys2[n2] = &expires_col;
  792. vals2[n2].nul = 0;
  793. UL_DB_EXPIRES_SET(&vals2[n2], _c->expires);
  794. n2++;
  795. keys2[n2] = &q_col;
  796. vals2[n2].type = DB1_DOUBLE;
  797. vals2[n2].nul = 0;
  798. vals2[n2].val.double_val = q2double(_c->q);
  799. n2++;
  800. keys2[n2] = &cseq_col;
  801. vals2[n2].type = DB1_INT;
  802. vals2[n2].nul = 0;
  803. vals2[n2].val.int_val = _c->cseq;
  804. n2++;
  805. keys2[n2] = &flags_col;
  806. vals2[n2].type = DB1_INT;
  807. vals2[n2].nul = 0;
  808. vals2[n2].val.bitmap_val = _c->flags;
  809. n2++;
  810. keys2[n2] = &cflags_col;
  811. vals2[n2].type = DB1_INT;
  812. vals2[n2].nul = 0;
  813. vals2[n2].val.bitmap_val = _c->cflags;
  814. n2++;
  815. keys2[n2] = &user_agent_col;
  816. vals2[n2].type = DB1_STR;
  817. vals2[n2].nul = 0;
  818. vals2[n2].val.str_val = _c->user_agent;
  819. n2++;
  820. keys2[n2] = &received_col;
  821. vals2[n2].type = DB1_STR;
  822. if (_c->received.s == 0) {
  823. vals2[n2].nul = 1;
  824. } else {
  825. vals2[n2].nul = 0;
  826. vals2[n2].val.str_val = _c->received;
  827. }
  828. n2++;
  829. keys2[n2] = &path_col;
  830. vals2[n2].type = DB1_STR;
  831. if (_c->path.s == 0) {
  832. vals2[n2].nul = 1;
  833. } else {
  834. vals2[n2].nul = 0;
  835. vals2[n2].val.str_val = _c->path;
  836. }
  837. n2++;
  838. keys2[n2] = &sock_col;
  839. vals2[n2].type = DB1_STR;
  840. if (_c->sock) {
  841. vals2[n2].val.str_val = _c->sock->sock_str;
  842. vals2[n2].nul = 0;
  843. } else {
  844. vals2[n2].nul = 1;
  845. }
  846. n2++;
  847. keys2[n2] = &methods_col;
  848. vals2[n2].type = DB1_BITMAP;
  849. if (_c->methods == 0xFFFFFFFF) {
  850. vals2[n2].nul = 1;
  851. } else {
  852. vals2[n2].val.bitmap_val = _c->methods;
  853. vals2[n2].nul = 0;
  854. }
  855. n2++;
  856. keys2[n2] = &last_mod_col;
  857. vals2[n2].nul = 0;
  858. UL_DB_EXPIRES_SET(&vals2[n2], _c->last_modified);
  859. n2++;
  860. keys2[n2] = &callid_col;
  861. vals2[n2].type = DB1_STR;
  862. vals2[n2].nul = 0;
  863. vals2[n2].val.str_val = _c->callid;
  864. n2++;
  865. keys2[n2] = &instance_col;
  866. if(_c->instance.len>0)
  867. {
  868. vals2[n2].type = DB1_STR;
  869. vals2[n2].nul = 0;
  870. vals2[n2].val.str_val = _c->instance;
  871. } else {
  872. vals2[n2].nul = 1;
  873. }
  874. n2++;
  875. keys2[n2] = &reg_id_col;
  876. vals2[n2].type = DB1_INT;
  877. vals2[n2].nul = 0;
  878. vals2[n2].val.int_val = (int)_c->reg_id;
  879. n2++;
  880. keys2[n2] = &contact_col;
  881. vals2[n2].type = DB1_STR;
  882. vals2[n2].nul = 0;
  883. vals2[n2].val.str_val = _c->c;
  884. LM_DBG("contact:%.*s\n", vals2[n2].val.str_val.len, vals2[n2].val.str_val.s);
  885. n2++;
  886. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  887. LM_ERR("sql use_table failed\n");
  888. return -1;
  889. }
  890. if (ul_dbf.update(ul_dbh, keys1, 0, vals1, keys2, vals2, n1, n2) < 0) {
  891. LM_ERR("updating database failed\n");
  892. return -1;
  893. }
  894. if (ul_db_check_update==1 && ul_dbf.affected_rows) {
  895. /* supposed to be an UPDATE, but if affected rows is 0, then try
  896. * to do an INSERT */
  897. if(ul_dbf.affected_rows(ul_dbh)==0) {
  898. LM_DBG("affected rows by UPDATE was 0, doing an INSERT\n");
  899. if(db_insert_ucontact(_c)<0)
  900. return -1;
  901. }
  902. }
  903. /* delete old db attrs and add the current list */
  904. if (ul_xavp_contact_name.s) {
  905. auser = *_c->aor;
  906. if (use_domain) {
  907. adomain.s = memchr(_c->aor->s, '@', _c->aor->len);
  908. if (adomain.s==0) {
  909. auser.len = 0;
  910. adomain = *_c->aor;
  911. } else {
  912. auser.len = adomain.s - _c->aor->s;
  913. adomain.s++;
  914. adomain.len = _c->aor->s +
  915. _c->aor->len - adomain.s;
  916. }
  917. uldb_delete_attrs(_c->domain, &auser,
  918. &adomain, &_c->ruid);
  919. uldb_insert_attrs(_c->domain, &auser,
  920. &adomain, &_c->ruid, _c->xavp);
  921. } else {
  922. uldb_delete_attrs(_c->domain, &auser,
  923. NULL, &_c->ruid);
  924. uldb_insert_attrs(_c->domain, &auser,
  925. NULL, &_c->ruid, _c->xavp);
  926. }
  927. }
  928. return 0;
  929. }
  930. /*!
  931. * \brief Update contact in the database by instance reg_id
  932. * \param _c updated contact
  933. * \return 0 on success, -1 on failure
  934. */
  935. int db_update_ucontact_instance(ucontact_t* _c)
  936. {
  937. str auser;
  938. str adomain;
  939. db_key_t keys1[4];
  940. db_val_t vals1[4];
  941. int n1;
  942. db_key_t keys2[13];
  943. db_val_t vals2[13];
  944. int n2;
  945. if (_c->flags & FL_MEM) {
  946. return 0;
  947. }
  948. if(_c->instance.len<=0) {
  949. LM_ERR("updating record in database failed - empty instance\n");
  950. return -1;
  951. }
  952. n1 = 0;
  953. keys1[n1] = &user_col;
  954. vals1[n1].type = DB1_STR;
  955. vals1[n1].nul = 0;
  956. vals1[n1].val.str_val = *_c->aor;
  957. LM_DBG("aor:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  958. n1++;
  959. keys1[n1] = &instance_col;
  960. vals1[n1].type = DB1_STR;
  961. vals1[n1].nul = 0;
  962. vals1[n1].val.str_val = _c->instance;
  963. LM_DBG("instance:%.*s\n", vals1[n1].val.str_val.len, vals1[n1].val.str_val.s);
  964. n1++;
  965. keys1[n1] = &reg_id_col;
  966. vals1[n1].type = DB1_INT;
  967. vals1[n1].nul = 0;
  968. vals1[n1].val.int_val = (int)_c->reg_id;
  969. LM_DBG("reg-id:%d\n", vals1[n1].val.int_val);
  970. n1++;
  971. n2 = 0;
  972. keys2[n2] = &expires_col;
  973. vals2[n2].nul = 0;
  974. UL_DB_EXPIRES_SET(&vals2[n2], _c->expires);
  975. n2++;
  976. keys2[n2] = &q_col;
  977. vals2[n2].type = DB1_DOUBLE;
  978. vals2[n2].nul = 0;
  979. vals2[n2].val.double_val = q2double(_c->q);
  980. n2++;
  981. keys2[n2] = &cseq_col;
  982. vals2[n2].type = DB1_INT;
  983. vals2[n2].nul = 0;
  984. vals2[n2].val.int_val = _c->cseq;
  985. n2++;
  986. keys2[n2] = &flags_col;
  987. vals2[n2].type = DB1_INT;
  988. vals2[n2].nul = 0;
  989. vals2[n2].val.bitmap_val = _c->flags;
  990. n2++;
  991. keys2[n2] = &cflags_col;
  992. vals2[n2].type = DB1_INT;
  993. vals2[n2].nul = 0;
  994. vals2[n2].val.bitmap_val = _c->cflags;
  995. n2++;
  996. keys2[n2] = &user_agent_col;
  997. vals2[n2].type = DB1_STR;
  998. vals2[n2].nul = 0;
  999. vals2[n2].val.str_val = _c->user_agent;
  1000. n2++;
  1001. keys2[n2] = &received_col;
  1002. vals2[n2].type = DB1_STR;
  1003. if (_c->received.s == 0) {
  1004. vals2[n2].nul = 1;
  1005. } else {
  1006. vals2[n2].nul = 0;
  1007. vals2[n2].val.str_val = _c->received;
  1008. }
  1009. n2++;
  1010. keys2[n2] = &path_col;
  1011. vals2[n2].type = DB1_STR;
  1012. if (_c->path.s == 0) {
  1013. vals2[n2].nul = 1;
  1014. } else {
  1015. vals2[n2].nul = 0;
  1016. vals2[n2].val.str_val = _c->path;
  1017. }
  1018. n2++;
  1019. keys2[n2] = &sock_col;
  1020. vals2[n2].type = DB1_STR;
  1021. if (_c->sock) {
  1022. vals2[n2].val.str_val = _c->sock->sock_str;
  1023. vals2[n2].nul = 0;
  1024. } else {
  1025. vals2[n2].nul = 1;
  1026. }
  1027. n2++;
  1028. keys2[n2] = &methods_col;
  1029. vals2[n2].type = DB1_BITMAP;
  1030. if (_c->methods == 0xFFFFFFFF) {
  1031. vals2[n2].nul = 1;
  1032. } else {
  1033. vals2[n2].val.bitmap_val = _c->methods;
  1034. vals2[n2].nul = 0;
  1035. }
  1036. n2++;
  1037. keys2[n2] = &last_mod_col;
  1038. vals2[n2].nul = 0;
  1039. UL_DB_EXPIRES_SET(&vals2[n2], _c->last_modified);
  1040. n2++;
  1041. keys2[n2] = &callid_col;
  1042. vals2[n2].type = DB1_STR;
  1043. vals2[n2].nul = 0;
  1044. vals2[n2].val.str_val = _c->callid;
  1045. n2++;
  1046. keys2[n2] = &contact_col;
  1047. vals2[n2].type = DB1_STR;
  1048. vals2[n2].nul = 0;
  1049. vals2[n2].val.str_val.s = _c->c.s;
  1050. vals2[n2].val.str_val.len = _c->c.len;
  1051. LM_DBG("contact:%.*s\n", vals2[n2].val.str_val.len, vals2[n2].val.str_val.s);
  1052. n2++;
  1053. auser = *_c->aor;
  1054. if (use_domain) {
  1055. keys1[n1] = &domain_col;
  1056. vals1[n1].type = DB1_STR;
  1057. vals1[n1].nul = 0;
  1058. adomain.s = memchr(_c->aor->s, '@', _c->aor->len);
  1059. if (adomain.s==0) {
  1060. vals1[0].val.str_val.len = 0;
  1061. vals1[n1].val.str_val = *_c->aor;
  1062. auser.len = 0;
  1063. adomain = *_c->aor;
  1064. } else {
  1065. vals1[0].val.str_val.len = adomain.s - _c->aor->s;
  1066. vals1[n1].val.str_val.s = adomain.s + 1;
  1067. vals1[n1].val.str_val.len = _c->aor->s + _c->aor->len - adomain.s - 1;
  1068. auser.len = adomain.s - _c->aor->s;
  1069. adomain.s++;
  1070. adomain.len = _c->aor->s +
  1071. _c->aor->len - adomain.s;
  1072. }
  1073. n1++;
  1074. }
  1075. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  1076. LM_ERR("sql use_table failed\n");
  1077. return -1;
  1078. }
  1079. if (ul_dbf.update(ul_dbh, keys1, 0, vals1, keys2, vals2, n1, n2) < 0) {
  1080. LM_ERR("updating database failed\n");
  1081. return -1;
  1082. }
  1083. if (ul_db_check_update==1 && ul_dbf.affected_rows) {
  1084. LM_DBG("update affected_rows 0\n");
  1085. /* supposed to be an UPDATE, but if affected rows is 0, then try
  1086. * to do an INSERT */
  1087. if(ul_dbf.affected_rows(ul_dbh)==0) {
  1088. LM_DBG("affected rows by UPDATE was 0, doing an INSERT\n");
  1089. if(db_insert_ucontact(_c)<0)
  1090. return -1;
  1091. }
  1092. }
  1093. /* delete old db attrs and add the current list */
  1094. if (ul_xavp_contact_name.s) {
  1095. if (use_domain) {
  1096. uldb_delete_attrs(_c->domain, &auser,
  1097. &adomain, &_c->ruid);
  1098. uldb_insert_attrs(_c->domain, &auser,
  1099. &adomain, &_c->ruid, _c->xavp);
  1100. } else {
  1101. uldb_delete_attrs(_c->domain, &auser,
  1102. NULL, &_c->ruid);
  1103. uldb_insert_attrs(_c->domain, &auser,
  1104. NULL, &_c->ruid, _c->xavp);
  1105. }
  1106. }
  1107. return 0;
  1108. }
  1109. /*!
  1110. * \brief Update contact in the database
  1111. * \param _c updated contact
  1112. * \return 0 on success, -1 on failure
  1113. */
  1114. int db_update_ucontact(ucontact_t* _c)
  1115. {
  1116. if(ul_db_ops_ruid==0)
  1117. if (_c->instance.len<=0) {
  1118. return db_update_ucontact_addr(_c);
  1119. }
  1120. else {
  1121. return db_update_ucontact_instance(_c);
  1122. }
  1123. else
  1124. return db_update_ucontact_ruid(_c);
  1125. }
  1126. /*!
  1127. * \brief Delete contact from the database by address
  1128. * \param _c deleted contact
  1129. * \return 0 on success, -1 on failure
  1130. */
  1131. int db_delete_ucontact_addr(ucontact_t* _c)
  1132. {
  1133. char* dom;
  1134. db_key_t keys[4];
  1135. db_val_t vals[4];
  1136. int n;
  1137. if (_c->flags & FL_MEM) {
  1138. return 0;
  1139. }
  1140. n = 0;
  1141. keys[n] = &user_col;
  1142. vals[n].type = DB1_STR;
  1143. vals[n].nul = 0;
  1144. vals[n].val.str_val = *_c->aor;
  1145. n++;
  1146. keys[n] = &contact_col;
  1147. vals[n].type = DB1_STR;
  1148. vals[n].nul = 0;
  1149. vals[n].val.str_val = _c->c;
  1150. n++;
  1151. keys[n] = &callid_col;
  1152. vals[n].type = DB1_STR;
  1153. vals[n].nul = 0;
  1154. vals[n].val.str_val = _c->callid;
  1155. n++;
  1156. if (use_domain) {
  1157. keys[n] = &domain_col;
  1158. vals[n].type = DB1_STR;
  1159. vals[n].nul = 0;
  1160. dom = memchr(_c->aor->s, '@', _c->aor->len);
  1161. if (dom==0) {
  1162. vals[0].val.str_val.len = 0;
  1163. vals[n].val.str_val = *_c->aor;
  1164. } else {
  1165. vals[0].val.str_val.len = dom - _c->aor->s;
  1166. vals[n].val.str_val.s = dom + 1;
  1167. vals[n].val.str_val.len = _c->aor->s +
  1168. _c->aor->len - dom - 1;
  1169. }
  1170. uldb_delete_attrs(_c->domain, &vals[0].val.str_val,
  1171. &vals[n].val.str_val, &_c->ruid);
  1172. n++;
  1173. } else {
  1174. uldb_delete_attrs(_c->domain, &vals[0].val.str_val,
  1175. NULL, &_c->ruid);
  1176. }
  1177. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  1178. LM_ERR("sql use_table failed\n");
  1179. return -1;
  1180. }
  1181. if (ul_dbf.delete(ul_dbh, keys, 0, vals, n) < 0) {
  1182. LM_ERR("deleting from database failed\n");
  1183. return -1;
  1184. }
  1185. return 0;
  1186. }
  1187. /*!
  1188. * \brief Delete contact from the database by ruid
  1189. * \param _c deleted contact
  1190. * \return 0 on success, -1 on failure
  1191. */
  1192. int db_delete_ucontact_ruid(ucontact_t* _c)
  1193. {
  1194. db_key_t keys[1];
  1195. db_val_t vals[1];
  1196. int n;
  1197. if (_c->flags & FL_MEM) {
  1198. return 0;
  1199. }
  1200. if(_c->ruid.len<=0) {
  1201. LM_ERR("deleting from database failed - empty ruid\n");
  1202. return -1;
  1203. }
  1204. n = 0;
  1205. keys[n] = &ruid_col;
  1206. vals[n].type = DB1_STR;
  1207. vals[n].nul = 0;
  1208. vals[n].val.str_val = _c->ruid;
  1209. n++;
  1210. if (ul_dbf.use_table(ul_dbh, _c->domain) < 0) {
  1211. LM_ERR("sql use_table failed\n");
  1212. return -1;
  1213. }
  1214. if (ul_dbf.delete(ul_dbh, keys, 0, vals, n) < 0) {
  1215. LM_ERR("deleting from database failed\n");
  1216. return -1;
  1217. }
  1218. return 0;
  1219. }
  1220. /*!
  1221. * \brief Delete contact from the database
  1222. * \param _c deleted contact
  1223. * \return 0 on success, -1 on failure
  1224. */
  1225. int db_delete_ucontact(ucontact_t* _c)
  1226. {
  1227. if(ul_db_ops_ruid==0)
  1228. return db_delete_ucontact_addr(_c);
  1229. else
  1230. return db_delete_ucontact_ruid(_c);
  1231. }
  1232. /*!
  1233. * \brief Remove a contact from list belonging to a certain record
  1234. * \param _r record the contact belongs
  1235. * \param _c removed contact
  1236. */
  1237. static inline void unlink_contact(struct urecord* _r, ucontact_t* _c)
  1238. {
  1239. if (_c->prev) {
  1240. _c->prev->next = _c->next;
  1241. if (_c->next) {
  1242. _c->next->prev = _c->prev;
  1243. }
  1244. } else {
  1245. _r->contacts = _c->next;
  1246. if (_c->next) {
  1247. _c->next->prev = 0;
  1248. }
  1249. }
  1250. }
  1251. /*!
  1252. * \brief Insert a new contact into the list at the correct position
  1253. * \param _r record that holds the sorted contacts
  1254. * \param _c new contact
  1255. */
  1256. static inline void update_contact_pos(struct urecord* _r, ucontact_t* _c)
  1257. {
  1258. ucontact_t *pos, *ppos;
  1259. if (desc_time_order) {
  1260. /* order by time - first the newest */
  1261. if (_c->prev==0)
  1262. return;
  1263. unlink_contact(_r, _c);
  1264. /* insert it at the beginning */
  1265. _c->next = _r->contacts;
  1266. _c->prev = 0;
  1267. _r->contacts->prev = _c;
  1268. _r->contacts = _c;
  1269. } else {
  1270. /* order by q - first the smaller q */
  1271. if ( (_c->prev==0 || _c->q<=_c->prev->q)
  1272. && (_c->next==0 || _c->q>=_c->next->q) )
  1273. return;
  1274. /* need to move , but where? */
  1275. unlink_contact(_r, _c);
  1276. _c->next = _c->prev = 0;
  1277. for(pos=_r->contacts,ppos=0;pos&&pos->q<_c->q;ppos=pos,pos=pos->next);
  1278. if (pos) {
  1279. if (!pos->prev) {
  1280. pos->prev = _c;
  1281. _c->next = pos;
  1282. _r->contacts = _c;
  1283. } else {
  1284. _c->next = pos;
  1285. _c->prev = pos->prev;
  1286. pos->prev->next = _c;
  1287. pos->prev = _c;
  1288. }
  1289. } else if (ppos) {
  1290. ppos->next = _c;
  1291. _c->prev = ppos;
  1292. } else {
  1293. _r->contacts = _c;
  1294. }
  1295. }
  1296. }
  1297. /*!
  1298. * \brief Update ucontact with new values
  1299. * \param _r record the contact belongs to
  1300. * \param _c updated contact
  1301. * \param _ci new contact informations
  1302. * \return 0 on success, -1 on failure
  1303. */
  1304. int update_ucontact(struct urecord* _r, ucontact_t* _c, ucontact_info_t* _ci)
  1305. {
  1306. int res;
  1307. /* we have to update memory in any case, but database directly
  1308. * only in db_mode 1 */
  1309. if (mem_update_ucontact( _c, _ci) < 0) {
  1310. LM_ERR("failed to update memory\n");
  1311. return -1;
  1312. }
  1313. /* run callbacks for UPDATE event */
  1314. if (exists_ulcb_type(UL_CONTACT_UPDATE))
  1315. {
  1316. LM_DBG("exists callback for type= UL_CONTACT_UPDATE\n");
  1317. run_ul_callbacks( UL_CONTACT_UPDATE, _c);
  1318. }
  1319. if (_r && db_mode!=DB_ONLY)
  1320. update_contact_pos( _r, _c);
  1321. st_update_ucontact(_c);
  1322. if (db_mode == WRITE_THROUGH || db_mode==DB_ONLY) {
  1323. if (ul_db_update_as_insert)
  1324. res = db_insert_ucontact(_c);
  1325. else
  1326. res = db_update_ucontact(_c);
  1327. if (res < 0) {
  1328. LM_ERR("failed to update database\n");
  1329. return -1;
  1330. } else {
  1331. _c->state = CS_SYNC;
  1332. }
  1333. }
  1334. return 0;
  1335. }
  1336. /*!
  1337. * \brief Load all location attributes from a udomain
  1338. *
  1339. * Load all location attributes from a udomain, useful to populate the
  1340. * memory cache on startup.
  1341. * \param _dname loaded domain name
  1342. * \param _user sip username
  1343. * \param _domain sip domain
  1344. * \param _ruid usrloc record unique id
  1345. * \return 0 on success, -1 on failure
  1346. */
  1347. int uldb_delete_attrs(str* _dname, str *_user, str *_domain, str *_ruid)
  1348. {
  1349. char tname_buf[64];
  1350. str tname;
  1351. db_key_t keys[3];
  1352. db_val_t vals[3];
  1353. LM_DBG("trying to delete location attributes\n");
  1354. if(ul_xavp_contact_name.s==NULL) {
  1355. /* feature disabled by mod param */
  1356. return 0;
  1357. }
  1358. if(_dname->len+6>=64) {
  1359. LM_ERR("attributes table name is too big\n");
  1360. return -1;
  1361. }
  1362. strncpy(tname_buf, _dname->s, _dname->len);
  1363. tname_buf[_dname->len] = '\0';
  1364. strcat(tname_buf, "_attrs");
  1365. tname.s = tname_buf;
  1366. tname.len = _dname->len + 6;
  1367. keys[0] = &ulattrs_user_col;
  1368. keys[1] = &ulattrs_ruid_col;
  1369. keys[2] = &ulattrs_domain_col;
  1370. vals[0].type = DB1_STR;
  1371. vals[0].nul = 0;
  1372. vals[0].val.str_val = *_user;
  1373. vals[1].type = DB1_STR;
  1374. vals[1].nul = 0;
  1375. vals[1].val.str_val = *_ruid;
  1376. if (use_domain) {
  1377. vals[2].type = DB1_STR;
  1378. vals[2].nul = 0;
  1379. vals[2].val.str_val = *_domain;
  1380. }
  1381. if (ul_dbf.use_table(ul_dbh, &tname) < 0) {
  1382. LM_ERR("sql use_table failed\n");
  1383. return -1;
  1384. }
  1385. if (ul_dbf.delete(ul_dbh, keys, 0, vals, (use_domain) ? (3) : (2)) < 0) {
  1386. LM_ERR("deleting from database failed\n");
  1387. return -1;
  1388. }
  1389. return 0;
  1390. }
  1391. /*!
  1392. * \brief Insert contact attributes into the database
  1393. * \param _dname loaded domain name
  1394. * \param _user sip username
  1395. * \param _domain sip domain
  1396. * \param _ruid record unique id
  1397. * \param _xhead head of xavp list
  1398. * \return 0 on success, -1 on failure
  1399. */
  1400. int uldb_insert_attrs(str *_dname, str *_user, str *_domain,
  1401. str *_ruid, sr_xavp_t *_xhead)
  1402. {
  1403. char tname_buf[64];
  1404. str tname;
  1405. str avalue;
  1406. sr_xavp_t *xavp;
  1407. db_key_t keys[7];
  1408. db_val_t vals[7];
  1409. int nr_cols;
  1410. LM_DBG("trying to insert location attributes\n");
  1411. if(ul_xavp_contact_name.s==NULL) {
  1412. /* feature disabled by mod param */
  1413. LM_DBG("location attributes disabled\n");
  1414. return 0;
  1415. }
  1416. if(_xhead==NULL || _xhead->val.type!=SR_XTYPE_XAVP
  1417. || _xhead->val.v.xavp==NULL) {
  1418. /* nothing to write */
  1419. LM_DBG("no location attributes\n");
  1420. return 0;
  1421. }
  1422. if(_dname->len+6>=64) {
  1423. LM_ERR("attributes table name is too big\n");
  1424. return -1;
  1425. }
  1426. strncpy(tname_buf, _dname->s, _dname->len);
  1427. tname_buf[_dname->len] = '\0';
  1428. strcat(tname_buf, "_attrs");
  1429. tname.s = tname_buf;
  1430. tname.len = _dname->len + 6;
  1431. if (ul_dbf.use_table(ul_dbh, &tname) < 0) {
  1432. LM_ERR("sql use_table failed for %.*s\n", tname.len, tname.s);
  1433. return -1;
  1434. }
  1435. keys[0] = &ulattrs_user_col;
  1436. keys[1] = &ulattrs_ruid_col;
  1437. keys[2] = &ulattrs_last_mod_col;
  1438. keys[3] = &ulattrs_aname_col;
  1439. keys[4] = &ulattrs_atype_col;
  1440. keys[5] = &ulattrs_avalue_col;
  1441. keys[6] = &ulattrs_domain_col;
  1442. vals[0].type = DB1_STR;
  1443. vals[0].nul = 0;
  1444. vals[0].val.str_val = *_user;
  1445. vals[1].type = DB1_STR;
  1446. vals[1].nul = 0;
  1447. vals[1].val.str_val = *_ruid;
  1448. vals[2].nul = 0;
  1449. UL_DB_EXPIRES_SET(&vals[2], time(NULL));
  1450. if (use_domain && _domain!=NULL && _domain->s!=NULL) {
  1451. nr_cols = 7;
  1452. vals[6].type = DB1_STR;
  1453. vals[6].nul = 0;
  1454. vals[6].val.str_val = *_domain;
  1455. } else {
  1456. nr_cols = 6;
  1457. }
  1458. for(xavp=_xhead->val.v.xavp; xavp; xavp=xavp->next) {
  1459. vals[3].type = DB1_STR;
  1460. vals[3].nul = 0;
  1461. vals[3].val.str_val = xavp->name;
  1462. vals[4].type = DB1_INT;
  1463. vals[4].nul = 0;
  1464. if(xavp->val.type==SR_XTYPE_STR) {
  1465. vals[4].val.int_val = 0;
  1466. avalue = xavp->val.v.s;
  1467. } else if(xavp->val.type==SR_XTYPE_INT) {
  1468. vals[4].val.int_val = 1;
  1469. avalue.s = sint2str((long)xavp->val.v.i, &avalue.len);
  1470. } else {
  1471. continue;
  1472. }
  1473. vals[5].type = DB1_STR;
  1474. vals[5].nul = 0;
  1475. vals[5].val.str_val = avalue;
  1476. if (ul_dbf.insert(ul_dbh, keys, vals, nr_cols) < 0) {
  1477. LM_ERR("inserting contact in db failed\n");
  1478. return -1;
  1479. }
  1480. }
  1481. return 0;
  1482. }