Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,1736 +0,0 @@
1
-/*
2
- * Copyright (C) 2006 Voice System SRL
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- *
20
- */
21
-
22
-
23
-/*!
24
- * \file
25
- * \brief Functions related to dialog handling
26
- * \ingroup dialog
27
- * Module: \ref dialog
28
- */
29
-
30
-#include <string.h>
31
-#include <time.h>
32
-
33
-#include "../../trim.h"
34
-#include "../../pvar.h"
35
-#include "../../timer.h"
36
-#include "../../counters.h"
37
-#include "../../action.h"
38
-#include "../../script_cb.h"
39
-#include "../../pt.h"
40
-#include "../../fmsg.h"
41
-#include "../../parser/parse_from.h"
42
-#include "../../parser/parse_cseq.h"
43
-#include "../../parser/contact/parse_contact.h"
44
-#include "../../parser/parse_from.h"
45
-#include "../../parser/parse_rr.h"
46
-#include "../../modules/tm/tm_load.h"
47
-#include "../rr/api.h"
48
-#include "dlg_hash.h"
49
-#include "dlg_timer.h"
50
-#include "dlg_cb.h"
51
-#include "dlg_cseq.h"
52
-#include "dlg_handlers.h"
53
-#include "dlg_req_within.h"
54
-#include "dlg_db_handler.h"
55
-#include "dlg_profile.h"
56
-#include "dlg_var.h"
57
-#include "dlg_dmq.h"
58
-
59
-static str       rr_param;		/*!< record-route parameter for matching */
60
-static int       dlg_flag_mask=0;	/*!< flag for dialog tracking */
61
-static pv_spec_t *timeout_avp;		/*!< AVP for timeout setting */
62
-static int       default_timeout;	/*!< default dialog timeout */
63
-static int       seq_match_mode;	/*!< dlg_match mode */ 
64
-static int       shutdown_done = 0;	/*!< 1 when destroy_dlg_handlers was called */
65
-extern int       detect_spirals;
66
-extern int       dlg_timeout_noreset;
67
-extern int       initial_cbs_inscript;
68
-extern int       dlg_send_bye;
69
-extern int       dlg_event_rt[DLG_EVENTRT_MAX];
70
-extern int       dlg_wait_ack;
71
-extern int       dlg_enable_dmq;
72
-int              spiral_detected = -1;
73
-
74
-extern struct rr_binds d_rrb;		/*!< binding to record-routing module */
75
-
76
-
77
-extern pv_elem_t *ruri_param_model;	/*!< pv-string to get r-uri */
78
-
79
-static unsigned int CURR_DLG_LIFETIME = 0;	/*!< current dialog lifetime */
80
-static unsigned int CURR_DLG_STATUS = 0;	/*!< current dialog state */
81
-static unsigned int CURR_DLG_ID  = 0xffffffff;	/*!< current dialog id */
82
-
83
-
84
-/*! size of the dialog record-route parameter */
85
-#define RR_DLG_PARAM_SIZE  (2*2*sizeof(int)+3+MAX_DLG_RR_PARAM_NAME)
86
-/*! separator inside the record-route paramter */
87
-#define DLG_SEPARATOR      '.'
88
-
89
-int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
90
-		int mode);
91
-int dlg_set_tm_waitack(tm_cell_t *t, dlg_cell_t *dlg);
92
-
93
-/*!
94
- * \brief Initialize the dialog handlers
95
- * \param rr_param_p added record-route parameter
96
- * \param dlg_flag_p dialog flag
97
- * \param timeout_avp_p AVP for timeout setting
98
- * \param default_timeout_p default timeout
99
- * \param seq_match_mode_p matching mode
100
- */
101
-void init_dlg_handlers(char *rr_param_p, int dlg_flag_p,
102
-		pv_spec_t *timeout_avp_p ,int default_timeout_p,
103
-		int seq_match_mode_p)
104
-{
105
-	rr_param.s = rr_param_p;
106
-	rr_param.len = strlen(rr_param.s);
107
-
108
-	if(dlg_flag_p>=0) dlg_flag_mask = 1<<dlg_flag_p;
109
-
110
-	timeout_avp = timeout_avp_p;
111
-	default_timeout = default_timeout_p;
112
-	seq_match_mode = seq_match_mode_p;
113
-}
114
-
115
-
116
-/*!
117
- * \brief Shutdown operation of the module
118
- */
119
-void destroy_dlg_handlers(void)
120
-{
121
-	shutdown_done = 1;
122
-}
123
-
124
-
125
-/*!
126
- * \brief Add record-route parameter for dialog tracking
127
- * \param req SIP request
128
- * \param entry dialog hash entry
129
- * \param id dialog hash id
130
- * \return 0 on success, -1 on failure
131
- */
132
-static inline int add_dlg_rr_param(struct sip_msg *req, unsigned int entry,
133
-		unsigned int id)
134
-{
135
-	static char buf[RR_DLG_PARAM_SIZE];
136
-	str s;
137
-	int n;
138
-	char *p;
139
-
140
-	s.s = p = buf;
141
-
142
-	*(p++) = ';';
143
-	memcpy(p, rr_param.s, rr_param.len);
144
-	p += rr_param.len;
145
-	*(p++) = '=';
146
-
147
-	n = RR_DLG_PARAM_SIZE - (p-buf);
148
-	if (int2reverse_hex( &p, &n, entry)==-1)
149
-		return -1;
150
-
151
-	*(p++) = DLG_SEPARATOR;
152
-
153
-	n = RR_DLG_PARAM_SIZE - (p-buf);
154
-	if (int2reverse_hex( &p, &n, id)==-1)
155
-		return -1;
156
-
157
-	s.len = p-buf;
158
-
159
-	if (d_rrb.add_rr_param( req, &s)<0) {
160
-		LM_ERR("failed to add rr param\n");
161
-		return -1;
162
-	}
163
-
164
-	return 0;
165
-}
166
-
167
-
168
-/*!
169
- * \brief Parse SIP message and populate leg informations
170
- *
171
- * Parse SIP message and populate leg informations. 
172
- * \param dlg the dialog to add cseq, contact & record_route
173
- * \param msg sip message
174
- * \param t transaction
175
- * \param leg type of the call leg
176
- * \param tag SIP To tag
177
- * \return 0 on success, -1 on failure
178
- * \note for a request: get record route in normal order, for a reply get
179
- * in reverse order, skipping the ones from the request and the proxies' own
180
- */
181
-int populate_leg_info( struct dlg_cell *dlg, struct sip_msg *msg,
182
-	struct cell* t, unsigned int leg, str *tag)
183
-{
184
-	unsigned int skip_recs;
185
-	str cseq;
186
-	str contact;
187
-	str rr_set;
188
-
189
-	dlg->bind_addr[leg] = msg->rcv.bind_address;
190
-
191
-	/* extract the cseq number as string */
192
-	if (leg==DLG_CALLER_LEG) {
193
-		if((!msg->cseq && (parse_headers(msg,HDR_CSEQ_F,0)<0 || !msg->cseq))
194
-			|| !msg->cseq->parsed){
195
-			LM_ERR("bad sip message or missing CSeq hdr :-/\n");
196
-			goto error0;
197
-		}
198
-		cseq = (get_cseq(msg))->number;
199
-	} else {
200
-		/* use the same as in request */
201
-		cseq = dlg->cseq[DLG_CALLEE_LEG];
202
-	}
203
-
204
-	/* extract the contact address */
205
-	if (!msg->contact&&(parse_headers(msg,HDR_CONTACT_F,0)<0||!msg->contact)){
206
-		LM_ERR("bad sip message or missing Contact hdr\n");
207
-		goto error0;
208
-	}
209
-	if ( parse_contact(msg->contact)<0 ||
210
-	((contact_body_t *)msg->contact->parsed)->contacts==NULL ||
211
-	((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL ) {
212
-		LM_ERR("bad Contact HDR\n");
213
-		goto error0;
214
-	}
215
-	contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri;
216
-
217
-	/* extract the RR parts */
218
-	if(!msg->record_route && (parse_headers(msg,HDR_EOH_F,0)<0)  ){
219
-		LM_ERR("failed to parse record route header\n");
220
-		goto error0;
221
-	}
222
-
223
-	if (leg==DLG_CALLER_LEG) {
224
-		skip_recs = 0;
225
-	} else {
226
-		/* was the 200 OK received or local generated */
227
-		skip_recs = dlg->from_rr_nb +
228
-			((t->relayed_reply_branch>=0)?
229
-				((t->uac[t->relayed_reply_branch].flags&TM_UAC_FLAG_R2)?2:
230
-				 ((t->uac[t->relayed_reply_branch].flags&TM_UAC_FLAG_RR)?1:0))
231
-				:0);
232
-	}
233
-
234
-	if(msg->record_route){
235
-		if( print_rr_body(msg->record_route, &rr_set, leg,
236
-							&skip_recs) != 0 ){
237
-			LM_ERR("failed to print route records \n");
238
-			goto error0;
239
-		}
240
-	} else {
241
-		rr_set.s = 0;
242
-		rr_set.len = 0;
243
-	}
244
-
245
-	if(leg==DLG_CALLER_LEG)
246
-		dlg->from_rr_nb = skip_recs;
247
-
248
-	LM_DBG("route_set %.*s, contact %.*s, cseq %.*s and bind_addr %.*s\n",
249
-		rr_set.len, rr_set.s, contact.len, contact.s,
250
-		cseq.len, cseq.s,
251
-		msg->rcv.bind_address->sock_str.len,
252
-		msg->rcv.bind_address->sock_str.s);
253
-
254
-	if (dlg_set_leg_info( dlg, tag, &rr_set, &contact, &cseq, leg)!=0) {
255
-		LM_ERR("dlg_set_leg_info failed\n");
256
-		if (rr_set.s) pkg_free(rr_set.s);
257
-		goto error0;
258
-	}
259
-
260
-	if (rr_set.s) pkg_free(rr_set.s);
261
-
262
-	return 0;
263
-error0:
264
-	return -1;
265
-}
266
-
267
-/*!
268
- * \brief Clone dialog internal unique id to shared memory
269
- */
270
-dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg)
271
-{
272
-	dlg_iuid_t *iuid = NULL;
273
-
274
-	if(dlg==NULL)
275
-		return NULL;
276
-
277
-	iuid = (dlg_iuid_t*)shm_malloc(sizeof(dlg_iuid_t));
278
-	if(iuid==NULL)
279
-	{
280
-		LM_ERR("failed to clone dialog iuid\n");
281
-		return NULL;
282
-	}
283
-
284
-	memset(iuid, 0, sizeof(dlg_iuid_t));
285
-	iuid->h_entry = dlg->h_entry;
286
-	iuid->h_id = dlg->h_id;
287
-
288
-	return iuid;
289
-}
290
-
291
-
292
-/*!
293
- * \brief Free dialog internal unique id stored in shared memory
294
- */
295
-void dlg_iuid_sfree(void *iuid)
296
-{
297
-    if(iuid) {
298
-		LM_DBG("freeing dlg iuid [%u:%u] (%p)\n",
299
-				((dlg_iuid_t*)iuid)->h_entry,
300
-				((dlg_iuid_t*)iuid)->h_id, iuid);
301
-		shm_free(iuid);
302
-	}
303
-}
304
-
305
-
306
-/*!
307
- * \brief Function that executes BYE reply callbacks
308
- * \param t transaction, unused
309
- * \param type type of the callback, should be TMCB_RESPONSE_FWDED
310
- * \param params saved dialog structure inside the callback
311
- */
312
-static void dlg_terminated_confirmed(tm_cell_t *t, int type,
313
-                                     struct tmcb_params* params)
314
-{
315
-    dlg_cell_t *dlg = NULL;
316
-	dlg_iuid_t *iuid = NULL;
317
-
318
-    if(!params || !params->req || !params->param)
319
-    {
320
-        LM_ERR("invalid parameters!\n");
321
-        return;
322
-    }
323
-
324
-	iuid = (dlg_iuid_t*)*params->param;
325
-	if(iuid==NULL)
326
-		return;
327
-
328
-    dlg = dlg_get_by_iuid(iuid);
329
-
330
-    if(dlg==NULL)
331
-    {
332
-        LM_ERR("failed to get dialog from params!\n");
333
-        return;
334
-    }
335
-    /* dialog termination confirmed (BYE reply) */
336
-    run_dlg_callbacks(DLGCB_TERMINATED_CONFIRMED,
337
-                      dlg,
338
-                      params->req,
339
-                      params->rpl,
340
-                      DLG_DIR_UPSTREAM,
341
-                      0);
342
-	dlg_release(dlg);
343
-}
344
-
345
-/*!
346
- * \brief Execute callback for the BYE request and register callback for the BYE reply
347
- * \param req request message
348
- * \param dlg corresponding dialog
349
- * \param dir message direction
350
- */
351
-static void dlg_terminated(sip_msg_t *req, dlg_cell_t *dlg, unsigned int dir)
352
-{
353
-	dlg_iuid_t *iuid = NULL;
354
-
355
-    if(!req) {
356
-        LM_ERR("request is empty!");
357
-        return;
358
-    }
359
-
360
-    if(!dlg) {
361
-        LM_ERR("dialog is empty!");
362
-        return;
363
-    }
364
-
365
-    /* dialog terminated (BYE) */
366
-    run_dlg_callbacks(DLGCB_TERMINATED, dlg, req, NULL, dir, 0);
367
-
368
-	iuid = dlg_get_iuid_shm_clone(dlg);
369
-	if(iuid==NULL)
370
-		return;
371
-
372
-    /* register callback for the coresponding reply */
373
-    if (d_tmb.register_tmcb(req,
374
-                            0,
375
-                            TMCB_RESPONSE_OUT,
376
-                            dlg_terminated_confirmed,
377
-                            (void*)iuid,
378
-                            dlg_iuid_sfree) <= 0 ) {
379
-        LM_ERR("cannot register response callback for BYE request\n");
380
-        return;
381
-    }
382
-}
383
-
384
-/*!
385
- * \brief Function that is registered as TM callback and called on T destroy
386
- *
387
- * - happens when wait_ack==1
388
- *
389
- */
390
-static void dlg_ontdestroy(struct cell* t, int type, struct tmcb_params *param)
391
-{
392
-	dlg_cell_t *dlg = NULL;
393
-	dlg_iuid_t *iuid = NULL;
394
-
395
-	iuid = (dlg_iuid_t*)(*param->param);
396
-	dlg = dlg_get_by_iuid(iuid);
397
-	if(dlg==0)
398
-		return;
399
-	/* 1 for callback and 1 for dlg lookup */
400
-	dlg_unref(dlg, 2);
401
-}
402
-
403
-/*!
404
- * \brief Function that is registered as TM callback and called on replies
405
- *
406
- * Function that is registered as TM callback and called on replies. It
407
- * parses the reply and set the appropriate event. This is then used to
408
- * update the dialog state, run eventual dialog callbacks and save or
409
- * update the necessary informations about the dialog.
410
- * \see next_state_dlg
411
- * \param t transaction, unused
412
- * \param type type of the entered callback
413
- * \param param saved dialog structure in the callback
414
- */
415
-static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
416
-{
417
-    dlg_cell_t *dlg = NULL;
418
-	dlg_iuid_t *iuid = NULL;
419
-    int new_state, old_state, unref, event;
420
-    str tag;
421
-    sip_msg_t *req = param->req;
422
-	sip_msg_t *rpl = param->rpl;
423
-
424
-	if (shutdown_done)
425
-		return;
426
-	iuid = (dlg_iuid_t*)(*param->param);
427
-	dlg = dlg_get_by_iuid(iuid);
428
-	if(dlg==0)
429
-		return;
430
-
431
-	unref = 0;
432
-	if (type & (TMCB_RESPONSE_IN|TMCB_ON_FAILURE)) {
433
-		/* Set the dialog context so it is available in onreply_route and failure_route*/
434
-		set_current_dialog(req, dlg);
435
-		dlg_set_ctx_iuid(dlg);
436
-		goto done_early;
437
-	}
438
-
439
-	if (type==TMCB_RESPONSE_FWDED) {
440
-		/* The state does not change, but the msg is mutable in this callback*/
441
-		run_dlg_callbacks(DLGCB_RESPONSE_FWDED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
442
-		goto done_early;
443
-	}
444
-
445
-	if (type==TMCB_DESTROY)
446
-		event = DLG_EVENT_TDEL;
447
-	else if (param->code<200)
448
-		event = DLG_EVENT_RPL1xx;
449
-	else if (param->code<300)
450
-		event = DLG_EVENT_RPL2xx;
451
-	else
452
-		event = DLG_EVENT_RPL3xx;
453
-
454
-	next_state_dlg( dlg, event, &old_state, &new_state, &unref);
455
-	dlg_run_event_route(dlg, (rpl==FAKED_REPLY)?NULL:rpl, old_state, new_state);
456
-
457
-	if (new_state==DLG_STATE_EARLY) {
458
-		run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
459
-		if (old_state!=DLG_STATE_EARLY)
460
-			if_update_stat(dlg_enable_stats, early_dlgs, 1);
461
-		goto done;
462
-	}
463
-
464
-	if (new_state==DLG_STATE_CONFIRMED_NA &&
465
-	old_state!=DLG_STATE_CONFIRMED_NA && old_state!=DLG_STATE_CONFIRMED ) {
466
-		LM_DBG("dialog %p confirmed (ACK pending)\n",dlg);
467
-
468
-		 if (rpl != FAKED_REPLY) {
469
-			/* get to tag*/
470
-			if ( !rpl->to && ((parse_headers(rpl, HDR_TO_F,0)<0)
471
-						|| !rpl->to) ) {
472
-				LM_ERR("bad reply or missing TO hdr :-/\n");
473
-				tag.s = 0;
474
-				tag.len = 0;
475
-			} else {
476
-				tag = get_to(rpl)->tag_value;
477
-				if (tag.s==0 || tag.len==0) {
478
-					LM_ERR("missing TAG param in TO hdr :-/\n");
479
-					tag.s = 0;
480
-					tag.len = 0;
481
-				}
482
-			}
483
-
484
-			/* save callee's tag, cseq, contact and record route*/
485
-			if (populate_leg_info( dlg, rpl, t, DLG_CALLEE_LEG, &tag) !=0) {
486
-				LM_ERR("could not add further info to the dialog\n");
487
-			}
488
-		 } else {
489
-			 LM_ERR("Faked reply!\n");
490
-		 }
491
-
492
-		/* set start time */
493
-		dlg->start_ts = (unsigned int)(time(0));
494
-
495
-		/* save the settings to the database,
496
-		 * if realtime saving mode configured- save dialog now
497
-		 * else: the next time the timer will fire the update*/
498
-		dlg->dflags |= DLG_FLAG_NEW;
499
-		if ( dlg_db_mode==DB_MODE_REALTIME )
500
-			update_dialog_dbinfo(dlg);
501
-
502
-		if (0 != insert_dlg_timer( &dlg->tl, dlg->lifetime )) {
503
-			LM_CRIT("Unable to insert dlg %p [%u:%u] on event %d [%d->%d] "
504
-				"with clid '%.*s' and tags '%.*s' '%.*s'\n",
505
-				dlg, dlg->h_entry, dlg->h_id, event, old_state, new_state,
506
-				dlg->callid.len, dlg->callid.s,
507
-				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
508
-				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
509
-		} else {
510
-			/* dialog pointer inserted in timer list */
511
-			dlg_ref(dlg, 1);
512
-		}
513
-
514
-		/* dialog confirmed (ACK pending) */
515
-		run_dlg_callbacks( DLGCB_CONFIRMED_NA, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
516
-
517
-		if (old_state==DLG_STATE_EARLY)
518
-			if_update_stat(dlg_enable_stats, early_dlgs, -1);
519
-
520
-		if (unref) dlg_unref(dlg, unref);
521
-		if_update_stat(dlg_enable_stats, active_dlgs, 1);
522
-		goto done;
523
-	}
524
-
525
-	if(new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
526
-		/* set end time */
527
-		dlg->end_ts = (unsigned int)(time(0));
528
-	}
529
-
530
-	if ( new_state==DLG_STATE_DELETED
531
-				&& (old_state==DLG_STATE_UNCONFIRMED
532
-					|| old_state==DLG_STATE_EARLY) ) {
533
-		LM_DBG("dialog %p failed (negative reply)\n", dlg);
534
-		/* dialog setup not completed (3456XX) */
535
-		run_dlg_callbacks( DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
536
-		if(dlg_wait_ack==1)
537
-			dlg_set_tm_waitack(t, dlg);
538
-		/* do unref */
539
-		if (unref)
540
-			dlg_unref(dlg, unref);
541
-		if (old_state==DLG_STATE_EARLY)
542
-			if_update_stat(dlg_enable_stats, early_dlgs, -1);
543
-
544
-		if_update_stat(dlg_enable_stats, failed_dlgs, 1);
545
-
546
-		goto done;
547
-	}
548
-
549
-	if (unref) dlg_unref(dlg, unref);
550
-
551
-done:
552
-	if(dlg_enable_dmq && (dlg->iflags & DLG_IFLAG_DMQ_SYNC) && new_state>old_state) {
553
-		dlg_dmq_replicate_action(DLG_DMQ_STATE, dlg, 0, 0);
554
-	}
555
-
556
-done_early:
557
-	/* unref due to dlg_get_by_iuid() */
558
-	dlg_release(dlg);
559
-	return;
560
-}
561
-
562
-
563
-/*!
564
- * \brief Helper function that run dialog callbacks on forwarded requests
565
- * \see dlg_seq_up_onreply
566
- * \see dlg_seq_down_onreply
567
- * \param t transaction, unused
568
- * \param type type of the callback, should be TMCB_RESPONSE_FWDED
569
- * \param param saved dialog structure inside the callback
570
- * \param direction direction of the request
571
- */
572
-static void dlg_seq_onreply_helper(struct cell* t, int type,
573
-		struct tmcb_params *param, const int direction)
574
-{
575
-	dlg_cell_t *dlg = NULL;
576
-	dlg_iuid_t *iuid = NULL;
577
-
578
-	if (shutdown_done)
579
-		return;
580
-	iuid = (dlg_iuid_t*)(*param->param);
581
-	dlg = dlg_get_by_iuid(iuid);
582
-	if (dlg==0)
583
-		return;
584
-
585
-	if (type==TMCB_RESPONSE_FWDED)
586
-	{
587
-		run_dlg_callbacks( DLGCB_RESPONSE_WITHIN,
588
-		                   dlg,
589
-		                   param->req,
590
-		                   param->rpl,
591
-		                   direction,
592
-		                   0);
593
-	}
594
-	dlg_release(dlg);
595
-
596
-	return;
597
-}
598
-
599
-
600
-/*!
601
- * \brief Run dialog callbacks on forwarded requests in upstream direction
602
- * \see dlg_seq_onreply_helper
603
- * \param t transaction, unused
604
- * \param type type of the callback, should be TMCB_RESPONSE_FWDED
605
- * \param param saved dialog structure inside the callback
606
- */
607
-static void dlg_seq_up_onreply(struct cell* t, int type, struct tmcb_params *param)
608
-{
609
-	dlg_seq_onreply_helper(t, type, param, DLG_DIR_UPSTREAM);
610
-}
611
-
612
-
613
-/*!
614
- * \brief Run dialog callbacks on forwarded requests in downstream direction
615
- * \see dlg_seq_onreply_helper
616
- * \param t transaction, unused
617
- * \param type type of the callback, should be TMCB_RESPONSE_FWDED
618
- * \param param saved dialog structure inside the callback
619
- */
620
-static void dlg_seq_down_onreply(struct cell* t, int type, struct tmcb_params *param)
621
-{
622
-	dlg_seq_onreply_helper(t, type, param, DLG_DIR_DOWNSTREAM);
623
-}
624
-
625
-
626
-/*!
627
- * \brief Return the timeout for a dialog
628
- * \param req SIP message
629
- * \return value from timeout AVP if present or default timeout
630
- */
631
-inline static int get_dlg_timeout(struct sip_msg *req)
632
-{
633
-	pv_value_t pv_val;
634
-
635
-	if( timeout_avp ) {
636
-		if ( pv_get_spec_value( req, timeout_avp, &pv_val)==0 &&
637
-				pv_val.flags&PV_VAL_INT && pv_val.ri>0 ) {
638
-			return pv_val.ri;
639
-		}
640
-		LM_DBG("invalid AVP value, using default timeout\n");
641
-	}
642
-	return default_timeout;
643
-}
644
-
645
-/*!
646
- * \brief Helper function to get the necessary content from SIP message
647
- * \param req SIP request
648
- * \param callid found callid
649
- * \param ftag found from tag
650
- * \param ttag found to tag
651
- * \param with_ttag flag set if to tag must be found for success
652
- * \return 0 on success, -1 on failure
653
- */
654
-static inline int pre_match_parse( struct sip_msg *req, str *callid,
655
-		str *ftag, str *ttag, int with_ttag)
656
-{
657
-	if (parse_headers(req,HDR_CALLID_F|HDR_TO_F,0)<0 || !req->callid ||
658
-			!req->to ) {
659
-		LM_ERR("bad request or missing CALLID/TO hdr :-/\n");
660
-		return -1;
661
-	}
662
-
663
-	if (get_to(req)->tag_value.len==0) {
664
-		if (with_ttag == 1) {
665
-			/* out of dialog request with preloaded Route headers; ignore. */
666
-			return -1;
667
-		} else {
668
-			ttag->s = NULL;
669
-			ttag->len = 0;
670
-		}
671
-	} else {
672
-		*ttag = get_to(req)->tag_value;
673
-	}
674
-
675
-	if (parse_from_header(req)<0 || get_from(req)->tag_value.len==0) {
676
-		LM_ERR("failed to get From header\n");
677
-		return -1;
678
-	}
679
-
680
-	/* callid */
681
-	*callid = req->callid->body;
682
-	trim(callid);
683
-	/* from tag */
684
-	*ftag = get_from(req)->tag_value;
685
-	return 0;
686
-}
687
-
688
-/*!
689
- * \brief Sync dialog from tm callback (another wrapper)
690
- * \param t transaction, unused
691
- * \param type type of the entered callback
692
- * \param param saved dialog structure in the callback
693
- */
694
-static void dlg_on_send(struct cell* t, int type, struct tmcb_params *param)
695
-{
696
-	dlg_cell_t *dlg = NULL;
697
-	dlg_iuid_t *iuid = NULL;
698
-
699
-	LM_DBG("dialog_on_send CB\n");
700
-	iuid = (dlg_iuid_t*)(*param->param);
701
-	if (iuid==NULL)
702
-	return;
703
-
704
-	dlg = dlg_get_by_iuid(iuid);
705
-	if(dlg==NULL)
706
-	return;
707
-
708
-	/* sync over dmq */
709
-	if (dlg_enable_dmq) {
710
-	dlg_dmq_replicate_action(DLG_DMQ_UPDATE, dlg, 1, 0);
711
-	}
712
-
713
-	/* unref by 2: 1 set when adding in tm cb, 1 set by dlg_get_by_iuid() */
714
-	dlg_unref(dlg, 1);
715
-}
716
-
717
-
718
-/*!
719
- * \brief Function that is registered as TM callback and called on requests
720
- * \see dlg_new_dialog
721
- * \param t transaction, used to created the dialog
722
- * \param type type of the entered callback
723
- * \param param saved dialog structure in the callback
724
- */
725
-void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
726
-{
727
-	sip_msg_t *req = param->req;
728
-	dlg_cell_t *dlg = NULL;
729
-	dlg_iuid_t *iuid = NULL;
730
-
731
-	if(req->first_line.u.request.method_value == METHOD_BYE) {
732
-		_dlg_ctx.t = 1;
733
-		return;
734
-	}
735
-
736
-	if(req->first_line.u.request.method_value != METHOD_INVITE)
737
-		return;
738
-
739
-	dlg = dlg_get_ctx_dialog();
740
-
741
-	if (dlg!=NULL) {
742
-		if (!initial_cbs_inscript) {
743
-			if (spiral_detected == 1)
744
-				run_dlg_callbacks( DLGCB_SPIRALED, dlg,
745
-						req, NULL, DLG_DIR_DOWNSTREAM, 0);
746
-			else if (spiral_detected == 0)
747
-				run_create_callbacks(dlg, req);
748
-		}
749
-	}
750
-	if (dlg==NULL) {
751
-		if((req->flags&dlg_flag_mask)!=dlg_flag_mask)
752
-			return;
753
-		LM_DBG("dialog creation on config flag\n");
754
-		dlg_new_dialog(req, t, 1);
755
-		dlg = dlg_get_ctx_dialog();
756
-	}
757
-	if (dlg!=NULL) {
758
-		LM_DBG("dialog added to tm callbacks\n");
759
-		dlg_set_tm_callbacks(t, req, dlg, spiral_detected);
760
-		_dlg_ctx.t = 1;
761
-		dlg_release(dlg);
762
-	}
763
-
764
-	if (dlg_enable_dmq) {
765
-		iuid = dlg_get_iuid_shm_clone(dlg);
766
-		if(iuid==NULL)
767
-		{
768
-			LM_ERR("failed to create dialog unique id clone\n");
769
-		} else {
770
-			/* register callback for when the request is sent */
771
-			if ( d_tmb.register_tmcb(req, t, TMCB_REQUEST_FWDED,
772
-			dlg_on_send,
773
-			(void*)iuid, dlg_iuid_sfree)<0 ) {
774
-				LM_ERR("failed to register TMCB_REQUEST_FWDED\n");
775
-				shm_free(iuid);
776
-			}
777
-		}
778
-	}
779
-
780
-}
781
-
782
-
783
-/*!
784
- * \brief Unreference a new dialog, helper function for dlg_onreq
785
- * \see dlg_onreq
786
- * \param dialog unreferenced dialog
787
- */
788
-#if 0
789
-static void unref_new_dialog(void *iuid)
790
-{
791
-	struct tmcb_params p;
792
-
793
-	memset(&p, 0, sizeof(struct tmcb_params));
794
-	p.param = (void*)&iuid;
795
-	dlg_onreply(0, TMCB_DESTROY, &p);
796
-}
797
-#endif
798
-
799
-
800
-/*!
801
- * \brief Create a new dialog from a sip message
802
- *
803
- * Create a new dialog from a SIP message, register a callback
804
- * to keep track of the dialog with help of the tm module.
805
- * This function is either called from the request callback, or
806
- * from the dlg_manage function in the configuration script.
807
- * \see dlg_onreq
808
- * \see w_dlg_manage
809
- * \param req SIP message
810
- * \param t transaction
811
- * \param run_initial_cbs if set zero, initial callbacks are not executed
812
- * \return 0 on success, -1 on failure
813
- */ 
814
-int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
815
-{
816
-	dlg_cell_t *dlg;
817
-	str s;
818
-	str callid;
819
-    str ftag;
820
-    str ttag;
821
-    str req_uri;
822
-    unsigned int dir;
823
-
824
-	dlg = dlg_get_ctx_dialog();
825
-    if(dlg != NULL) {
826
-		dlg_release(dlg);
827
-        return -1;
828
-	}
829
-
830
-	if(req->first_line.u.request.method_value != METHOD_INVITE)
831
-		return -1;
832
-
833
-    if(pre_match_parse( req, &callid, &ftag, &ttag, 0)<0) {
834
-        LM_WARN("pre-matching failed\n");
835
-        return -1;
836
-    }
837
-
838
-    if(ttag.s!=0 && ttag.len!=0)
839
-        return -1;
840
-
841
-    if(pv_printf_s(req, ruri_param_model, &req_uri)<0) {
842
-        LM_ERR("error - cannot print the r-uri format\n");
843
-        return -1;
844
-    }
845
-    trim(&req_uri);
846
-
847
-	dir = DLG_DIR_NONE;
848
-	/* search dialog by SIP attributes
849
-	 * - hash table slot is left locked  */
850
-	dlg = dlg_search(&callid, &ftag, &ttag, &dir);
851
-	if(dlg) {
852
-		if (detect_spirals) {
853
-			if (spiral_detected == 1) {
854
-				dlg_hash_release(&callid);
855
-				return 0;
856
-			}
857
-
858
-			if ( dlg->state != DLG_STATE_DELETED ) {
859
-				LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
860
-					callid.len, callid.s);
861
-				spiral_detected = 1;
862
-
863
-				if (run_initial_cbs)
864
-					run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, NULL,
865
-							DLG_DIR_DOWNSTREAM, 0);
866
-				/* set ctx dlg id shortcuts */
867
-				_dlg_ctx.iuid.h_entry = dlg->h_entry;
868
-				_dlg_ctx.iuid.h_id = dlg->h_id;
869
-				/* search_dlg() has incremented the ref count by 1 */
870
-				dlg_release(dlg);
871
-				dlg_hash_release(&callid);
872
-				return 0;
873
-			}
874
-			dlg_release(dlg);
875
-		}
876
-    }
877
-    spiral_detected = 0;
878
-
879
-    dlg = build_new_dlg (&callid /*callid*/,
880
-                         &(get_from(req)->uri) /*from uri*/,
881
-                         &(get_to(req)->uri) /*to uri*/,
882
-                         &ftag/*from_tag*/,
883
-                         &req_uri /*r-uri*/ );
884
-
885
-	if (dlg==0) {
886
-		dlg_hash_release(&callid);
887
-		LM_ERR("failed to create new dialog\n");
888
-		return -1;
889
-	}
890
-
891
-	/* save caller's tag, cseq, contact and record route*/
892
-	if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG,
893
-			&(get_from(req)->tag_value)) !=0) {
894
-		dlg_hash_release(&callid);
895
-		LM_ERR("could not add further info to the dialog\n");
896
-		shm_free(dlg);
897
-		return -1;
898
-	}
899
-
900
-	/* Populate initial varlist: */
901
-	dlg->vars = get_local_varlist_pointer(req, 1);
902
-
903
-	/* after dlg_search() slot was kept locked */
904
-	link_dlg(dlg, 0, 1);