dlg_handlers.c 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477
  1. /*!
  2. * \file
  3. * \brief Functions related to dialog handling
  4. * \ingroup dialog
  5. * Module: \ref dialog
  6. */
  7. #include <string.h>
  8. #include <time.h>
  9. #include "../../trim.h"
  10. #include "../../pvar.h"
  11. #include "../../timer.h"
  12. #include "../../lib/kcore/statistics.h"
  13. #include "../../action.h"
  14. #include "../../script_cb.h"
  15. #include "../../lib/kcore/faked_msg.h"
  16. #include "../../parser/parse_from.h"
  17. #include "../../parser/parse_cseq.h"
  18. #include "../../parser/contact/parse_contact.h"
  19. #include "../../parser/parse_from.h"
  20. #include "../../parser/parse_rr.h"
  21. #include "../../modules/tm/tm_load.h"
  22. #include "../../modules/rr/api.h"
  23. #include "dlg_hash.h"
  24. #include "dlg_timer.h"
  25. #include "dlg_cb.h"
  26. #include "dlg_handlers.h"
  27. #include "dlg_req_within.h"
  28. #include "dlg_profile.h"
  29. #include "dlg_var.h"
  30. #include "dlg_db_handler.h"
  31. static str rr_param; /*!< record-route parameter for matching */
  32. static int dlg_flag; /*!< flag for dialog tracking */
  33. static pv_spec_t *timeout_avp; /*!< AVP for timeout setting */
  34. static int default_timeout; /*!< default dialog timeout */
  35. static int seq_match_mode; /*!< dlg_match mode */
  36. static int shutdown_done = 0; /*!< 1 when destroy_dlg_handlers was called */
  37. extern int detect_spirals;
  38. extern int initial_cbs_inscript;
  39. int spiral_detected = -1;
  40. extern struct rr_binds d_rrb; /*!< binding to record-routing module */
  41. extern struct tm_binds d_tmb;
  42. /* statistic variables */
  43. extern stat_var *early_dlgs; /*!< number of early dialogs */
  44. extern stat_var *processed_dlgs; /*!< number of processed dialogs */
  45. extern stat_var *expired_dlgs; /*!< number of expired dialogs */
  46. extern stat_var *failed_dlgs; /*!< number of failed dialogs */
  47. extern pv_elem_t *ruri_param_model; /*!< pv-string to get r-uri */
  48. static unsigned int CURR_DLG_LIFETIME = 0; /*!< current dialog lifetime */
  49. static unsigned int CURR_DLG_STATUS = 0; /*!< current dialog state */
  50. static unsigned int CURR_DLG_ID = 0xffffffff; /*!< current dialog id */
  51. /*! size of the dialog record-route parameter */
  52. #define RR_DLG_PARAM_SIZE (2*2*sizeof(int)+3+MAX_DLG_RR_PARAM_NAME)
  53. /*! separator inside the record-route paramter */
  54. #define DLG_SEPARATOR '.'
  55. /*!
  56. * \brief Initialize the dialog handlers
  57. * \param rr_param_p added record-route parameter
  58. * \param dlg_flag_p dialog flag
  59. * \param timeout_avp_p AVP for timeout setting
  60. * \param default_timeout_p default timeout
  61. * \param seq_match_mode_p matching mode
  62. */
  63. void init_dlg_handlers(char *rr_param_p, int dlg_flag_p, pv_spec_t *timeout_avp_p, int default_timeout_p, int seq_match_mode_p) {
  64. rr_param.s = rr_param_p;
  65. rr_param.len = strlen(rr_param.s);
  66. dlg_flag = 1 << dlg_flag_p;
  67. timeout_avp = timeout_avp_p;
  68. default_timeout = default_timeout_p;
  69. seq_match_mode = seq_match_mode_p;
  70. }
  71. /*!
  72. * \brief Shutdown operation of the module
  73. */
  74. void destroy_dlg_handlers(void) {
  75. shutdown_done = 1;
  76. }
  77. /*!
  78. * \brief Add record-route parameter for dialog tracking
  79. * \param req SIP request
  80. * \param entry dialog hash entry
  81. * \param id dialog hash id
  82. * \return 0 on success, -1 on failure
  83. */
  84. static inline int add_dlg_rr_param(struct dlg_cell *dlg, struct sip_msg *req, unsigned int entry, unsigned int id) {
  85. static char buf[RR_DLG_PARAM_SIZE];
  86. str s;
  87. int n;
  88. char *p;
  89. s.s = p = buf;
  90. *(p++) = ';';
  91. memcpy(p, rr_param.s, rr_param.len);
  92. p += rr_param.len;
  93. *(p++) = '=';
  94. char *did = p;
  95. n = RR_DLG_PARAM_SIZE - (p - buf);
  96. if (int2reverse_hex(&p, &n, entry) == -1)
  97. return -1;
  98. *(p++) = DLG_SEPARATOR;
  99. n = RR_DLG_PARAM_SIZE - (p - buf);
  100. if (int2reverse_hex(&p, &n, id) == -1)
  101. return -1;
  102. s.len = p - buf;
  103. if (d_rrb.add_rr_param(req, &s) < 0) {
  104. LM_ERR("failed to add rr param\n");
  105. return -1;
  106. }
  107. //add the did into the dlg structure
  108. int did_len = p - did;
  109. if (dlg->did.s) {
  110. if (dlg->did.len < did_len) {
  111. shm_free(dlg->did.s);
  112. dlg->did.s = (char*) shm_malloc(did_len);
  113. if (dlg->did.s == NULL) {
  114. LM_ERR("failed to add did to dlg_cell struct\n");
  115. return -1;
  116. }
  117. }
  118. } else {
  119. dlg->did.s = (char*) shm_malloc(did_len);
  120. if (dlg->did.s == NULL) {
  121. LM_ERR("failed to add did to dlg_cell struct\n");
  122. return -1;
  123. }
  124. }
  125. memcpy(dlg->did.s, did, did_len);
  126. dlg->did.len = did_len;
  127. return 0;
  128. }
  129. /*!
  130. * \brief Parse SIP message and populate leg informations
  131. *
  132. * Parse SIP message and populate leg informations.
  133. * \param dlg the dialog to add cseq, contact & record_route
  134. * \param msg sip message
  135. * \param t transaction
  136. * \param leg type of the call leg
  137. * \param tag SIP To tag
  138. * \return 0 on success, -1 on failure
  139. * \note for a request: get record route in normal order, for a reply get
  140. * in reverse order, skipping the ones from the request and the proxies' own
  141. */
  142. int populate_leg_info(struct dlg_cell *dlg, struct sip_msg *msg,
  143. struct cell* t, unsigned int leg, str *tag) {
  144. unsigned int skip_recs;
  145. str cseq;
  146. str contact;
  147. str rr_set;
  148. struct socket_info* callee_bind_address = NULL;
  149. if (leg == DLG_CALLER_LEG)
  150. dlg->caller_bind_addr = msg->rcv.bind_address;
  151. else
  152. callee_bind_address = msg->rcv.bind_address;
  153. /* extract the cseq number as string from the request or response*/
  154. //TO DO - can pair the cseqs here to make sure that the response and request are in sync
  155. if ((!msg->cseq && (parse_headers(msg, HDR_CSEQ_F, 0) < 0 || !msg->cseq))
  156. || !msg->cseq->parsed) {
  157. LM_ERR("bad sip message or missing CSeq hdr :-/\n");
  158. goto error0;
  159. }
  160. cseq = (get_cseq(msg))->number;
  161. /* extract the contact address */
  162. if (!msg->contact && (parse_headers(msg, HDR_CONTACT_F, 0) < 0 || !msg->contact)) {
  163. LM_ERR("bad sip message or missing Contact hdr\n");
  164. goto error0;
  165. }
  166. if (parse_contact(msg->contact) < 0 ||
  167. ((contact_body_t *) msg->contact->parsed)->contacts == NULL ||
  168. ((contact_body_t *) msg->contact->parsed)->contacts->next != NULL) {
  169. LM_ERR("bad Contact HDR\n");
  170. goto error0;
  171. }
  172. contact = ((contact_body_t *) msg->contact->parsed)->contacts->uri;
  173. /* extract the RR parts */
  174. if (!msg->record_route && (parse_headers(msg, HDR_EOH_F, 0) < 0)) {
  175. LM_ERR("failed to parse record route header\n");
  176. goto error0;
  177. }
  178. if (leg == DLG_CALLER_LEG) {
  179. skip_recs = 0;
  180. } else {
  181. skip_recs = 0;
  182. /* was the 200 OK received or local generated */
  183. /*skip_recs = dlg->from_rr_nb +
  184. ((t->relayed_reply_branch >= 0) ?
  185. ((t->uac[t->relayed_reply_branch].flags & TM_UAC_FLAG_R2) ? 2 :
  186. ((t->uac[t->relayed_reply_branch].flags & TM_UAC_FLAG_RR) ? 1 : 0))
  187. : 0);
  188. * */
  189. }
  190. if (msg->record_route) {
  191. if (print_rr_body(msg->record_route, &rr_set, leg,
  192. &skip_recs) != 0) {
  193. LM_ERR("failed to print route records \n");
  194. goto error0;
  195. }
  196. } else {
  197. rr_set.s = 0;
  198. rr_set.len = 0;
  199. }
  200. if (leg == DLG_CALLER_LEG)
  201. dlg->from_rr_nb = skip_recs;
  202. LM_DBG("route_set %.*s, contact %.*s, cseq %.*s and bind_addr %.*s\n",
  203. rr_set.len, rr_set.s, contact.len, contact.s,
  204. cseq.len, cseq.s,
  205. msg->rcv.bind_address->sock_str.len,
  206. msg->rcv.bind_address->sock_str.s);
  207. if (dlg_set_leg_info(dlg, tag, &rr_set, &contact, &cseq, callee_bind_address, leg) != 0) {
  208. LM_ERR("dlg_set_leg_info failed\n");
  209. if (rr_set.s) pkg_free(rr_set.s);
  210. goto error0;
  211. }
  212. if (rr_set.s) pkg_free(rr_set.s);
  213. return 0;
  214. error0:
  215. return -1;
  216. }
  217. /*!
  218. * \brief Function that executes BYE reply callbacks
  219. * \param t transaction, unused
  220. * \param type type of the callback, should be TMCB_RESPONSE_FWDED
  221. * \param param saved dialog structure inside the callback
  222. */
  223. static void dlg_terminated_confirmed(struct cell* t,
  224. int type,
  225. struct tmcb_params* params) {
  226. if (!params || !params->req || !params->param) {
  227. LM_ERR("invalid parameters!\n");
  228. return;
  229. }
  230. struct dlg_cell* dlg = (struct dlg_cell*) *params->param;
  231. if (!dlg) {
  232. LM_ERR("failed to get dialog from params!\n");
  233. return;
  234. }
  235. /* dialog termination confirmed (BYE reply) */
  236. run_dlg_callbacks(DLGCB_TERMINATED_CONFIRMED,
  237. dlg,
  238. params->req,
  239. params->rpl,
  240. DLG_DIR_UPSTREAM,
  241. 0);
  242. }
  243. /*!
  244. * \brief Execute callback for the BYE request and register callback for the BYE reply
  245. * \param req request message
  246. * \param dlg corresponding dialog
  247. * \param dir message direction
  248. */
  249. static void dlg_terminated(struct sip_msg* req,
  250. struct dlg_cell* dlg,
  251. unsigned int dir) {
  252. if (!req) {
  253. LM_ERR("request is empty!");
  254. return;
  255. }
  256. if (!dlg) {
  257. LM_ERR("dialog is empty!");
  258. return;
  259. }
  260. /* dialog terminated (BYE) */
  261. run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0);
  262. /* register callback for the coresponding reply */
  263. LM_DBG("Registering tmcb1\n");
  264. if (d_tmb.register_tmcb(req,
  265. 0,
  266. TMCB_RESPONSE_OUT,
  267. dlg_terminated_confirmed,
  268. (void*) dlg,
  269. 0) <= 0) {
  270. LM_ERR("cannot register response callback for BYE request\n");
  271. return;
  272. }
  273. }
  274. static void unlink_dlgouts_from_cb(struct cell* t, int type, struct tmcb_params *param) {
  275. struct dlg_cell *dlg = (struct dlg_cell *) (*param->param);
  276. if (!dlg)
  277. return;
  278. if (t && t->fwded_totags && t->fwded_totags->tag.len > 0) {
  279. LM_DBG("unlink_dlgouts_from_cb: transaction [%.*s] can now be removed IFF it has been marked for deletion\n", t->fwded_totags->tag.len, t->fwded_totags->tag.s);
  280. dlg_remove_dlg_out_tag(dlg, &t->fwded_totags->tag);
  281. }
  282. }
  283. /*!
  284. * \brief Function that is registered as TM callback and called on replies
  285. *
  286. * Function that is registered as TM callback and called on replies. It
  287. * parses the reply and set the appropriate event. This is then used to
  288. * update the dialog state, run eventual dialog callbacks and save or
  289. * update the necessary informations about the dialog.
  290. * \see next_state_dlg
  291. * \param t transaction, unused
  292. * \param type type of the entered callback
  293. * \param param saved dialog structure in the callback
  294. */
  295. static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param) {
  296. struct dlg_cell *dlg;
  297. struct dlg_cell_out *dlg_out = 0;
  298. int new_state, old_state, unref, event;
  299. str to_tag, to_uri;
  300. struct sip_msg *req = param->req;
  301. struct sip_msg *rpl = param->rpl;
  302. struct dlg_entry_out* dlg_entry_out = 0;
  303. if (t && t->fwded_totags)
  304. LM_DBG("ONREPLY CALL_BACK from TM received and type is [%i] and TO is [%.*s]\n", type, t->fwded_totags->tag.len, t->fwded_totags->tag.s);
  305. else
  306. LM_DBG("ONREPLY CALL_BACK from TM received and type is [%i]\n", type);
  307. dlg = (struct dlg_cell *) (*param->param);
  308. if (shutdown_done || dlg == 0)
  309. return;
  310. if (t) {
  311. dlg->transaction = t;
  312. }
  313. LM_DBG("DLG dialogid is entry:id [%i:%i]\n", dlg->h_entry, dlg->h_id);
  314. if (type == TMCB_RESPONSE_FWDED) {
  315. // The state does not change, but the msg is mutable in this callback
  316. LM_DBG("TMCB_RESPONSE_FWDED from TM received");
  317. run_dlg_callbacks(DLGCB_RESPONSE_FWDED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
  318. return;
  319. }
  320. if (type == TMCB_RESPONSE_OUT) {
  321. LM_DBG("TMCB_RESPONSE_OUT\n");
  322. return;
  323. }
  324. if (type == TMCB_RESPONSE_READY) {
  325. if (rpl == FAKED_REPLY) {
  326. LM_DBG("Faked reply\n");
  327. return;
  328. }
  329. // get to tag
  330. LM_DBG("Extracting to-tag from reply");
  331. if (!rpl->to && ((parse_headers(rpl, HDR_TO_F, 0) < 0) || !rpl->to)) {
  332. LM_ERR("bad reply or missing TO hdr :-/\n");
  333. to_tag.s = 0;
  334. to_tag.len = 0;
  335. } else {
  336. //populate to uri for this branch.
  337. to_uri = get_to(rpl)->uri;
  338. to_tag = get_to(rpl)->tag_value;
  339. if (to_tag.s == 0 || to_tag.len == 0) {
  340. LM_ERR("missing TAG param in TO hdr :-/\n");
  341. to_tag.s = 0;
  342. to_tag.len = 0;
  343. //Here we assume that the transaction module timer will remove any early dialogs
  344. return;
  345. }
  346. }
  347. LM_DBG("Got to-tag from response: %.*s \n", to_tag.len, to_tag.s);
  348. }
  349. if (type == TMCB_DESTROY)
  350. event = DLG_EVENT_TDEL;
  351. else if (param->code < 200)
  352. event = DLG_EVENT_RPL1xx;
  353. else if (param->code < 300)
  354. event = DLG_EVENT_RPL2xx;
  355. else
  356. event = DLG_EVENT_RPL3xx;
  357. LM_DBG("Calling next_state_dlg and event is %i\n", event);
  358. next_state_dlg(dlg, event, &old_state, &new_state, &unref, &to_tag);
  359. if (type == TMCB_RESPONSE_READY) {
  360. LM_DBG("Checking if there is an existing dialog_out entry with same to-tag");
  361. dlg_entry_out = &dlg->dlg_entry_out;
  362. lock_get(dlg->dlg_out_entries_lock);
  363. dlg_out = dlg_entry_out->first;
  364. LM_DBG("Scanning dlg_entry_out list for dlg_out");
  365. while (dlg_out) {
  366. //Check if there is an already dialog_out entry with same To-tag
  367. if (dlg_out->to_tag.len == to_tag.len &&
  368. memcmp(dlg_out->to_tag.s, to_tag.s, dlg_out->to_tag.len) == 0) {
  369. //Found a dialog_out entry with same to_tag!
  370. LM_DBG("Found dlg_out for to-tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s);
  371. break;
  372. }
  373. dlg_out = dlg_out->next;
  374. }
  375. lock_release(dlg->dlg_out_entries_lock);
  376. if (!dlg_out) {
  377. LM_DBG("No dlg_out entry found - creating a new dialog_out entry on dialog [%p]\n", dlg);
  378. dlg_out = build_new_dlg_out(dlg, &to_uri, &to_tag);
  379. link_dlg_out(dlg, dlg_out, 0);
  380. /* save callee's cseq, caller cseq, callee contact and callee record route*/
  381. if (populate_leg_info(dlg, rpl, t, DLG_CALLEE_LEG, &to_tag) != 0) {
  382. LM_ERR("could not add further info to the dlg out\n");
  383. }
  384. if (!dlg_out) {
  385. LM_ERR("failed to create new dialog out structure\n");
  386. //TODO do something on this error!
  387. }
  388. } else {
  389. //This dlg_out already exists, update cseq and contact if present
  390. LM_DBG("dlg_out entry found - updating cseq's for dialog out [%p] for to-tag [%.*s] \n", dlg_out, dlg_out->to_tag.len, dlg_out->to_tag.s);
  391. if ((!rpl->cseq && parse_headers(rpl, HDR_CSEQ_F, 0) < 0) || !rpl->cseq ||
  392. !rpl->cseq->parsed) {
  393. LM_ERR("bad sip message or missing CSeq hdr :-/\n");
  394. }
  395. dlg_update_cseq(dlg, DLG_CALLEE_LEG, &((get_cseq(rpl))->number), &(dlg_out->to_tag));
  396. /* extract the contact address to update if present*/
  397. if (!rpl->contact && (parse_headers(rpl, HDR_CONTACT_F, 0) < 0 || !rpl->contact)) {
  398. LM_ERR("Can not update callee contact: bad sip message or missing Contact hdr\n");
  399. }
  400. else if (parse_contact(rpl->contact) < 0 ||
  401. ((contact_body_t *) rpl->contact->parsed)->contacts == NULL ||
  402. ((contact_body_t *) rpl->contact->parsed)->contacts->next != NULL) {
  403. LM_ERR("Can not update callee contact: bad Contact HDR\n");
  404. }
  405. else
  406. {
  407. str contact;
  408. contact = ((contact_body_t *) rpl->contact->parsed)->contacts->uri;
  409. dlg_update_contact(dlg, DLG_CALLEE_LEG, &contact, &(dlg_out->to_tag));
  410. }
  411. }
  412. }
  413. if (new_state == DLG_STATE_EARLY) {
  414. if ((dlg->dflags & DLG_FLAG_INSERTED) == 0) {
  415. dlg->dflags |= DLG_FLAG_NEW;
  416. } else {
  417. dlg->dflags |= DLG_FLAG_CHANGED;
  418. }
  419. if (dlg_db_mode == DB_MODE_REALTIME)
  420. update_dialog_dbinfo(dlg);
  421. run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
  422. return;
  423. }
  424. LM_DBG("new state is %i and old state is %i\n", new_state, old_state);
  425. if ((new_state == DLG_STATE_CONFIRMED) && (event == DLG_EVENT_RPL2xx)) {
  426. LM_DBG("dialog %p confirmed \n", dlg);
  427. //Remove all the other entries in dialog_out for the same dialog after TM expires the transaction
  428. //(not before in order to absorb late in-early-dialog requests).
  429. //remove all other dlg_out objects
  430. if (dlg_out) {
  431. if (d_tmb.register_tmcb(req, NULL, TMCB_DESTROY, unlink_dlgouts_from_cb, (void*) dlg, NULL) < 0) {
  432. LM_ERR("failed to register deletion delay function\n");
  433. LM_DBG("Removing all other DLGs");
  434. dlg_remove_dlg_out(dlg_out, dlg, 0);
  435. } else {
  436. //mark the outs for deletion
  437. dlg_remove_dlg_out(dlg_out, dlg, 1);
  438. }
  439. } else {
  440. LM_ERR("There is no dlg_out structure - this is bad\n");
  441. //TODO: add error handling here
  442. }
  443. /* set start time */
  444. dlg->start_ts = (unsigned int) (time(0));
  445. /* save the settings to the database,
  446. * if realtime saving mode configured- save dialog now
  447. * else: the next time the timer will fire the update*/
  448. if ((dlg->dflags & DLG_FLAG_INSERTED) == 0) {
  449. dlg->dflags |= DLG_FLAG_NEW;
  450. } else {
  451. dlg->dflags |= DLG_FLAG_CHANGED;
  452. }
  453. if (dlg_db_mode == DB_MODE_REALTIME)
  454. update_dialog_dbinfo(dlg);
  455. if (0 != insert_dlg_timer(&dlg->tl, dlg->lifetime)) {
  456. LM_CRIT("Unable to insert dlg %p [%u:%u] on event %d [%d->%d] "
  457. "with clid '%.*s' and tags '%.*s' \n",
  458. dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state,
  459. dlg->callid.len, dlg->callid.s,
  460. dlg->from_tag.len, dlg->from_tag.s);
  461. } else {
  462. ref_dlg(dlg, 1);
  463. }
  464. run_dlg_callbacks(DLGCB_CONFIRMED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
  465. if (unref) unref_dlg(dlg, unref);
  466. return;
  467. }
  468. if (new_state == DLG_STATE_CONCURRENTLY_CONFIRMED && (old_state == DLG_STATE_CONFIRMED || old_state == DLG_STATE_CONCURRENTLY_CONFIRMED)) {
  469. //This is a concurrently confirmed call
  470. LM_DBG("This is a concurrently confirmed call.");
  471. //Create a new Dialog ID token “X”
  472. //Not sure how to do this so just going to use existing Did and add an X character to it
  473. str new_did;
  474. create_concurrent_did(dlg, &new_did);
  475. //assign new did to the created or updated dialog_out entry.
  476. update_dlg_out_did(dlg_out, &new_did);
  477. //Then, duplicate the dialog_in entry and set its Dialog ID value to new_did
  478. //for now rather just create new dlg structure with the correct params - this should be fixed if future use requires
  479. struct dlg_cell *new_dlg = 0;
  480. new_dlg = build_new_dlg(&(dlg->callid) /*callid*/,
  481. &(dlg->from_uri) /*from uri*/,
  482. &(dlg->from_tag)/*from_tag*/,
  483. &(dlg->req_uri) /*r-uri*/);
  484. //assign new did to dlg_in
  485. update_dlg_did(new_dlg, &new_did);
  486. if (new_dlg == 0) {
  487. LM_ERR("failed to create new dialog\n");
  488. return;
  489. }
  490. //link the new_dlg with dlg_out object
  491. link_dlg_out(new_dlg, dlg_out, 0);
  492. }
  493. if (old_state != DLG_STATE_DELETED && new_state == DLG_STATE_DELETED) {
  494. LM_DBG("dialog %p failed (negative reply)\n", dlg);
  495. /* dialog setup not completed (3456XX) */
  496. run_dlg_callbacks(DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
  497. /* do unref */
  498. if (unref)
  499. unref_dlg(dlg, unref);
  500. return;
  501. }
  502. if (unref) unref_dlg(dlg, unref);
  503. return;
  504. }
  505. /*!
  506. * \brief Helper function that run dialog callbacks on forwarded requests
  507. * \see dlg_seq_up_onreply
  508. * \see dlg_seq_down_onreply
  509. * \param t transaction, unused
  510. * \param type type of the callback, should be TMCB_RESPONSE_FWDED
  511. * \param param saved dialog structure inside the callback
  512. * \param direction direction of the request
  513. */
  514. static void dlg_seq_onreply_helper(struct cell* t, int type,
  515. struct tmcb_params *param, const int direction) {
  516. struct dlg_cell *dlg;
  517. dlg = (struct dlg_cell *) (*param->param);
  518. if (shutdown_done || dlg == 0)
  519. return;
  520. if (type == TMCB_RESPONSE_FWDED) {
  521. run_dlg_callbacks(DLGCB_RESPONSE_WITHIN,
  522. dlg,
  523. param->req,
  524. param->rpl,
  525. direction,
  526. 0);
  527. return;
  528. }
  529. return;
  530. }
  531. /*!
  532. * \brief Run dialog callbacks on forwarded requests in upstream direction
  533. * \see dlg_seq_onreply_helper
  534. * \param t transaction, unused
  535. * \param type type of the callback, should be TMCB_RESPONSE_FWDED
  536. * \param param saved dialog structure inside the callback
  537. */
  538. static void dlg_seq_up_onreply(struct cell* t, int type, struct tmcb_params *param) {
  539. return dlg_seq_onreply_helper(t, type, param, DLG_DIR_UPSTREAM);
  540. }
  541. /*!
  542. * \brief Run dialog callbacks on forwarded requests in downstream direction
  543. * \see dlg_seq_onreply_helper
  544. * \param t transaction, unused
  545. * \param type type of the callback, should be TMCB_RESPONSE_FWDED
  546. * \param param saved dialog structure inside the callback
  547. */
  548. static void dlg_seq_down_onreply(struct cell* t, int type, struct tmcb_params *param) {
  549. return dlg_seq_onreply_helper(t, type, param, DLG_DIR_DOWNSTREAM);
  550. }
  551. /*!
  552. * \brief Return the timeout for a dialog
  553. * \param req SIP message
  554. * \return value from timeout AVP if present or default timeout
  555. */
  556. inline static int get_dlg_timeout(struct sip_msg *req) {
  557. pv_value_t pv_val;
  558. if (timeout_avp) {
  559. if (pv_get_spec_value(req, timeout_avp, &pv_val) == 0 &&
  560. pv_val.flags & PV_VAL_INT && pv_val.ri > 0) {
  561. return pv_val.ri;
  562. }
  563. LM_DBG("invalid AVP value, using default timeout\n");
  564. }
  565. return default_timeout;
  566. }
  567. /*!
  568. * \brief Helper function to get the necessary content from SIP message
  569. * \param req SIP request
  570. * \param callid found callid
  571. * \param ftag found from tag
  572. * \param ttag found to tag
  573. * \param with_ttag flag set if to tag must be found for success
  574. * \return 0 on success, -1 on failure
  575. */
  576. static inline int pre_match_parse(struct sip_msg *req, str *callid,
  577. str *ftag, str *ttag, int with_ttag) {
  578. if (parse_headers(req, HDR_CALLID_F | HDR_TO_F, 0) < 0 || !req->callid ||
  579. !req->to) {
  580. LM_ERR("bad request or missing CALLID/TO hdr :-/\n");
  581. return -1;
  582. }
  583. if (get_to(req)->tag_value.len == 0) {
  584. if (with_ttag == 1) {
  585. /* out of dialog request with preloaded Route headers; ignore. */
  586. return -1;
  587. } else {
  588. ttag->s = NULL;
  589. ttag->len = 0;
  590. }
  591. } else {
  592. *ttag = get_to(req)->tag_value;
  593. }
  594. if (parse_from_header(req) < 0 || get_from(req)->tag_value.len == 0) {
  595. LM_ERR("failed to get From header\n");
  596. return -1;
  597. }
  598. /* callid */
  599. *callid = req->callid->body;
  600. trim(callid);
  601. /* from tag */
  602. *ftag = get_from(req)->tag_value;
  603. return 0;
  604. }
  605. /*!
  606. * \brief Function that is registered as TM callback and called on requests
  607. * \see dlg_new_dialog
  608. * \param t transaction, used to created the dialog
  609. * \param type type of the entered callback
  610. * \param param saved dialog structure in the callback
  611. */
  612. void dlg_onreq(struct cell* t, int type, struct tmcb_params *param) {
  613. struct sip_msg *req = param->req;
  614. if ((req->flags & dlg_flag) != dlg_flag)
  615. return;
  616. if (current_dlg_pointer != NULL)
  617. return;
  618. dlg_new_dialog(req, t, 1);
  619. }
  620. /*!
  621. * \brief Unreference a new dialog, helper function for dlg_onreq
  622. * \see dlg_onreq
  623. * \param dialog unreferenced dialog
  624. */
  625. static void unref_new_dialog(void *dialog) {
  626. struct tmcb_params p;
  627. memset(&p, 0, sizeof (struct tmcb_params));
  628. p.param = (void*) &dialog;
  629. dlg_onreply(0, TMCB_DESTROY, &p);
  630. }
  631. /*!
  632. * \brief Unreference a dialog (small wrapper to take care of shutdown)
  633. * \see unref_dlg
  634. * \param dialog unreferenced dialog
  635. */
  636. static void unreference_dialog(void *dialog) {
  637. // if the dialog table is gone, it means the system is shutting down.
  638. if (!dialog || !d_table)
  639. return;
  640. unref_dlg((struct dlg_cell*) dialog, 1);
  641. }
  642. /*!
  643. * \brief Dummy callback just to keep the compiler happy
  644. * \param t unused
  645. * \param type unused
  646. * \param param unused
  647. */
  648. void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param) {
  649. return;
  650. }
  651. /*!
  652. * \brief Register a transaction on a dialog
  653. * \param t transaction
  654. * \param type type of the entered callback
  655. * \param param saved dialog structure in the callback
  656. */
  657. static int store_dlg_in_tm(struct sip_msg* msg,
  658. struct cell* t,
  659. struct dlg_cell *dlg) {
  660. if (!msg || msg == FAKED_REPLY || !t || !dlg) {
  661. LM_ERR("invalid parameter msg(%p), t(%p), dlg(%p)\n", msg, t, dlg);
  662. return -1;
  663. }
  664. if (get_dialog_from_tm(t)) {
  665. LM_NOTICE("dialog %p is already set for this transaction!\n", dlg);
  666. return 1;
  667. }
  668. // facilitate referencing of dialog through TMCB_MAX
  669. if (d_tmb.register_tmcb(msg,
  670. t,
  671. TMCB_MAX,
  672. dlg_tmcb_dummy,
  673. (void*) dlg, unreference_dialog) < 0) {
  674. LM_ERR("failed cache in T the shortcut to dlg %p\n", dlg);
  675. return -3;
  676. }
  677. // registering succeeded, we must increase the reference counter
  678. ref_dlg(dlg, 1);
  679. return 0;
  680. }
  681. /*!
  682. * \brief Callback to register a transaction on a dialog
  683. * \param t transaction, unused
  684. * \param type type of the entered callback
  685. * \param param saved dialog structure in the callback
  686. */
  687. static void store_dlg_in_tm_cb(struct cell* t,
  688. int type,
  689. struct tmcb_params *param) {
  690. struct dlg_cell *dlg = (struct dlg_cell *) (*param->param);
  691. struct sip_msg* msg = param->rpl;
  692. if (msg == NULL || msg == FAKED_REPLY) {
  693. msg = param->req;
  694. }
  695. store_dlg_in_tm(msg, t, dlg);
  696. }
  697. /*!
  698. * \brief Create a new dialog from a sip message
  699. *
  700. * Create a new dialog from a SIP message, register a callback
  701. * to keep track of the dialog with help of the tm module.
  702. * This function is either called from the request callback, or
  703. * from the dlg_manage function in the configuration script.
  704. * \see dlg_onreq
  705. * \see w_dlg_manage
  706. * \param msg SIP message
  707. * \param t transaction
  708. * \return 0 on success, -1 on failure
  709. */
  710. int dlg_new_dialog(struct sip_msg *req, struct cell *t, const int run_initial_cbs) {
  711. struct dlg_cell *dlg;
  712. str s;
  713. str callid;
  714. str ftag;
  715. str ttag;
  716. str req_uri;
  717. unsigned int dir;
  718. LM_DBG("starting dlg_new_dialog and method is [%.*s]\n", req->first_line.u.request.method.len, req->first_line.u.request.method.s);
  719. if (current_dlg_pointer != NULL)
  720. return -1;
  721. if (req->first_line.u.request.method_value == METHOD_CANCEL)
  722. return -1;
  723. if (pre_match_parse(req, &callid, &ftag, &ttag, 0) < 0) {
  724. LM_WARN("pre-matching failed\n");
  725. return -1;
  726. }
  727. if (ttag.s != 0 && ttag.len != 0)
  728. return -1;
  729. if (pv_printf_s(req, ruri_param_model, &req_uri) < 0) {
  730. LM_ERR("error - cannot print the r-uri format\n");
  731. return -1;
  732. }
  733. trim(&req_uri);
  734. if (detect_spirals) {
  735. if (spiral_detected == 1)
  736. return 0;
  737. dir = DLG_DIR_NONE;
  738. dlg = get_dlg(&callid, &ftag, &ttag, &dir);
  739. if (dlg) {
  740. LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
  741. callid.len, callid.s);
  742. spiral_detected = 1;
  743. if (run_initial_cbs)
  744. run_dlg_callbacks(DLGCB_SPIRALED, dlg, req, NULL, DLG_DIR_DOWNSTREAM, 0);
  745. //Add did to rr header for all spiralled requested INVITEs
  746. if (req->first_line.u.request.method_value == METHOD_INVITE) {
  747. if (add_dlg_rr_param(dlg, req, dlg->h_entry, dlg->h_id) < 0) {
  748. LM_ERR("failed to add RR param\n");
  749. }
  750. }
  751. // get_dlg has incremented the ref count by 1
  752. unref_dlg(dlg, 1);
  753. goto finish;
  754. }
  755. }
  756. spiral_detected = 0;
  757. LM_DBG("Building new Dialog for call-id %.*s\n", callid.len, callid.s);
  758. LM_DBG("SIP Method: %.*s \n", req->first_line.u.request.method.len, req->first_line.u.request.method.s);
  759. dlg = build_new_dlg(&callid /*callid*/,
  760. &(get_from(req)->uri) /*from uri*/,
  761. &ftag/*from_tag*/,
  762. &req_uri /*r-uri*/);
  763. if (dlg == 0) {
  764. LM_ERR("failed to create new dialog\n");
  765. return -1;
  766. }
  767. /* save caller's tag, cseq, contact and record route*/
  768. if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG,
  769. &(get_from(req)->tag_value)) != 0) {
  770. LM_ERR("could not add further info to the dialog\n");
  771. lock_destroy(dlg->dlg_out_entries_lock);
  772. lock_dealloc(dlg->dlg_out_entries_lock);
  773. shm_free(dlg);
  774. return -1;
  775. }
  776. dlg->transaction = t;
  777. /* Populate initial varlist: */
  778. dlg->vars = get_local_varlist_pointer(req, 1);
  779. link_dlg(dlg, 0);
  780. if (run_initial_cbs) run_create_callbacks(dlg, req);
  781. //Dialog will *always* use DID cookie so no need for match mode anymore
  782. if (add_dlg_rr_param(dlg, req, dlg->h_entry, dlg->h_id) < 0) {
  783. LM_ERR("failed to add RR param\n");
  784. goto error;
  785. }
  786. if (d_tmb.register_tmcb(req, t,
  787. TMCB_RESPONSE_READY | TMCB_RESPONSE_FWDED | TMCB_RESPONSE_OUT,
  788. dlg_onreply, (void*) dlg, unref_new_dialog) < 0) {
  789. LM_ERR("failed to register TMCB\n");
  790. goto error;
  791. }
  792. // increase reference counter because of registered callback
  793. ref_dlg(dlg, 1);
  794. dlg->lifetime = get_dlg_timeout(req);
  795. s.s = _dlg_ctx.to_route_name;
  796. s.len = strlen(s.s);
  797. dlg_set_toroute(dlg, &s);
  798. dlg->sflags |= _dlg_ctx.flags;
  799. if (_dlg_ctx.to_bye != 0)
  800. dlg->dflags |= DLG_FLAG_TOBYE;
  801. finish:
  802. if (t) {
  803. // transaction exists ==> keep ref counter large enough to
  804. // avoid premature cleanup and ensure proper dialog referencing
  805. if (store_dlg_in_tm(req, t, dlg) < 0) {
  806. LM_ERR("failed to store dialog in transaction\n");
  807. goto error;
  808. }
  809. } else {
  810. // no transaction exists ==> postpone work until we see the
  811. // request being forwarded statefully
  812. if (d_tmb.register_tmcb(req, NULL, TMCB_REQUEST_FWDED,
  813. store_dlg_in_tm_cb, (void*) dlg, NULL) < 0) {
  814. LM_ERR("failed to register callback for storing dialog in transaction\n");
  815. goto error;
  816. }
  817. }
  818. LM_DBG("Setting current dialog\n");
  819. set_current_dialog(req, dlg);
  820. _dlg_ctx.dlg = dlg;
  821. ref_dlg(dlg, 1);
  822. return 0;
  823. error:
  824. LM_DBG("Error in build_new_dlg");
  825. if (!spiral_detected)
  826. unref_dlg(dlg, 1); // undo ref regarding linking
  827. return -1;
  828. }
  829. /*!
  830. * \brief Parse the record-route parameter, to get dialog information back
  831. * \param p start of parameter string
  832. * \param end end of parameter string
  833. * \param h_entry found dialog hash entry
  834. * \param h_id found dialog hash id
  835. * \return 0 on success, -1 on failure
  836. */
  837. static inline int parse_dlg_rr_param(char *p, char *end, int *h_entry, int *h_id) {
  838. char *s;
  839. for (s = p; p < end && *p != DLG_SEPARATOR; p++);
  840. if (*p != DLG_SEPARATOR) {
  841. LM_ERR("malformed rr param '%.*s'\n", (int) (long) (end - s), s);
  842. return -1;
  843. }
  844. if (reverse_hex2int(s, p - s, (unsigned int*) h_entry) < 0) {
  845. LM_ERR("invalid hash entry '%.*s'\n", (int) (long) (p - s), s);
  846. return -1;
  847. }
  848. if (reverse_hex2int(p + 1, end - (p + 1), (unsigned int*) h_id) < 0) {
  849. LM_ERR("invalid hash id '%.*s'\n", (int) (long) (end - (p + 1)), p + 1);
  850. return -1;
  851. }
  852. return 0;
  853. }
  854. /*!
  855. * \brief Update the saved CSEQ information in dialog from SIP message
  856. * \param dlg updated dialog
  857. * \param req SIP request
  858. * \param dir direction of request, must DLG_DIR_UPSTREAM or DLG_DIR_DOWNSTREAM
  859. * \return 0 on success, -1 on failure
  860. */
  861. static inline int update_cseqs(struct dlg_cell *dlg, struct sip_msg *req,
  862. unsigned int dir, str *to_tag) {
  863. if ((!req->cseq && parse_headers(req, HDR_CSEQ_F, 0) < 0) || !req->cseq ||
  864. !req->cseq->parsed) {
  865. LM_ERR("bad sip message or missing CSeq hdr :-/\n");
  866. return -1;
  867. }
  868. if (dir == DLG_DIR_UPSTREAM) {
  869. return dlg_update_cseq(dlg, DLG_CALLEE_LEG, &((get_cseq(req))->number), to_tag);
  870. } else if (dir == DLG_DIR_DOWNSTREAM) {
  871. return dlg_update_cseq(dlg, DLG_CALLER_LEG, &((get_cseq(req))->number), to_tag);
  872. } else {
  873. LM_CRIT("dir is not set!\n");
  874. return -1;
  875. }
  876. }
  877. /*!
  878. * \brief Function that is registered as RR callback for dialog tracking
  879. *
  880. * Function that is registered as RR callback for dialog tracking. It
  881. * sets the appropriate events after the SIP method and run the state
  882. * machine to update the dialog state. It updates then the saved
  883. * dialogs and also the statistics.
  884. * \param req SIP request
  885. * \param route_params record-route parameter
  886. * \param param unused
  887. */
  888. void dlg_onroute(struct sip_msg* req, str *route_params, void *param) {
  889. struct dlg_cell *dlg;
  890. str val, callid, ftag, ttag;
  891. int h_entry, h_id, new_state, old_state, unref, event, timeout;
  892. unsigned int dir;
  893. int ret = 0;
  894. if (current_dlg_pointer != NULL)
  895. return;
  896. /* skip initial requests - they may end up here because of the
  897. * preloaded route */
  898. if ((!req->to && parse_headers(req, HDR_TO_F, 0) < 0) || !req->to) {
  899. LM_ERR("bad request or missing TO hdr :-/\n");
  900. return;
  901. }
  902. if (get_to(req)->tag_value.len == 0)
  903. return;
  904. dlg = 0;
  905. dir = DLG_DIR_NONE;
  906. if (seq_match_mode != SEQ_MATCH_NO_ID) {
  907. if (d_rrb.get_route_param(req, &rr_param, &val) != 0) {
  908. LM_DBG("Route param '%.*s' not found\n", rr_param.len, rr_param.s);
  909. if (seq_match_mode == SEQ_MATCH_STRICT_ID)
  910. return;
  911. } else {
  912. LM_DBG("route param is '%.*s' (len=%d)\n", val.len, val.s, val.len);
  913. if (parse_dlg_rr_param(val.s, val.s + val.len, &h_entry, &h_id) < 0)
  914. return;
  915. dlg = lookup_dlg(h_entry, h_id);
  916. if (dlg == 0) {
  917. LM_WARN("unable to find dialog for %.*s "
  918. "with route param '%.*s' [%u:%u]\n",
  919. req->first_line.u.request.method.len,
  920. req->first_line.u.request.method.s,
  921. val.len, val.s, h_entry, h_id);
  922. if (seq_match_mode == SEQ_MATCH_STRICT_ID)
  923. return;
  924. } else {
  925. if (pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0) {
  926. // lookup_dlg has incremented the ref count by 1
  927. unref_dlg(dlg, 1);
  928. return;
  929. }
  930. if (match_dialog(dlg, &callid, &ftag, &ttag, &dir) == 0) {
  931. LM_WARN("tight matching failed for %.*s with callid='%.*s'/%d, "
  932. "ftag='%.*s'/%d, ttag='%.*s'/%d and direction=%d\n",
  933. req->first_line.u.request.method.len,
  934. req->first_line.u.request.method.s,
  935. callid.len, callid.s, callid.len,
  936. ftag.len, ftag.s, ftag.len,
  937. ttag.len, ttag.s, ttag.len, dir);
  938. LM_WARN("dialog identification elements are callid='%.*s'/%d, "
  939. "caller tag='%.*s'/%d\n",
  940. dlg->callid.len, dlg->callid.s, dlg->callid.len,
  941. dlg->from_tag.len, dlg->from_tag.s,
  942. dlg->from_tag.len);
  943. // lookup_dlg has incremented the ref count by 1
  944. unref_dlg(dlg, 1);
  945. // Reset variables in order to do a lookup based on SIP-Elements.
  946. dlg = 0;
  947. dir = DLG_DIR_NONE;
  948. if (seq_match_mode == SEQ_MATCH_STRICT_ID)
  949. return;
  950. }
  951. }
  952. }
  953. }
  954. if (dlg == 0) {
  955. if (pre_match_parse(req, &callid, &ftag, &ttag, 1) < 0)
  956. return;
  957. /* TODO - try to use the RR dir detection to speed up here the
  958. * search -bogdan */
  959. dlg = get_dlg(&callid, &ftag, &ttag, &dir);
  960. if (!dlg) {
  961. LM_DBG("Callid '%.*s' not found\n",
  962. req->callid->body.len, req->callid->body.s);
  963. return;
  964. }
  965. }
  966. /* set current dialog - re-use ref increment from dlg_get() above */
  967. set_current_dialog(req, dlg);
  968. _dlg_ctx.dlg = dlg;
  969. if (d_tmb.register_tmcb(req, NULL, TMCB_REQUEST_FWDED,
  970. store_dlg_in_tm_cb, (void*) dlg, NULL) < 0) {
  971. LM_ERR("failed to store dialog in transaction during dialog creation for later reference\n");
  972. }
  973. /* run state machine */
  974. switch (req->first_line.u.request.method_value) {
  975. case METHOD_PRACK:
  976. event = DLG_EVENT_REQPRACK;
  977. break;
  978. case METHOD_ACK:
  979. event = DLG_EVENT_REQACK;
  980. break;
  981. case METHOD_BYE:
  982. event = DLG_EVENT_REQBYE;
  983. break;
  984. default:
  985. event = DLG_EVENT_REQ;
  986. }
  987. next_state_dlg(dlg, event, &old_state, &new_state, &unref, 0);
  988. LM_DBG("unref after next state is %i\n", unref);
  989. CURR_DLG_ID = req->id;
  990. CURR_DLG_LIFETIME = (unsigned int) (time(0)) - dlg->start_ts;
  991. CURR_DLG_STATUS = new_state;
  992. /* run actions for the transition */
  993. if (event == DLG_EVENT_REQBYE && new_state == DLG_STATE_DELETED &&
  994. old_state != DLG_STATE_DELETED) {
  995. LM_DBG("BYE successfully processed\n");
  996. /* remove from timer */
  997. ret = remove_dialog_timer(&dlg->tl);
  998. if (ret < 0) {
  999. LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] "
  1000. "with clid '%.*s' and tags '%.*s'\n",
  1001. dlg, dlg->h_entry, dlg->h_id,
  1002. dlg->callid.len, dlg->callid.s,
  1003. dlg->from_tag.len, dlg->from_tag.s);
  1004. } else if (ret > 0) {
  1005. LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
  1006. "with clid '%.*s' and tags '%.*s' \n",
  1007. dlg, dlg->h_entry, dlg->h_id,
  1008. dlg->callid.len, dlg->callid.s,
  1009. dlg->from_tag.len, dlg->from_tag.s);
  1010. } else {
  1011. unref++;
  1012. }
  1013. /* dialog terminated (BYE) */
  1014. dlg_terminated(req, dlg, dir);
  1015. unref_dlg(dlg, unref);
  1016. return;
  1017. }
  1018. if ((event == DLG_EVENT_REQ || event == DLG_EVENT_REQACK)
  1019. && new_state == DLG_STATE_CONFIRMED) {
  1020. timeout = get_dlg_timeout(req);
  1021. if (timeout != default_timeout) {
  1022. dlg->lifetime = timeout;
  1023. }
  1024. if (update_dlg_timer(&dlg->tl, dlg->lifetime) == -1) {
  1025. LM_ERR("failed to update dialog lifetime\n");
  1026. }
  1027. if (update_cseqs(dlg, req, dir, &ttag) != 0) {
  1028. LM_ERR("cseqs update failed\n");
  1029. } else {
  1030. dlg->dflags |= DLG_FLAG_CHANGED;
  1031. }
  1032. if(dlg_db_mode==DB_MODE_REALTIME && (dlg->dflags&DLG_FLAG_CHANGED)) {
  1033. update_dialog_dbinfo(dlg);
  1034. }
  1035. if (old_state != DLG_STATE_CONFIRMED) {
  1036. LM_DBG("confirming ACK successfully processed\n");
  1037. /* confirming ACK request */
  1038. run_dlg_callbacks(DLGCB_CONFIRMED, dlg, req, NULL, dir, 0);
  1039. } else {
  1040. LM_DBG("sequential request successfully processed\n");
  1041. /* within dialog request */
  1042. run_dlg_callbacks(DLGCB_REQ_WITHIN, dlg, req, NULL, dir, 0);
  1043. if ((event != DLG_EVENT_REQACK) &&
  1044. (dlg->cbs.types) & DLGCB_RESPONSE_WITHIN) {
  1045. /* ref the dialog as registered into the transaction callback.
  1046. * unref will be done when the callback will be destroyed */
  1047. ref_dlg(dlg, 1);
  1048. /* register callback for the replies of this request */
  1049. if (d_tmb.register_tmcb(req, 0, TMCB_RESPONSE_FWDED,
  1050. (dir == DLG_DIR_UPSTREAM) ? dlg_seq_down_onreply : dlg_seq_up_onreply,
  1051. (void*) dlg, unreference_dialog) < 0) {
  1052. LM_ERR("failed to register TMCB (2)\n");
  1053. unref_dlg(dlg, 1);
  1054. }
  1055. }
  1056. }
  1057. }
  1058. if (new_state == DLG_STATE_CONFIRMED && old_state != DLG_STATE_CONFIRMED) {
  1059. dlg->dflags |= DLG_FLAG_CHANGED;
  1060. if(dlg_db_mode == DB_MODE_REALTIME)
  1061. update_dialog_dbinfo(dlg);
  1062. }
  1063. return;
  1064. }
  1065. /*!
  1066. * \brief Timer function that removes expired dialogs, run timeout route
  1067. * \param tl dialog timer list
  1068. */
  1069. void dlg_ontimeout(struct dlg_tl *tl) {
  1070. struct dlg_cell *dlg;
  1071. int new_state, old_state, unref;
  1072. struct sip_msg *fmsg;
  1073. /* get the dialog tl payload */
  1074. dlg = ((struct dlg_cell*) ((char *) (tl) -
  1075. (unsigned long) (&((struct dlg_cell*) 0)->tl)));
  1076. if (dlg->toroute > 0 && dlg->toroute < main_rt.entries
  1077. && main_rt.rlist[dlg->toroute] != NULL) {
  1078. fmsg = faked_msg_next();
  1079. if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE) > 0) {
  1080. dlg_set_ctx_dialog(dlg);
  1081. LM_DBG("executing route %d on timeout\n", dlg->toroute);
  1082. set_route_type(REQUEST_ROUTE);
  1083. run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
  1084. dlg_set_ctx_dialog(0);
  1085. exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
  1086. }
  1087. }
  1088. if ((dlg->dflags & DLG_FLAG_TOBYE)
  1089. && (dlg->state == DLG_STATE_CONFIRMED)) {
  1090. //TODO: dlg_bye_all(dlg, NULL);
  1091. unref_dlg(dlg, 1);
  1092. return;
  1093. }
  1094. next_state_dlg(dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref, 0);
  1095. if (new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED) {
  1096. LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s'\n",
  1097. dlg->callid.len, dlg->callid.s,
  1098. dlg->from_tag.len, dlg->from_tag.s);
  1099. /* dialog timeout */
  1100. run_dlg_callbacks(DLGCB_EXPIRED, dlg, NULL, NULL, DLG_DIR_NONE, 0);
  1101. unref_dlg(dlg, unref + 1);
  1102. } else {
  1103. unref_dlg(dlg, 1);
  1104. }
  1105. return;
  1106. }
  1107. /*!
  1108. * \brief Function that returns the dialog lifetime as pseudo-variable
  1109. * \param msg SIP message
  1110. * \param param pseudo-variable parameter
  1111. * \param res pseudo-variable result
  1112. * \return 0 on success, -1 on failure
  1113. */
  1114. int pv_get_dlg_lifetime(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
  1115. int l = 0;
  1116. char *ch = NULL;
  1117. if (msg == NULL || res == NULL)
  1118. return -1;
  1119. if (CURR_DLG_ID != msg->id)
  1120. return pv_get_null(msg, param, res);
  1121. res->ri = CURR_DLG_LIFETIME;
  1122. ch = int2str((unsigned long) res->ri, &l);
  1123. res->rs.s = ch;
  1124. res->rs.len = l;
  1125. res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT;
  1126. return 0;
  1127. }
  1128. /*!
  1129. * \brief Function that returns the dialog state as pseudo-variable
  1130. * \param msg SIP message
  1131. * \param param pseudo-variable parameter
  1132. * \param res pseudo-variable result
  1133. * \return 0 on success, -1 on failure
  1134. */
  1135. int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
  1136. int l = 0;
  1137. char *ch = NULL;
  1138. if (msg == NULL || res == NULL)
  1139. return -1;
  1140. if (CURR_DLG_ID != msg->id)
  1141. return pv_get_null(msg, param, res);
  1142. res->ri = CURR_DLG_STATUS;
  1143. ch = int2str((unsigned long) res->ri, &l);
  1144. res->rs.s = ch;
  1145. res->rs.len = l;
  1146. res->flags = PV_VAL_STR | PV_VAL_INT | PV_TYPE_INT;
  1147. return 0;
  1148. }
  1149. /*!
  1150. * \brief Helper function that prints all the properties of a dialog including all the dlg_out's
  1151. * \param dlg dialog cell
  1152. * \return void
  1153. */
  1154. void internal_print_all_dlg(struct dlg_cell *dlg) {
  1155. LM_DBG("Trying to get lock for printing\n");
  1156. lock_get(dlg->dlg_out_entries_lock);
  1157. struct dlg_cell_out *dlg_out;
  1158. struct dlg_entry_out *d_entry_out = &(dlg->dlg_entry_out);
  1159. LM_DBG("----------------------------");
  1160. LM_DBG("Dialog h_entry:h_id = [%u : %u]\n", dlg->h_entry, dlg->h_id);
  1161. LM_DBG("Dialog call-id: %.*s\n", dlg->callid.len, dlg->callid.s);
  1162. LM_DBG("Dialog state: %d\n", dlg->state);
  1163. LM_DBG("Dialog ref counter: %d\n", dlg->ref);
  1164. LM_DBG("Dialog did: %.*s\n", dlg->did.len, dlg->did.s);
  1165. LM_DBG("Dialog from_tag: %.*s\n", dlg->from_tag.len, dlg->from_tag.s);
  1166. LM_DBG("Dialog from_uri: %.*s\n", dlg->from_uri.len, dlg->from_uri.s);
  1167. LM_DBG("Dialog caller contact: %.*s\n", dlg->caller_contact.len, dlg->caller_contact.s);
  1168. LM_DBG("Dialog first request cseq: %.*s\n", dlg->first_req_cseq.len, dlg->first_req_cseq.s);
  1169. LM_DBG("Dialog caller route set: %.*s\n", dlg->caller_route_set.len, dlg->caller_route_set.s);
  1170. LM_DBG("Dialog lifetime: %d\n", dlg->lifetime);
  1171. LM_DBG("Dialog bind_address: %.*s\n", dlg->caller_bind_addr->sock_str.len, dlg->caller_bind_addr->sock_str.s);
  1172. dlg_out = d_entry_out->first;
  1173. while (dlg_out) {
  1174. LM_DBG("----------");
  1175. LM_DBG("Dialog out h_entry:h_id = [%u : %u]\n", dlg_out->h_entry, dlg_out->h_id);
  1176. LM_DBG("Dialog out did: %.*s\n", dlg_out->did.len, dlg_out->did.s);
  1177. LM_DBG("Dialog out to_tag: %.*s\n", dlg_out->to_tag.len, dlg_out->to_tag.s);
  1178. LM_DBG("Dialog out caller cseq: %.*s\n", dlg_out->caller_cseq.len, dlg_out->caller_cseq.s);
  1179. LM_DBG("Dialog out callee cseq: %.*s\n", dlg_out->callee_cseq.len, dlg_out->callee_cseq.s);
  1180. LM_DBG("Dialog out callee contact: %.*s\n", dlg_out->callee_contact.len, dlg_out->callee_contact.s);
  1181. LM_DBG("Dialog out callee route set: %.*s\n", dlg_out->callee_route_set.len, dlg_out->callee_route_set.s);
  1182. LM_DBG("----------");
  1183. dlg_out = dlg_out->next;
  1184. }
  1185. LM_DBG("Releasing lock for dlgout\n");
  1186. lock_release(dlg->dlg_out_entries_lock);
  1187. LM_DBG("----------------------------");
  1188. }
  1189. /*!
  1190. * \brief Helper function that prints information for all dialogs
  1191. * \return void
  1192. */
  1193. void print_all_dlgs() {
  1194. //print all dialog information - this is just for testing and is set to happen every 10 seconds
  1195. struct dlg_cell *dlg;
  1196. unsigned int i;
  1197. LM_DBG("********************");
  1198. LM_DBG("printing %i dialogs\n", d_table->size);
  1199. for (i = 0; i < d_table->size; i++) {
  1200. dlg_lock(d_table, &(d_table->entries[i]));
  1201. for (dlg = d_table->entries[i].first; dlg; dlg = dlg->next) {
  1202. internal_print_all_dlg(dlg);
  1203. }
  1204. dlg_unlock(d_table, &(d_table->entries[i]));
  1205. }
  1206. LM_DBG("********************");
  1207. }
  1208. struct dlg_cell *dlg_get_msg_dialog(sip_msg_t *msg)
  1209. {
  1210. struct dlg_cell *dlg = NULL;
  1211. str callid;
  1212. str ftag;
  1213. str ttag;
  1214. unsigned int dir;
  1215. /* Retrieve the current dialog */
  1216. dlg = dlg_get_ctx_dialog();
  1217. if (dlg != NULL )
  1218. return dlg;
  1219. if (pre_match_parse(msg, &callid, &ftag, &ttag, 0) < 0)
  1220. return NULL ;
  1221. dir = DLG_DIR_NONE;
  1222. dlg = get_dlg(&callid, &ftag, &ttag, &dir);
  1223. if (dlg == NULL ) {
  1224. LM_DBG("dlg with callid '%.*s' not found\n",
  1225. msg->callid->body.len, msg->callid->body.s);
  1226. return NULL ;
  1227. }
  1228. return dlg;
  1229. }