2
0

dlg_hash.c 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  1. /*!
  2. * \file
  3. * \brief Functions related to dialog creation and searching
  4. * \ingroup dialog
  5. * Module: \ref dialog
  6. */
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "../../dprint.h"
  10. #include "../../ut.h"
  11. #include "../../lib/kmi/mi.h"
  12. #include "dlg_timer.h"
  13. #include "dlg_var.h"
  14. #include "dlg_hash.h"
  15. #include "dlg_profile.h"
  16. #include "dlg_handlers.h"
  17. #include "dlg_db_handler.h"
  18. #define MAX_LDG_LOCKS 2048
  19. #define MIN_LDG_LOCKS 2
  20. extern int dlg_db_mode;
  21. /*! global dialog table */
  22. struct dlg_table *d_table = 0;
  23. /*! global dialog out table */
  24. static int dlg_hash_size_out = 4096;
  25. /*!
  26. * \brief Reference a dialog without locking
  27. * \param _dlg dialog
  28. * \param _cnt increment for the reference counter
  29. */
  30. #define ref_dlg_unsafe(_dlg,_cnt) \
  31. do { \
  32. (_dlg)->ref += (_cnt); \
  33. LM_DBG("ref dlg %p with %d -> %d\n", \
  34. (_dlg),(_cnt),(_dlg)->ref); \
  35. }while(0)
  36. /*!
  37. * \brief Unreference a dialog without locking
  38. * \param _dlg dialog
  39. * \param _cnt decrement for the reference counter
  40. * \param _d_entry dialog entry
  41. */
  42. #define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \
  43. do { \
  44. (_dlg)->ref -= (_cnt); \
  45. LM_DBG("unref dlg %p with %d -> %d\n",\
  46. (_dlg),(_cnt),(_dlg)->ref);\
  47. if ((_dlg)->ref<0) {\
  48. LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\
  49. "with clid '%.*s' and tags '%.*s'\n",\
  50. (_dlg)->ref, _cnt, _dlg,\
  51. (_dlg)->h_entry, (_dlg)->h_id,\
  52. (_dlg)->callid.len, (_dlg)->callid.s,\
  53. (_dlg)->from_tag.len,\
  54. (_dlg)->from_tag.s);\
  55. }\
  56. if ((_dlg)->ref<=0) { \
  57. unlink_unsafe_dlg( _d_entry, _dlg);\
  58. LM_DBG("ref <=0 for dialog %p\n",_dlg);\
  59. destroy_dlg(_dlg);\
  60. }\
  61. }while(0)
  62. /*!
  63. * \brief Initialize the global dialog table
  64. * \param size size of the table
  65. * \return 0 on success, -1 on failure
  66. */
  67. int init_dlg_table(unsigned int size) {
  68. unsigned int n;
  69. unsigned int i;
  70. d_table = (struct dlg_table*) shm_malloc
  71. (sizeof (struct dlg_table) +size * sizeof (struct dlg_entry));
  72. if (d_table == 0) {
  73. LM_ERR("no more shm mem (1)\n");
  74. goto error0;
  75. }
  76. memset(d_table, 0, sizeof (struct dlg_table));
  77. d_table->size = size;
  78. d_table->entries = (struct dlg_entry*) (d_table + 1);
  79. n = (size < MAX_LDG_LOCKS) ? size : MAX_LDG_LOCKS;
  80. for (; n >= MIN_LDG_LOCKS; n--) {
  81. d_table->locks = lock_set_alloc(n);
  82. if (d_table->locks == 0)
  83. continue;
  84. if (lock_set_init(d_table->locks) == 0) {
  85. lock_set_dealloc(d_table->locks);
  86. d_table->locks = 0;
  87. continue;
  88. }
  89. d_table->locks_no = n;
  90. break;
  91. }
  92. if (d_table->locks == 0) {
  93. LM_ERR("unable to allocted at least %d locks for the hash table\n",
  94. MIN_LDG_LOCKS);
  95. goto error1;
  96. }
  97. for (i = 0; i < size; i++) {
  98. memset(&(d_table->entries[i]), 0, sizeof (struct dlg_entry));
  99. d_table->entries[i].next_id = rand() % (3*size);
  100. d_table->entries[i].lock_idx = i % d_table->locks_no;
  101. }
  102. return 0;
  103. error1:
  104. shm_free(d_table);
  105. error0:
  106. return -1;
  107. }
  108. /*!
  109. * \brief free all the memory in the entry_out structure
  110. * \param d_entry_out structure
  111. * \return void
  112. */
  113. static void destroy_entry_out(struct dlg_entry_out *d_entry_out) {
  114. struct dlg_cell_out *dlg_out;
  115. struct dlg_cell_out *dlg_out_tmp;
  116. dlg_out = d_entry_out->first;
  117. LM_DBG("Destroy dialog entry out\n");
  118. while (dlg_out) {
  119. //clear all dlg_out memory space
  120. if (dlg_out->caller_cseq.s) {
  121. LM_DBG("content before freeing caller cseq is [%.*s]\n", dlg_out->caller_cseq.len, dlg_out->caller_cseq.s);
  122. shm_free(dlg_out->caller_cseq.s);
  123. }
  124. if (dlg_out->callee_cseq.s) {
  125. LM_DBG("content before freeing callee cseq is [%.*s]\n", dlg_out->callee_cseq.len, dlg_out->callee_cseq.s);
  126. shm_free(dlg_out->callee_cseq.s);
  127. }
  128. if (dlg_out->callee_contact.s) {
  129. LM_DBG("content before freeing callee contact is [%.*s]\n", dlg_out->callee_contact.len, dlg_out->callee_contact.s);
  130. shm_free(dlg_out->callee_contact.s);
  131. }
  132. if (dlg_out->callee_route_set.s) {
  133. shm_free(dlg_out->callee_route_set.s);
  134. }
  135. if (dlg_out->did.s) {
  136. shm_free(dlg_out->did.s);
  137. }
  138. dlg_out_tmp = dlg_out->next;
  139. shm_free(dlg_out);
  140. dlg_out = dlg_out_tmp;
  141. }
  142. }
  143. /*!
  144. * \brief Destroy a dialog, run callbacks and free memory
  145. * \param dlg destroyed dialog
  146. */
  147. inline void destroy_dlg(struct dlg_cell *dlg) {
  148. int ret = 0;
  149. struct dlg_var *var;
  150. LM_DBG("destroying dialog %p\n", dlg);
  151. ret = remove_dialog_timer(&dlg->tl);
  152. if (ret < 0) {
  153. LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] "
  154. "with clid '%.*s' and tags '%.*s'\n",
  155. dlg, dlg->h_entry, dlg->h_id,
  156. dlg->callid.len, dlg->callid.s,
  157. dlg->from_tag.len, dlg->from_tag.s);
  158. } else if (ret > 0) {
  159. LM_DBG("removed timer for dlg %p [%u:%u] "
  160. "with clid '%.*s' and tags '%.*s' \n",
  161. dlg, dlg->h_entry, dlg->h_id,
  162. dlg->callid.len, dlg->callid.s,
  163. dlg->from_tag.len, dlg->from_tag.s);
  164. }
  165. if (dlg_db_mode)
  166. remove_dialog_in_from_db(dlg);
  167. LM_DBG("About to run dlg callback for destroy\n");
  168. run_dlg_callbacks(DLGCB_DESTROY, dlg, NULL, NULL, DLG_DIR_NONE, 0);
  169. LM_DBG("DONE: About to run dlg callback for destroy\n");
  170. if (dlg == get_current_dlg_pointer())
  171. reset_current_dlg_pointer();
  172. if (dlg->cbs.first)
  173. destroy_dlg_callbacks_list(dlg->cbs.first);
  174. if (dlg->profile_links)
  175. destroy_linkers(dlg->profile_links);
  176. if (dlg->from_tag.s)
  177. shm_free(dlg->from_tag.s);
  178. if (dlg->first_req_cseq.s)
  179. shm_free(dlg->first_req_cseq.s);
  180. if (dlg->toroute_name.s)
  181. shm_free(dlg->toroute_name.s);
  182. if (dlg->did.s)
  183. shm_free(dlg->did.s);
  184. if (dlg->caller_route_set.s)
  185. shm_free(dlg->caller_route_set.s);
  186. if (dlg->caller_contact.s)
  187. shm_free(dlg->caller_contact.s);
  188. while (dlg->vars) {
  189. var = dlg->vars;
  190. dlg->vars = dlg->vars->next;
  191. shm_free(var->key.s);
  192. shm_free(var->value.s);
  193. shm_free(var);
  194. }
  195. if (&(dlg->dlg_entry_out)) {
  196. lock_get(dlg->dlg_out_entries_lock);
  197. destroy_entry_out(&(dlg->dlg_entry_out));
  198. lock_release(dlg->dlg_out_entries_lock);
  199. }
  200. lock_destroy(dlg->dlg_out_entries_lock);
  201. lock_dealloc(dlg->dlg_out_entries_lock);
  202. shm_free(dlg);
  203. dlg = 0;
  204. }
  205. /*!
  206. * \brief Destroy the global dialog table
  207. */
  208. void destroy_dlg_table(void) {
  209. struct dlg_cell *dlg, *l_dlg;
  210. unsigned int i;
  211. if (d_table == 0)
  212. return;
  213. if (d_table->locks) {
  214. lock_set_destroy(d_table->locks);
  215. lock_set_dealloc(d_table->locks);
  216. }
  217. for (i = 0; i < d_table->size; i++) {
  218. dlg = d_table->entries[i].first;
  219. while (dlg) {
  220. l_dlg = dlg;
  221. dlg = dlg->next;
  222. destroy_dlg(l_dlg);
  223. }
  224. }
  225. shm_free(d_table);
  226. d_table = 0;
  227. return;
  228. }
  229. /*!
  230. * \brief Create a new dialog structure for a SIP dialog
  231. * \param callid dialog callid
  232. * \param from_uri dialog from uri
  233. * \param to_uri dialog to uri
  234. * \param from_tag dialog from tag
  235. * \param req_uri dialog r-uri
  236. * \return created dialog structure on success, NULL otherwise
  237. */
  238. struct dlg_cell* build_new_dlg(str *callid, str *from_uri, str *from_tag, str *req_uri) {
  239. struct dlg_cell *dlg;
  240. int len;
  241. char *p;
  242. len = sizeof (struct dlg_cell) +callid->len + from_uri->len + req_uri->len;
  243. dlg = (struct dlg_cell*) shm_malloc(len);
  244. if (dlg == 0) {
  245. LM_ERR("no more shm mem (%d)\n", len);
  246. return 0;
  247. }
  248. memset(dlg, 0, len);
  249. dlg->dlg_out_entries_lock = lock_alloc();
  250. if (dlg->dlg_out_entries_lock == NULL) {
  251. LM_ERR("Cannot allocate lock for dlg out entries. Aborting...\n");
  252. shm_free(dlg);
  253. return 0;
  254. } else {
  255. if (lock_init(dlg->dlg_out_entries_lock) == NULL) {
  256. LM_ERR("Cannot init the lock for dlg out entries. Aborting...\n");
  257. lock_destroy(dlg->dlg_out_entries_lock);
  258. lock_dealloc(dlg->dlg_out_entries_lock);
  259. shm_free(dlg);
  260. return 0;
  261. }
  262. }
  263. dlg->state = DLG_STATE_UNCONFIRMED;
  264. dlg->h_entry = core_hash(callid, 0, d_table->size);
  265. LM_DBG("new dialog on hash %u\n", dlg->h_entry);
  266. p = (char*) (dlg + 1);
  267. dlg->callid.s = p;
  268. dlg->callid.len = callid->len;
  269. memcpy(p, callid->s, callid->len);
  270. p += callid->len;
  271. dlg->from_uri.s = p;
  272. dlg->from_uri.len = from_uri->len;
  273. memcpy(p, from_uri->s, from_uri->len);
  274. p += from_uri->len;
  275. dlg->req_uri.s = p;
  276. dlg->req_uri.len = req_uri->len;
  277. memcpy(p, req_uri->s, req_uri->len);
  278. p += req_uri->len;
  279. if (p != (((char*) dlg) + len)) {
  280. LM_CRIT("buffer overflow\n");
  281. shm_free(dlg);
  282. return 0;
  283. }
  284. return dlg;
  285. }
  286. /*!
  287. * \brief Set the leg information for an existing dialog
  288. * \param dlg dialog
  289. * \param tag from tag or to tag
  290. * \param rr record-routing information
  291. * \param contact caller or callee contact
  292. * \param cseq CSEQ of caller or callee
  293. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  294. * \return 0 on success, -1 on failure
  295. */
  296. int dlg_set_leg_info(struct dlg_cell *dlg, str* tag, str *rr, str *contact,
  297. str *cseq, struct socket_info *bind_addr, unsigned int leg) {
  298. if (!dlg) {
  299. return -1;
  300. }
  301. //create new dlg_out entry
  302. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  303. struct dlg_cell_out *dlg_out;
  304. if (leg == DLG_CALLER_LEG) {
  305. if (tag->len > 0) {
  306. dlg->from_tag.s = (char*) shm_malloc(tag->len);
  307. if (!dlg->from_tag.s) {
  308. LM_ERR("no more shm_mem\n");
  309. return -1;
  310. }
  311. memcpy(dlg->from_tag.s, tag->s, tag->len);
  312. dlg->from_tag.len = tag->len;
  313. }
  314. if (contact->len > 0) {
  315. dlg->caller_contact.s = (char*) shm_malloc(contact->len);
  316. if (!dlg->caller_contact.s) {
  317. LM_ERR("no more shm_mem\n");
  318. return -1;
  319. }
  320. memcpy(dlg->caller_contact.s, contact->s, contact->len);
  321. dlg->caller_contact.len = contact->len;
  322. }
  323. if (rr->len > 0) {
  324. dlg->caller_route_set.s = (char*) shm_malloc(rr->len);
  325. if (!dlg->caller_route_set.s) {
  326. LM_ERR("no more shm_mem\n");
  327. return -1;
  328. }
  329. memcpy(dlg->caller_route_set.s, rr->s, rr->len);
  330. dlg->caller_route_set.len = rr->len;
  331. }
  332. if (cseq->len > 0) {
  333. dlg->first_req_cseq.s = (char*) shm_malloc(cseq->len);
  334. if (!dlg->first_req_cseq.s) {
  335. LM_ERR("no more shm_mem\n");
  336. return -1;
  337. }
  338. memcpy(dlg->first_req_cseq.s, cseq->s, cseq->len);
  339. dlg->first_req_cseq.len = cseq->len;
  340. }
  341. } else {
  342. /* this is the callee side so we need to find the dialog_out entry with the correct to_tag
  343. and assign caller and callee cseq, callee contact, callee route_set
  344. */
  345. if (d_entry_out) {
  346. lock_get(dlg->dlg_out_entries_lock);
  347. dlg_out = d_entry_out->first;
  348. while (dlg_out) {
  349. LM_DBG("Searching out dialog with to_tag '%.*s' (looking for %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s, tag->len, tag->s);
  350. if (dlg_out->to_tag.len == tag->len && memcmp(dlg_out->to_tag.s, tag->s, dlg_out->to_tag.len) == 0) {
  351. LM_DBG("Found dialog_out entry with correct to_tag - updating leg info\n");
  352. if (contact->len > 0) {
  353. dlg_out->callee_contact.s = (char*) shm_malloc(contact->len);
  354. if (!dlg_out->callee_contact.s) {
  355. LM_ERR("no more shm mem\n");
  356. return -1; //if we're out of mem we dont really care about cleaning up - prob going to crash anyway
  357. }
  358. dlg_out->callee_contact.len = contact->len;
  359. memcpy(dlg_out->callee_contact.s, contact->s, contact->len);
  360. }
  361. if (rr->len > 0) {
  362. dlg_out->callee_route_set.s = (char*) shm_malloc(rr->len);
  363. if (!dlg_out->callee_route_set.s) {
  364. LM_ERR("no more shm mem\n");
  365. return -1; //if we're out of mem we dont really care about cleaning up - prob going to crash anyway
  366. }
  367. dlg_out->callee_route_set.len = rr->len;
  368. memcpy(dlg_out->callee_route_set.s, rr->s, rr->len);
  369. }
  370. if (cseq->len > 0) {
  371. dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len);
  372. dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len);
  373. if (!dlg_out->callee_cseq.s || !dlg_out->caller_cseq.s) {
  374. LM_ERR("no more shm mem\n");
  375. return -1; //if we're out of mem we dont really care about cleaning up - prob going to crash anyway
  376. }
  377. dlg_out->caller_cseq.len = cseq->len;
  378. memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len);
  379. dlg_out->callee_cseq.len = cseq->len;
  380. memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len);
  381. }
  382. dlg_out->callee_bind_addr = bind_addr;
  383. }
  384. dlg_out = dlg_out->next;
  385. }
  386. lock_release(dlg->dlg_out_entries_lock);
  387. } else {
  388. LM_ERR("This dialog has no dialog out entries\n");
  389. return -1;
  390. }
  391. }
  392. return 0;
  393. }
  394. /*!
  395. * \brief Create a new dialog out structure for a SIP dialog
  396. * \param to_tag - dialog to_tag
  397. * \return created dlg_out structure on success, NULL otherwise
  398. */
  399. struct dlg_cell_out* build_new_dlg_out(struct dlg_cell *dlg, str* to_uri, str* to_tag) {
  400. struct dlg_cell_out *dlg_out;
  401. int len;
  402. char *p;
  403. //len = sizeof (struct dlg_cell_out) +dlg->did.len + to_tag->len + to_uri->len;
  404. len = sizeof (struct dlg_cell_out) +to_tag->len + to_uri->len;
  405. dlg_out = (struct dlg_cell_out*) shm_malloc(len);
  406. if (dlg_out == 0) {
  407. LM_ERR("no more shm mem (%d)\n", len);
  408. return 0;
  409. }
  410. memset(dlg_out, 0, len);
  411. dlg_out->h_entry = core_hash(to_tag, 0, dlg_hash_size_out);
  412. LM_DBG("new dialog_out on hash %u\n", dlg_out->h_entry);
  413. p = (char*) (dlg_out + 1);
  414. //dlg_out->did.s = p;
  415. //dlg_out->did.len = dlg->did.len;
  416. //memcpy(p, dlg->did.s, dlg->did.len);
  417. //p += dlg->did.len;
  418. dlg_out->to_uri.s = p;
  419. dlg_out->to_uri.len = to_uri->len;
  420. memcpy(p, to_uri->s, to_uri->len);
  421. p += to_uri->len;
  422. dlg_out->to_tag.s = p;
  423. dlg_out->to_tag.len = to_tag->len;
  424. memcpy(p, to_tag->s, to_tag->len);
  425. p += to_tag->len;
  426. if (p != (((char*) dlg_out) + len)) {
  427. LM_CRIT("buffer overflow\n");
  428. shm_free(dlg_out);
  429. return 0;
  430. }
  431. //did might be updated (check update_did_dlg_out) if there is a concurrent call -therefore this should not be done as single block of memory
  432. //so Richard editted this to not have did in the single block of memory
  433. if (dlg->did.len > 0) {
  434. dlg_out->did.s = (char*) shm_malloc(dlg->did.len);
  435. if (!dlg_out->did.s) {
  436. LM_ERR("no more shm_mem\n");
  437. return 0;
  438. }
  439. memcpy(dlg_out->did.s, dlg->did.s, dlg->did.len);
  440. dlg_out->did.len = dlg->did.len;
  441. }
  442. return dlg_out;
  443. }
  444. /*!
  445. * \brief Free the memory for a dlg_out cell
  446. * \param dlg_out structure
  447. * \return void
  448. */
  449. void free_dlg_out_cell(struct dlg_cell_out *dlg_out) {
  450. if (dlg_out->callee_contact.s)
  451. shm_free(dlg_out->callee_contact.s);
  452. if (dlg_out->callee_cseq.s)
  453. shm_free(dlg_out->callee_cseq.s);
  454. if (dlg_out->callee_route_set.s)
  455. shm_free(dlg_out->callee_route_set.s);
  456. if (dlg_out->caller_cseq.s)
  457. shm_free(dlg_out->caller_cseq.s);
  458. //Richard removed this - it is free-ed two lines above!!??!
  459. //if (dlg_out->callee_route_set.s)
  460. // shm_free(dlg_out->callee_route_set.s);
  461. //Richard added this as the did is now malloc-ed separately and not as a single concurrent block (as the totag etc. are)
  462. if (dlg_out->did.s)
  463. shm_free(dlg_out->did.s);
  464. shm_free(dlg_out);
  465. }
  466. /*!
  467. * \brief Remove dlg_out entry identified by to_tag from dlg structure
  468. * \param dlg structure
  469. * \param dlg_out to_tag
  470. * \return void
  471. */
  472. void dlg_remove_dlg_out_tag(struct dlg_cell *dlg, str *to_tag) {
  473. lock_get(dlg->dlg_out_entries_lock);
  474. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  475. struct dlg_cell_out *pdlg_out = d_entry_out->first;
  476. struct dlg_cell_out *tmpdlg = 0;
  477. int only = 0;
  478. while (pdlg_out) {
  479. if (pdlg_out->deleted) {
  480. LM_DBG("Found dlg_out to remove\n");
  481. if (pdlg_out->prev) {
  482. pdlg_out->prev->next = pdlg_out->next;
  483. } else {
  484. //assume that we are first
  485. if (pdlg_out->next) {
  486. d_entry_out->first = pdlg_out->next;
  487. pdlg_out->next->prev = 0;
  488. } else {
  489. LM_ERR("dlg out entry has prev set to null and next set to null too\n");
  490. only = 1;
  491. }
  492. }
  493. if (pdlg_out->next) {
  494. pdlg_out->next->prev = pdlg_out->prev;
  495. } else {
  496. //we are likely the last
  497. if (pdlg_out->prev) {
  498. d_entry_out->last = pdlg_out->prev;
  499. } else {
  500. LM_ERR("dlg out next is NULL and so is prev");
  501. only = 1;
  502. }
  503. }
  504. tmpdlg = pdlg_out->next;
  505. free_dlg_out_cell(pdlg_out);
  506. pdlg_out = tmpdlg;
  507. if (only) {
  508. d_entry_out->last = 0;
  509. d_entry_out->first = 0;
  510. }
  511. } else {
  512. LM_DBG("Not deleting dlg_out as it is not set to deleted\n");
  513. pdlg_out = pdlg_out->next;
  514. }
  515. }
  516. lock_release(dlg->dlg_out_entries_lock);
  517. }
  518. /*!
  519. * \brief Remove all dlg_out entries from dlg structure expect that identified as dlg_do_not_remove
  520. * \param dlg_out cell - structure to not remove
  521. * \param mark_only - 1 then only mark for deletion, if 0 then delete
  522. * \return void
  523. */
  524. void dlg_remove_dlg_out(struct dlg_cell_out *dlg_out_do_not_remove, struct dlg_cell *dlg, int only_mark) {
  525. lock_get(dlg->dlg_out_entries_lock);
  526. //get dlg_out_entry list from dlg
  527. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  528. struct dlg_cell_out *dlg_out;
  529. //check if list is empty
  530. if ((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) {
  531. LM_DBG("There are no dlg_out entries\n");
  532. lock_release(dlg->dlg_out_entries_lock);
  533. return;
  534. }
  535. dlg_out = d_entry_out->first;
  536. LM_DBG("Scanning dlg_entry_out list for dlg_out entry with did: [%s]", dlg->did.s);
  537. //run through the list and for each dlg_out_entry:
  538. while (dlg_out) {
  539. //check if it is the dlg_out that we don't want to remove (compare the to-tags)
  540. if (dlg_out->to_tag.len == dlg_out_do_not_remove->to_tag.len &&
  541. memcmp(dlg_out->to_tag.s, dlg_out_do_not_remove->to_tag.s, dlg_out->to_tag.len) == 0) {
  542. LM_DBG("This is the dlg_out not to be removed!\n");
  543. } else {
  544. //check if this the last entry in the entry_table
  545. if ((d_entry_out->first == d_entry_out->last)) {
  546. //we shouldnt ever get here
  547. LM_DBG("This is the last dlg_out_entry in the dlg_entries_out\n");
  548. //this is the last then set entry_out-> first and entry_out->last to zero
  549. dlg->dlg_entry_out.first = dlg->dlg_entry_out.last = 0;
  550. } else {
  551. if (!only_mark) {
  552. LM_DBG("Deleteing dlg out structure\n");
  553. if (dlg_out->prev) {
  554. dlg_out->prev->next = dlg_out->next;
  555. }
  556. //make the next->previous dlg_out point to the previous of this dlg_out
  557. //do not do this if this is the last entry in the list as the next struct is null
  558. if (dlg_out->next) {
  559. dlg_out->next->prev = dlg_out->prev;
  560. }
  561. free_dlg_out_cell(dlg_out);
  562. } else {
  563. LM_DBG("Marking dlg_out structure for deletion - it should be deleted by tm callback instead to_tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s);
  564. dlg_out->deleted = 1;
  565. }
  566. }
  567. }
  568. dlg_out = dlg_out->next;
  569. }
  570. lock_release(dlg->dlg_out_entries_lock);
  571. }
  572. /*!
  573. * \brief Update or set the CSEQ for an existing dialog
  574. * \param dlg dialog
  575. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  576. * \param cseq CSEQ of caller or callee
  577. * \return 0 on success, -1 on failure
  578. */
  579. int dlg_update_cseq(struct dlg_cell * dlg, unsigned int leg, str *cseq, str *to_tag) {
  580. LM_DBG("trying to update cseq with seq [%.*s]\n", cseq->len, cseq->s);
  581. //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller cseq accordingly
  582. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  583. struct dlg_cell_out *dlg_out;
  584. dlg_out = d_entry_out->first;
  585. if (to_tag) {
  586. //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple)
  587. while (dlg_out) {
  588. if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) {
  589. //this parameter matches we have found the dlg_out to update the cseq
  590. if (leg == DLG_CALLER_LEG) {
  591. //update caller cseq
  592. if (dlg_out->caller_cseq.s) {
  593. if (dlg_out->caller_cseq.len < cseq->len) {
  594. shm_free(dlg_out->caller_cseq.s);
  595. dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len);
  596. if (dlg_out->caller_cseq.s == NULL)
  597. goto error;
  598. dlg_out->caller_cseq.len = cseq->len;
  599. memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len);
  600. }
  601. } else {
  602. dlg_out->caller_cseq.s = (char*) shm_malloc(cseq->len);
  603. if (dlg_out->caller_cseq.s == NULL)
  604. goto error;
  605. dlg_out->caller_cseq.len = cseq->len;
  606. memcpy(dlg_out->caller_cseq.s, cseq->s, cseq->len);
  607. }
  608. } else if (leg == DLG_CALLEE_LEG) {
  609. //update callee cseq
  610. if (dlg_out->callee_cseq.s) {
  611. if (dlg_out->callee_cseq.len < cseq->len) {
  612. shm_free(dlg_out->callee_cseq.s);
  613. dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len);
  614. if (dlg_out->callee_cseq.s == NULL)
  615. goto error;
  616. dlg_out->callee_cseq.len = cseq->len;
  617. memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len);
  618. }
  619. } else {
  620. dlg_out->callee_cseq.s = (char*) shm_malloc(cseq->len);
  621. if (dlg_out->callee_cseq.s == NULL)
  622. goto error;
  623. dlg_out->callee_cseq.len = cseq->len;
  624. memcpy(dlg_out->callee_cseq.s, cseq->s, cseq->len);
  625. }
  626. }
  627. }
  628. dlg_out = dlg_out->next;
  629. }
  630. }
  631. return 0;
  632. error:
  633. LM_ERR("not more shm mem\n");
  634. return -1;
  635. }
  636. /*!
  637. * \brief Update or set the CSEQ for an existing dialog
  638. * \param dlg dialog
  639. * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
  640. * \param cseq CSEQ of caller or callee
  641. * \return 0 on success, -1 on failure
  642. */
  643. int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *contact, str *to_tag) {
  644. LM_DBG("trying to update contact with contact [%.*s]\n", contact->len, contact->s);
  645. //Runs through the dlg_oput entries finds the one that matches the to_tag and updates the callee or caller contact accordingly
  646. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  647. struct dlg_cell_out *dlg_out;
  648. dlg_out = d_entry_out->first;
  649. if (leg == DLG_CALLER_LEG) {
  650. //update caller contact
  651. if (dlg->caller_contact.s) {
  652. if (dlg->caller_contact.len < contact->len) {
  653. shm_free(dlg->caller_contact.s);
  654. dlg->caller_contact.s = (char*) shm_malloc(contact->len);
  655. if (dlg->caller_contact.s == NULL)
  656. goto error;
  657. dlg->caller_contact.len = contact->len;
  658. memcpy(dlg->caller_contact.s, contact->s, contact->len);
  659. }
  660. } else {
  661. dlg->caller_contact.s = (char*) shm_malloc(contact->len);
  662. if (dlg->caller_contact.s == NULL)
  663. goto error;
  664. dlg->caller_contact.len = contact->len;
  665. memcpy(dlg->caller_contact.s, contact->s, contact->len);
  666. }
  667. }
  668. if (leg == DLG_CALLEE_LEG) {
  669. //update callee contact
  670. if (!to_tag) {
  671. LM_ERR("No to tag to identify dlg_out\n");
  672. return -1;
  673. }
  674. //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple)
  675. while (dlg_out) {
  676. if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) {
  677. //this parameter matches we have found the dlg_out to update the callee contact
  678. //update callee contact
  679. if (dlg_out->callee_contact.s) {
  680. if (dlg_out->callee_contact.len < contact->len) {
  681. shm_free(dlg_out->callee_contact.s);
  682. dlg_out->callee_contact.s = (char*) shm_malloc(contact->len);
  683. if (dlg_out->callee_contact.s == NULL)
  684. goto error;
  685. dlg_out->callee_contact.len = contact->len;
  686. memcpy(dlg_out->callee_contact.s, contact->s, contact->len);
  687. }
  688. } else {
  689. dlg_out->callee_contact.s = (char*) shm_malloc(contact->len);
  690. if (dlg_out->callee_contact.s == NULL)
  691. goto error;
  692. dlg_out->callee_contact.len = contact->len;
  693. memcpy(dlg_out->callee_contact.s, contact->s, contact->len);
  694. }
  695. }
  696. dlg_out = dlg_out->next;
  697. }
  698. }
  699. return 0;
  700. error:
  701. LM_ERR("not more shm mem\n");
  702. return -1;
  703. }
  704. /*!
  705. * \brief Lookup a dialog in the global list
  706. *
  707. * Note that the caller is responsible for decrementing (or reusing)
  708. * the reference counter by one again iff a dialog has been found.
  709. * \param h_entry number of the hash table entry
  710. * \param h_id id of the hash table entry
  711. * \return dialog structure on success, NULL on failure
  712. */
  713. struct dlg_cell * lookup_dlg(unsigned int h_entry, unsigned int h_id) {
  714. struct dlg_cell *dlg;
  715. struct dlg_entry *d_entry;
  716. if (h_entry >= d_table->size)
  717. goto not_found;
  718. d_entry = &(d_table->entries[h_entry]);
  719. dlg_lock(d_table, d_entry);
  720. for (dlg = d_entry->first; dlg; dlg = dlg->next) {
  721. if (dlg->h_id == h_id) {
  722. ref_dlg_unsafe(dlg, 1);
  723. dlg_unlock(d_table, d_entry);
  724. LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry);
  725. return dlg;
  726. }
  727. }
  728. dlg_unlock(d_table, d_entry);
  729. not_found:
  730. LM_DBG("no dialog id=%u found on entry %u\n", h_id, h_entry);
  731. return 0;
  732. }
  733. /*!
  734. * \brief Helper function to get a dialog corresponding to a SIP message
  735. * \see get_dlg
  736. * \param callid callid
  737. * \param ftag from tag
  738. * \param ttag to tag
  739. * \param dir direction
  740. * \return dialog structure on success, NULL on failure
  741. */
  742. static inline struct dlg_cell * internal_get_dlg(unsigned int h_entry,
  743. str *callid, str *ftag, str *ttag, unsigned int *dir) {
  744. struct dlg_cell *dlg;
  745. struct dlg_entry *d_entry;
  746. d_entry = &(d_table->entries[h_entry]);
  747. dlg_lock(d_table, d_entry);
  748. for (dlg = d_entry->first; dlg; dlg = dlg->next) {
  749. /* Check callid / fromtag / totag */
  750. if (match_dialog(dlg, callid, ftag, ttag, dir) == 1) {
  751. ref_dlg_unsafe(dlg, 1);
  752. dlg_unlock(d_table, d_entry);
  753. return dlg;
  754. }
  755. }
  756. dlg_unlock(d_table, d_entry);
  757. return 0;
  758. }
  759. /*!
  760. * \brief Get dialog that correspond to CallId, From Tag and To Tag
  761. *
  762. * Get dialog that correspond to CallId, From Tag and To Tag.
  763. * See RFC 3261, paragraph 4. Overview of Operation:
  764. * "The combination of the To tag, From tag, and Call-ID completely
  765. * defines a peer-to-peer SIP relationship between [two UAs] and is
  766. * referred to as a dialog."
  767. * Note that the caller is responsible for decrementing (or reusing)
  768. * the reference counter by one again iff a dialog has been found.
  769. * \param callid callid
  770. * \param ftag from tag
  771. * \param ttag to tag
  772. * \param dir direction
  773. * \return dialog structure on success, NULL on failure
  774. */
  775. struct dlg_cell * get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir) {
  776. struct dlg_cell *dlg;
  777. if ((dlg = internal_get_dlg(core_hash(callid, 0,
  778. d_table->size), callid, ftag, ttag, dir)) == 0 &&
  779. (dlg = internal_get_dlg(core_hash(callid, ttag->len
  780. ? ttag : 0, d_table->size), callid, ftag, ttag, dir)) == 0) {
  781. LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
  782. return 0;
  783. }
  784. return dlg;
  785. }
  786. /*!
  787. * \brief Link a dialog structure
  788. * \param dlg dialog
  789. * \param n extra increments for the reference counter
  790. */
  791. void link_dlg_out(struct dlg_cell *dlg, struct dlg_cell_out *dlg_out, int n) {
  792. LM_DBG("Start: link_dlg_out\n");
  793. lock_get(dlg->dlg_out_entries_lock);
  794. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  795. if ((d_entry_out->first == d_entry_out->last) && (d_entry_out->first == 0)) {
  796. //adding first out dialog
  797. LM_DBG("Adding first dlg_out structure\n");
  798. d_entry_out->first = dlg_out;
  799. d_entry_out->last = dlg_out;
  800. } else {
  801. LM_DBG("Adding new dlg_out structure\n");
  802. dlg_out->prev = d_entry_out->last;
  803. dlg_out->next = 0;
  804. d_entry_out->last->next = dlg_out;
  805. d_entry_out->last = dlg_out;
  806. }
  807. lock_release(dlg->dlg_out_entries_lock);
  808. LM_DBG("Done: link_dlg_out\n");
  809. return;
  810. }
  811. /*!
  812. * \brief Link a dialog structure
  813. * \param dlg dialog
  814. * \param n extra increments for the reference counter
  815. */
  816. void link_dlg(struct dlg_cell *dlg, int n) {
  817. struct dlg_entry *d_entry;
  818. LM_DBG("Linking new dialog with h_entry: %u", dlg->h_entry);
  819. d_entry = &(d_table->entries[dlg->h_entry]);
  820. dlg_lock(d_table, d_entry);
  821. dlg->h_id = d_entry->next_id++;
  822. if (d_entry->first == 0) {
  823. d_entry->first = d_entry->last = dlg;
  824. } else {
  825. d_entry->last->next = dlg;
  826. dlg->prev = d_entry->last;
  827. d_entry->last = dlg;
  828. }
  829. ref_dlg_unsafe(dlg, 1 + n);
  830. dlg_unlock(d_table, d_entry);
  831. return;
  832. }
  833. /*!
  834. * \brief Refefence a dialog with locking
  835. * \see ref_dlg_unsafe
  836. * \param dlg dialog
  837. * \param cnt increment for the reference counter
  838. */
  839. void ref_dlg(struct dlg_cell *dlg, unsigned int cnt) {
  840. struct dlg_entry *d_entry;
  841. d_entry = &(d_table->entries[dlg->h_entry]);
  842. dlg_lock(d_table, d_entry);
  843. ref_dlg_unsafe(dlg, cnt);
  844. dlg_unlock(d_table, d_entry);
  845. }
  846. /*!
  847. * \brief Unreference a dialog with locking
  848. * \see unref_dlg_unsafe
  849. * \param dlg dialog
  850. * \param cnt decrement for the reference counter
  851. */
  852. void unref_dlg(struct dlg_cell *dlg, unsigned int cnt) {
  853. struct dlg_entry *d_entry;
  854. d_entry = &(d_table->entries[dlg->h_entry]);
  855. dlg_lock(d_table, d_entry);
  856. unref_dlg_unsafe(dlg, cnt, d_entry);
  857. dlg_unlock(d_table, d_entry);
  858. }
  859. /*!
  860. * Small logging helper functions for next_state_dlg.
  861. * \param event logged event
  862. * \param dlg dialog data
  863. * \see next_state_dlg
  864. */
  865. static inline void log_next_state_dlg(const int event, const struct dlg_cell * dlg) {
  866. LM_CRIT("bogus event %d in state %d for dlg %p [%u:%u] with clid '%.*s' and tags "
  867. "'%.*s'\n", event, dlg->state, dlg, dlg->h_entry, dlg->h_id,
  868. dlg->callid.len, dlg->callid.s,
  869. dlg->from_tag.len, dlg->from_tag.s);
  870. }
  871. /*!
  872. * \brief Update a dialog state according a event and the old state
  873. *
  874. * This functions implement the main state machine that update a dialog
  875. * state according a processed event and the current state. If necessary
  876. * it will delete the processed dialog. The old and new state are also
  877. * saved for reference.
  878. * \param dlg updated dialog
  879. * \param event current event
  880. * \param old_state old dialog state
  881. * \param new_state new dialog state
  882. * \param unref set to 1 when the dialog was deleted, 0 otherwise
  883. */
  884. void next_state_dlg(struct dlg_cell *dlg, int event,
  885. int *old_state, int *new_state, int *unref, str * to_tag) {
  886. struct dlg_entry *d_entry;
  887. d_entry = &(d_table->entries[dlg->h_entry]);
  888. *unref = 0;
  889. dlg_lock(d_table, d_entry);
  890. *old_state = dlg->state;
  891. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  892. struct dlg_cell_out *dlg_out;
  893. dlg_out = d_entry_out->first;
  894. int found = -1;
  895. switch (event) {
  896. case DLG_EVENT_TDEL:
  897. switch (dlg->state) {
  898. case DLG_STATE_UNCONFIRMED:
  899. case DLG_STATE_EARLY:
  900. dlg->state = DLG_STATE_DELETED;
  901. unref_dlg_unsafe(dlg, 1, d_entry);
  902. *unref = 1;
  903. break;
  904. case DLG_STATE_CONFIRMED:
  905. unref_dlg_unsafe(dlg, 1, d_entry);
  906. break;
  907. case DLG_STATE_DELETED:
  908. *unref = 1;
  909. break;
  910. default:
  911. log_next_state_dlg(event, dlg);
  912. }
  913. break;
  914. case DLG_EVENT_RPL1xx:
  915. switch (dlg->state) {
  916. case DLG_STATE_UNCONFIRMED:
  917. case DLG_STATE_EARLY:
  918. dlg->state = DLG_STATE_EARLY;
  919. break;
  920. default:
  921. log_next_state_dlg(event, dlg);
  922. }
  923. break;
  924. case DLG_EVENT_RPL3xx:
  925. switch (dlg->state) {
  926. case DLG_STATE_UNCONFIRMED:
  927. case DLG_STATE_EARLY:
  928. dlg->state = DLG_STATE_DELETED;
  929. *unref = 1;
  930. break;
  931. default:
  932. log_next_state_dlg(event, dlg);
  933. }
  934. break;
  935. case DLG_EVENT_RPL2xx:
  936. switch (dlg->state) {
  937. case DLG_STATE_DELETED:
  938. if (dlg->dflags & DLG_FLAG_HASBYE) {
  939. LM_CRIT("bogus event %d in state %d (with BYE) "
  940. "for dlg %p [%u:%u] with clid '%.*s' and tags '%.*s' \n",
  941. event, dlg->state, dlg, dlg->h_entry, dlg->h_id,
  942. dlg->callid.len, dlg->callid.s,
  943. dlg->from_tag.len, dlg->from_tag.s);
  944. break;
  945. }
  946. ref_dlg_unsafe(dlg, 1);
  947. case DLG_STATE_UNCONFIRMED:
  948. case DLG_STATE_EARLY:
  949. dlg->state = DLG_STATE_CONFIRMED;
  950. //TODO: check that the callbacks for confirmed are run
  951. break;
  952. case DLG_STATE_CONFIRMED:
  953. //check the to_tag passed parameter exists
  954. if (to_tag) {
  955. //compare the to_tag passed parameter to the dlg_out to_tag entry of the dlg parameter (There should be only 1 dlg_out entry)
  956. if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) {
  957. //this parameter matches the existing dlg_out and is therefore a retransmission, so break
  958. break;
  959. } else {
  960. LM_ERR("It looks like this is a concurrently confirmed call!!\n");
  961. LM_ERR("Error checking now so not putting into DLG_STATE_CONCURRENTLY_CONFIRMED\n");
  962. LM_ERR("This is event DLG_EVENT_RPL2XX and the current dlg state is DLG_STATE_CONFIRMED\n");
  963. LM_ERR("There should only be one dlg out here as the state is CONFIRMED but we are checking anyway!\n");
  964. LM_ERR("To tag passed in the 2XX: [%.*s]", to_tag->len, to_tag->s);
  965. LM_ERR("Now printing dlgouts totags - there should be only one!\n");
  966. while (dlg_out) {
  967. LM_ERR("dlg_out to_tag: [%.*s]\n", dlg_out->to_tag.len, dlg_out->to_tag.s);
  968. dlg_out = dlg_out->next;
  969. }
  970. //The parameter does not match so this is a concurrently confirmed call
  971. //dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED;
  972. }
  973. } else {
  974. //to_tag parameter does not exist so break
  975. break;
  976. }
  977. case DLG_STATE_CONCURRENTLY_CONFIRMED:
  978. //check the to_tag passed parameter exists
  979. if (to_tag) {
  980. //compare the to_tag passed parameter to all the dlg_out to_tag entry of the dlg parameter (There could be multiple)
  981. while (dlg_out) {
  982. if (dlg_out->to_tag.len == to_tag->len && memcmp(dlg_out->to_tag.s, to_tag->s, dlg_out->to_tag.len) == 0) {
  983. //this parameter matches the existing dlg_out and is therefore a retransmission
  984. found = 1;
  985. }
  986. dlg_out = dlg_out->next;
  987. }
  988. if (found == -1) {
  989. //The parameter does not match so this is another concurrently confirmed call (we would have breaked by now if it matched)
  990. dlg->state = DLG_STATE_CONCURRENTLY_CONFIRMED;
  991. }
  992. } else {
  993. //to_tag parameter does not exist so break
  994. break;
  995. }
  996. break;
  997. default:
  998. log_next_state_dlg(event, dlg);
  999. }
  1000. break;
  1001. case DLG_EVENT_REQACK:
  1002. switch (dlg->state) {
  1003. case DLG_STATE_CONFIRMED:
  1004. break;
  1005. case DLG_STATE_DELETED:
  1006. break;
  1007. default:
  1008. log_next_state_dlg(event, dlg);
  1009. }
  1010. break;
  1011. case DLG_EVENT_REQBYE:
  1012. switch (dlg->state) {
  1013. case DLG_STATE_CONFIRMED:
  1014. dlg->dflags |= DLG_FLAG_HASBYE;
  1015. dlg->state = DLG_STATE_DELETED;
  1016. *unref = 1;
  1017. break;
  1018. case DLG_STATE_EARLY:
  1019. case DLG_STATE_DELETED:
  1020. break;
  1021. default:
  1022. log_next_state_dlg(event, dlg);
  1023. }
  1024. break;
  1025. case DLG_EVENT_REQPRACK:
  1026. switch (dlg->state) {
  1027. case DLG_STATE_EARLY:
  1028. //Richard added this - think it is necessary as can received PRACK in early state!
  1029. break;
  1030. default:
  1031. log_next_state_dlg(event, dlg);
  1032. }
  1033. break;
  1034. case DLG_EVENT_REQ:
  1035. switch (dlg->state) {
  1036. case DLG_STATE_EARLY:
  1037. case DLG_STATE_CONFIRMED:
  1038. break;
  1039. default:
  1040. log_next_state_dlg(event, dlg);
  1041. }
  1042. break;
  1043. default:
  1044. LM_CRIT("unknown event %d in state %d "
  1045. "for dlg %p [%u:%u] with clid '%.*s' and tags '%.*s'\n",
  1046. event, dlg->state, dlg, dlg->h_entry, dlg->h_id,
  1047. dlg->callid.len, dlg->callid.s,
  1048. dlg->from_tag.len, dlg->from_tag.s);
  1049. }
  1050. *new_state = dlg->state;
  1051. dlg_unlock(d_table, d_entry);
  1052. LM_DBG("dialog %p changed from state %d to "
  1053. "state %d, due event %d\n", dlg, *old_state, *new_state, event);
  1054. }
  1055. /**
  1056. *
  1057. */
  1058. int dlg_set_toroute(struct dlg_cell *dlg, str * route) {
  1059. if (dlg == NULL || route == NULL || route->len <= 0)
  1060. return 0;
  1061. if (dlg->toroute_name.s != NULL) {
  1062. shm_free(dlg->toroute_name.s);
  1063. dlg->toroute_name.s = NULL;
  1064. dlg->toroute_name.len = 0;
  1065. }
  1066. dlg->toroute_name.s = (char*) shm_malloc((route->len + 1) * sizeof (char));
  1067. if (dlg->toroute_name.s == NULL) {
  1068. LM_ERR("no more shared memory\n");
  1069. return -1;
  1070. }
  1071. memcpy(dlg->toroute_name.s, route->s, route->len);
  1072. dlg->toroute_name.len = route->len;
  1073. dlg->toroute_name.s[dlg->toroute_name.len] = '\0';
  1074. dlg->toroute = route_lookup(&main_rt, dlg->toroute_name.s);
  1075. return 0;
  1076. }
  1077. /*!
  1078. * \brief Takes the did of the dialog and appends an "x" to it to make a different did for concurrent calls
  1079. * \param dlg_cell - dlg_cell whose did we use
  1080. * \param new_did - empty container for new_did
  1081. * \return void
  1082. */
  1083. void create_concurrent_did(struct dlg_cell *dlg, str * new_did) {
  1084. int len = dlg->did.len + 1 + 1;
  1085. new_did->s = shm_malloc(len);
  1086. if (new_did->s == 0) {
  1087. LM_ERR("no more shm mem (%d)\n", len);
  1088. return;
  1089. }
  1090. memset(new_did->s, 0, len);
  1091. memcpy(new_did->s, dlg->did.s, dlg->did.len);
  1092. new_did->s[dlg->did.len] = 'x';
  1093. new_did->len = dlg->did.len + 1;
  1094. }
  1095. /*!
  1096. * \brief Update the did of the dlg_out structure
  1097. * \param dlg_cell_out - structure to update
  1098. * \param new_did - new did to use
  1099. * \return 1 success, 0 failure
  1100. */
  1101. int update_dlg_out_did(struct dlg_cell_out *dlg_out, str * new_did) {
  1102. //update the did of the dlg_out
  1103. if (dlg_out->did.s) {
  1104. if (dlg_out->did.len < new_did->len) {
  1105. shm_free(dlg_out->did.s);
  1106. dlg_out->did.s = (char*) shm_malloc(new_did->len);
  1107. if (dlg_out->did.s == NULL)
  1108. goto error;
  1109. }
  1110. } else {
  1111. dlg_out->did.s = (char*) shm_malloc(new_did->len);
  1112. if (dlg_out->did.s == NULL)
  1113. goto error;
  1114. }
  1115. memcpy(dlg_out->did.s, new_did->s, new_did->len);
  1116. dlg_out->did.len = new_did->len;
  1117. return 0;
  1118. error:
  1119. LM_ERR("not more shm mem\n");
  1120. return -1;
  1121. }
  1122. /*!
  1123. * \brief Update the did of the dlg structure
  1124. * \param dlg_cell - structure to update
  1125. * \param new_did - new did to use
  1126. * \return 1 success, 0 failure
  1127. */
  1128. int update_dlg_did(struct dlg_cell *dlg, str * new_did) {
  1129. //update the did of the dlg_out
  1130. if (dlg->did.s) {
  1131. if (dlg->did.len < new_did->len) {
  1132. shm_free(dlg->did.s);
  1133. dlg->did.s = (char*) shm_malloc(new_did->len);
  1134. if (dlg->did.s == NULL)
  1135. goto error;
  1136. }
  1137. } else {
  1138. dlg->did.s = (char*) shm_malloc(new_did->len);
  1139. if (dlg->did.s == NULL)
  1140. goto error;
  1141. }
  1142. memcpy(dlg->did.s, new_did->s, new_did->len);
  1143. dlg->did.len = new_did->len;
  1144. return 0;
  1145. error:
  1146. LM_ERR("not more shm mem\n");
  1147. return -1;
  1148. }
  1149. /**************************** MI functions ******************************/
  1150. /*!
  1151. * \brief Helper method that output a dialog via the MI interface
  1152. * \see mi_print_dlg
  1153. * \param rpl MI node that should be filled
  1154. * \param dlg printed dialog
  1155. * \param with_context if 1 then the dialog context will be also printed
  1156. * \return 0 on success, -1 on failure
  1157. */
  1158. static inline int internal_mi_print_dlg_out(struct mi_node *rpl,
  1159. struct dlg_cell_out * dlg_out) {
  1160. struct mi_node* node = NULL;
  1161. struct mi_node* node1 = NULL;
  1162. struct mi_attr* attr = NULL;
  1163. node = add_mi_node_child(rpl, 0, "dialog_out", 10, 0, 0);
  1164. if (node == 0)
  1165. goto error;
  1166. attr = addf_mi_attr(node, 0, "hash", 4, "%u:%u",
  1167. dlg_out->h_entry, dlg_out->h_id);
  1168. if (attr == 0)
  1169. goto error;
  1170. node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_tag", 6,
  1171. dlg_out->to_tag.s, dlg_out->to_tag.len);
  1172. if (node1 == 0)
  1173. goto error;
  1174. node1 = add_mi_node_child(node, MI_DUP_VALUE, "did", 3,
  1175. dlg_out->did.s, dlg_out->did.len);
  1176. if (node1 == 0)
  1177. goto error;
  1178. node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_contact", 14,
  1179. dlg_out->callee_contact.s,
  1180. dlg_out->callee_contact.len);
  1181. if (node1 == 0)
  1182. goto error;
  1183. node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_cseq", 11,
  1184. dlg_out->caller_cseq.s,
  1185. dlg_out->caller_cseq.len);
  1186. if (node1 == 0)
  1187. goto error;
  1188. node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_cseq", 11,
  1189. dlg_out->callee_cseq.s,
  1190. dlg_out->callee_cseq.len);
  1191. if (node1 == 0)
  1192. goto error;
  1193. node1 = add_mi_node_child(node, MI_DUP_VALUE, "callee_route_set", 16,
  1194. dlg_out->callee_route_set.s,
  1195. dlg_out->callee_route_set.len);
  1196. if (node1 == 0)
  1197. goto error;
  1198. if (dlg_out->callee_bind_addr) {
  1199. node1 = add_mi_node_child(node, 0,
  1200. "callee_bind_addr", 16,
  1201. dlg_out->callee_bind_addr->sock_str.s,
  1202. dlg_out->callee_bind_addr->sock_str.len);
  1203. } else {
  1204. node1 = add_mi_node_child(node, 0,
  1205. "callee_bind_addr", 16, 0, 0);
  1206. }
  1207. return 0;
  1208. error:
  1209. LM_ERR("failed to add node\n");
  1210. return -1;
  1211. }
  1212. /*!
  1213. * \brief Helper method that output a dialog via the MI interface
  1214. * \see mi_print_dlg
  1215. * \param rpl MI node that should be filled
  1216. * \param dlg printed dialog
  1217. * \param with_context if 1 then the dialog context will be also printed
  1218. * \return 0 on success, -1 on failure
  1219. */
  1220. static inline int internal_mi_print_dlg(struct mi_node *rpl,
  1221. struct dlg_cell *dlg, int with_context) {
  1222. struct mi_node* node = NULL;
  1223. struct mi_node* node1 = NULL;
  1224. struct mi_attr* attr = NULL;
  1225. int len;
  1226. char* p;
  1227. node = add_mi_node_child(rpl, 0, "dialog", 6, 0, 0);
  1228. if (node == 0)
  1229. goto error;
  1230. attr = addf_mi_attr(node, 0, "hash", 4, "%u:%u",
  1231. dlg->h_entry, dlg->h_id);
  1232. if (attr == 0)
  1233. goto error;
  1234. p = int2str((unsigned long) dlg->state, &len);
  1235. node1 = add_mi_node_child(node, MI_DUP_VALUE, "state", 5, p, len);
  1236. if (node1 == 0)
  1237. goto error;
  1238. p = int2str((unsigned long) dlg->ref, &len);
  1239. node1 = add_mi_node_child(node, MI_DUP_VALUE, "ref_count", 9, p, len);
  1240. if (node1 == 0)
  1241. goto error;
  1242. p = int2str((unsigned long) dlg->start_ts, &len);
  1243. node1 = add_mi_node_child(node, MI_DUP_VALUE, "timestart", 9, p, len);
  1244. if (node1 == 0)
  1245. goto error;
  1246. p = int2str((unsigned long) dlg->tl.timeout, &len);
  1247. node1 = add_mi_node_child(node, MI_DUP_VALUE, "timeout", 7, p, len);
  1248. if (node1 == 0)
  1249. goto error;
  1250. node1 = add_mi_node_child(node, MI_DUP_VALUE, "callid", 6,
  1251. dlg->callid.s, dlg->callid.len);
  1252. if (node1 == 0)
  1253. goto error;
  1254. node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_uri", 8,
  1255. dlg->from_uri.s, dlg->from_uri.len);
  1256. if (node1 == 0)
  1257. goto error;
  1258. node1 = add_mi_node_child(node, MI_DUP_VALUE, "from_tag", 8,
  1259. dlg->from_tag.s, dlg->from_tag.len);
  1260. if (node1 == 0)
  1261. goto error;
  1262. node1 = add_mi_node_child(node, MI_DUP_VALUE, "did", 3,
  1263. dlg->did.s, dlg->did.len);
  1264. if (node1 == 0)
  1265. goto error;
  1266. node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_contact", 14,
  1267. dlg->caller_contact.s,
  1268. dlg->caller_contact.len);
  1269. if (node1 == 0)
  1270. goto error;
  1271. node1 = add_mi_node_child(node, MI_DUP_VALUE, "first_req_cseq", 14,
  1272. dlg->first_req_cseq.s,
  1273. dlg->first_req_cseq.len);
  1274. if (node1 == 0)
  1275. goto error;
  1276. node1 = add_mi_node_child(node, MI_DUP_VALUE, "caller_route_set", 16,
  1277. dlg->caller_route_set.s,
  1278. dlg->caller_route_set.len);
  1279. if (node1 == 0)
  1280. goto error;
  1281. if (dlg->caller_bind_addr) {
  1282. node1 = add_mi_node_child(node, 0,
  1283. "caller_bind_addr", 16,
  1284. dlg->caller_bind_addr->sock_str.s,
  1285. dlg->caller_bind_addr->sock_str.len);
  1286. } else {
  1287. node1 = add_mi_node_child(node, 0,
  1288. "caller_bind_addr", 16, 0, 0);
  1289. }
  1290. if (with_context) {
  1291. node1 = add_mi_node_child(node, 0, "context", 7, 0, 0);
  1292. if (node1 == 0)
  1293. goto error;
  1294. run_dlg_callbacks(DLGCB_MI_CONTEXT,
  1295. dlg,
  1296. NULL,
  1297. NULL,
  1298. DLG_DIR_NONE,
  1299. (void *) node1);
  1300. }
  1301. struct dlg_cell_out *dlg_out;
  1302. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  1303. dlg_out = d_entry_out->first;
  1304. while (dlg_out) {
  1305. if (internal_mi_print_dlg_out(rpl, dlg_out) != 0)
  1306. goto error;
  1307. dlg_out = dlg_out->next;
  1308. }
  1309. return 0;
  1310. error:
  1311. LM_ERR("failed to add node\n");
  1312. return -1;
  1313. }
  1314. /*!
  1315. * \brief Output a dialog via the MI interface
  1316. * \param rpl MI node that should be filled
  1317. * \param dlg printed dialog
  1318. * \param with_context if 1 then the dialog context will be also printed
  1319. * \return 0 on success, -1 on failure
  1320. */
  1321. int mi_print_dlg(struct mi_node *rpl, struct dlg_cell *dlg, int with_context) {
  1322. return internal_mi_print_dlg(rpl, dlg, with_context);
  1323. }
  1324. /*!
  1325. * \brief Helper function that output all dialogs via the MI interface
  1326. * \see mi_print_dlgs
  1327. * \param rpl MI node that should be filled
  1328. * \param with_context if 1 then the dialog context will be also printed
  1329. * \return 0 on success, -1 on failure
  1330. */
  1331. static int internal_mi_print_dlgs(struct mi_node *rpl, int with_context) {
  1332. struct dlg_cell *dlg;
  1333. unsigned int i;
  1334. LM_DBG("printing %i dialogs\n", d_table->size);
  1335. for (i = 0; i < d_table->size; i++) {
  1336. dlg_lock(d_table, &(d_table->entries[i]));
  1337. for (dlg = d_table->entries[i].first; dlg; dlg = dlg->next) {
  1338. if (internal_mi_print_dlg(rpl, dlg, with_context) != 0)
  1339. goto error;
  1340. }
  1341. dlg_unlock(d_table, &(d_table->entries[i]));
  1342. }
  1343. return 0;
  1344. error:
  1345. dlg_unlock(d_table, &(d_table->entries[i]));
  1346. LM_ERR("failed to print dialog\n");
  1347. return -1;
  1348. }
  1349. static inline struct mi_root * process_mi_params(struct mi_root *cmd_tree, struct dlg_cell **dlg_p) {
  1350. struct mi_node* node;
  1351. struct dlg_entry *d_entry;
  1352. struct dlg_cell *dlg;
  1353. str *callid;
  1354. str *from_tag;
  1355. unsigned int h_entry;
  1356. node = cmd_tree->node.kids;
  1357. if (node == NULL) {
  1358. /* no parameters at all */
  1359. *dlg_p = NULL;
  1360. return NULL;
  1361. }
  1362. /* we have params -> get callid and fromtag */
  1363. callid = &node->value;
  1364. LM_DBG("callid='%.*s'\n", callid->len, callid->s);
  1365. node = node->next;
  1366. if (!node || !node->value.s || !node->value.len) {
  1367. from_tag = NULL;
  1368. } else {
  1369. from_tag = &node->value;
  1370. LM_DBG("from_tag='%.*s'\n", from_tag->len, from_tag->s);
  1371. if (node->next != NULL)
  1372. return init_mi_tree(400, MI_SSTR(MI_MISSING_PARM));
  1373. }
  1374. h_entry = core_hash(callid, 0, d_table->size);
  1375. d_entry = &(d_table->entries[h_entry]);
  1376. dlg_lock(d_table, d_entry);
  1377. for (dlg = d_entry->first; dlg; dlg = dlg->next) {
  1378. if (match_downstream_dialog(dlg, callid, from_tag) == 1) {
  1379. if (dlg->state == DLG_STATE_DELETED) {
  1380. *dlg_p = NULL;
  1381. break;
  1382. } else {
  1383. *dlg_p = dlg;
  1384. dlg_unlock(d_table, d_entry);
  1385. return 0;
  1386. }
  1387. }
  1388. }
  1389. dlg_unlock(d_table, d_entry);
  1390. return init_mi_tree(404, MI_SSTR("Nu such dialog"));
  1391. }
  1392. /*!
  1393. * \brief Output all dialogs via the MI interface
  1394. * \param cmd_tree MI command tree
  1395. * \param param unused
  1396. * \return mi node with the dialog information, or NULL on failure
  1397. */
  1398. struct mi_root * mi_print_dlgs(struct mi_root *cmd_tree, void *param) {
  1399. struct mi_root* rpl_tree = NULL;
  1400. struct mi_node* rpl = NULL;
  1401. struct dlg_cell* dlg = NULL;
  1402. rpl_tree = process_mi_params(cmd_tree, &dlg);
  1403. if (rpl_tree)
  1404. //param error
  1405. return rpl_tree;
  1406. rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK));
  1407. if (rpl_tree == 0)
  1408. return 0;
  1409. rpl = &rpl_tree->node;
  1410. if (dlg == NULL) {
  1411. if (internal_mi_print_dlgs(rpl, 0) != 0)
  1412. goto error;
  1413. } else {
  1414. if (internal_mi_print_dlg(rpl, dlg, 0) != 0)
  1415. goto error;
  1416. }
  1417. return rpl_tree;
  1418. error:
  1419. free_mi_tree(rpl_tree);
  1420. return NULL;
  1421. }
  1422. /*!
  1423. * \brief Print a dialog context via the MI interface
  1424. * \param cmd_tree MI command tree
  1425. * \param param unused
  1426. * \return mi node with the dialog information, or NULL on failure
  1427. */
  1428. struct mi_root * mi_print_dlgs_ctx(struct mi_root *cmd_tree, void *param) {
  1429. struct mi_root* rpl_tree = NULL;
  1430. struct mi_node* rpl = NULL;
  1431. struct dlg_cell* dlg = NULL;
  1432. rpl_tree = process_mi_params(cmd_tree, &dlg);
  1433. if (rpl_tree)
  1434. /* param error */
  1435. return rpl_tree;
  1436. rpl_tree = init_mi_tree(200, MI_SSTR(MI_OK));
  1437. if (rpl_tree == 0)
  1438. return 0;
  1439. rpl = &rpl_tree->node;
  1440. if (dlg == NULL) {
  1441. if (internal_mi_print_dlgs(rpl, 1) != 0)
  1442. goto error;
  1443. } else {
  1444. if (internal_mi_print_dlg(rpl, dlg, 1) != 0)
  1445. goto error;
  1446. }
  1447. return rpl_tree;
  1448. error:
  1449. free_mi_tree(rpl_tree);
  1450. return NULL;
  1451. }
  1452. time_t api_get_dlg_expires(str *callid, str *ftag, str *ttag) {
  1453. struct dlg_cell *dlg;
  1454. time_t expires = 0;
  1455. time_t start;
  1456. if (!callid || !ftag || !ttag) {
  1457. LM_ERR("Missing callid, from tag or to tag\n");
  1458. return 0;
  1459. }
  1460. unsigned int direction = DLG_DIR_NONE;
  1461. dlg = get_dlg(callid, ftag, ttag, &direction);
  1462. if (!dlg) return 0;
  1463. if (dlg->state != DLG_STATE_CONFIRMED || !dlg->start_ts) {
  1464. /* Dialog not started yet so lets assume start time is now.*/
  1465. start = time(0);
  1466. } else {
  1467. start = dlg->start_ts;
  1468. }
  1469. expires = start + dlg->lifetime;
  1470. unref_dlg(dlg, 1);
  1471. return expires;
  1472. }
  1473. char* state_to_char(unsigned int state) {
  1474. switch (state) {
  1475. case DLG_STATE_UNCONFIRMED:
  1476. return "Unconfirmed";
  1477. case DLG_STATE_EARLY:
  1478. return "Early";
  1479. case DLG_STATE_CONFIRMED:
  1480. return "Confirmed";
  1481. case DLG_STATE_DELETED:
  1482. return "Deleted";
  1483. default:
  1484. return "Unknown";
  1485. }
  1486. }