1 /*
2  * Copyright (C) 2006 Voice System SRL
3  * Copyright (C) 2011 Carsten Bock, carsten@ng-voice.com
4  *
5  * This file is part of Kamailio, a free SIP server.
6  *
7  * Kamailio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version
11  *
12  * Kamailio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 
23 /*!
24  * \file
25  * \brief Functions and definitions related to dialog creation and searching
26  * \ingroup dialog
27  * Module: \ref dialog
28  */
29 
30 #ifndef _DIALOG_DLG_HASH_H_
31 #define _DIALOG_DLG_HASH_H_
32 
33 #include "../../core/locking.h"
34 #include "../../core/timer.h"
35 #include "../../core/atomic_ops.h"
36 #include "dlg_timer.h"
37 #include "dlg_cb.h"
38 
39 
40 /* states of a dialog */
41 #define DLG_STATE_UNCONFIRMED  1 /*!< unconfirmed dialog */
42 #define DLG_STATE_EARLY        2 /*!< early dialog */
43 #define DLG_STATE_CONFIRMED_NA 3 /*!< confirmed dialog without a ACK yet */
44 #define DLG_STATE_CONFIRMED    4 /*!< confirmed dialog */
45 #define DLG_STATE_DELETED      5 /*!< deleted dialog */
46 
47 /* events for dialog processing */
48 #define DLG_EVENT_TDEL         1 /*!< transaction was destroyed */
49 #define DLG_EVENT_RPL1xx       2 /*!< 1xx request */
50 #define DLG_EVENT_RPL2xx       3 /*!< 2xx request */
51 #define DLG_EVENT_RPL3xx       4 /*!< 3xx request */
52 #define DLG_EVENT_REQPRACK     5 /*!< PRACK request */
53 #define DLG_EVENT_REQACK       6 /*!< ACK request */
54 #define DLG_EVENT_REQBYE       7 /*!< BYE request */
55 #define DLG_EVENT_REQ          8 /*!< other requests */
56 
57 /* dialog internal flags only in memory */
58 #define DLG_FLAG_NEW           (1<<0) /*!< new dialog */
59 #define DLG_FLAG_CHANGED       (1<<1) /*!< dialog was changed */
60 #define DLG_FLAG_HASBYE        (1<<2) /*!< bye was received */
61 #define DLG_FLAG_CALLERBYE     (1<<4) /*!< bye from caller */
62 #define DLG_FLAG_CALLEEBYE     (1<<5) /*!< bye from callee */
63 #define DLG_FLAG_LOCALDLG      (1<<6) /*!< local dialog, unused */
64 #define DLG_FLAG_CHANGED_VARS  (1<<7) /*!< dialog-variables changed */
65 
66 /* dialog-variable flags (in addition to dialog-flags) */
67 #define DLG_FLAG_DEL           (1<<8) /*!< delete this var */
68 
69 #define DLG_FLAG_TM            (1<<9) /*!< dialog is set in transaction */
70 #define DLG_FLAG_EXPIRED       (1<<10)/*!< dialog is expired */
71 #define DLG_FLAG_CHANGED_PROF  (1<<10)/*!< dialog-profiles changed DMQ*/
72 #define DLG_FLAG_DB_LOAD_EXTRA (1<<12)/*!< dialog loaded extra from db */
73 
74 /* internal flags stored in db */
75 #define DLG_IFLAG_TIMEOUTBYE        (1<<0) /*!< send bye on time-out */
76 #define DLG_IFLAG_KA_SRC            (1<<1) /*!< send keep alive to src */
77 #define DLG_IFLAG_KA_DST            (1<<2) /*!< send keep alive to dst */
78 #define DLG_IFLAG_TIMER_NORESET     (1<<3) /*!< don't reset dialog timers on in-dialog messages reception */
79 #define DLG_IFLAG_CSEQ_DIFF         (1<<4) /*!< CSeq changed in dialog */
80 #define DLG_IFLAG_PRACK             (1<<5) /*!< PRACK was routed during initial state */
81 #define DLG_IFLAG_DMQ_SYNC          (1<<6) /*!< sync this dialog via dmq DMQ*/
82 
83 #define DLG_CALLER_LEG         0 /*!< attribute that belongs to a caller leg */
84 #define DLG_CALLEE_LEG         1 /*!< attribute that belongs to a callee leg */
85 
86 #define DLG_DIR_NONE           0 /*!< dialog has no direction */
87 #define DLG_DIR_DOWNSTREAM     1 /*!< dialog has downstream direction */
88 #define DLG_DIR_UPSTREAM       2 /*!< dialog has upstream direction */
89 
90 #define DLG_EVENTRT_START    0
91 #define DLG_EVENTRT_END      1
92 #define DLG_EVENTRT_FAILED   2
93 #define DLG_EVENTRT_MAX      3
94 
95 /*! internal unique ide per dialog */
96 typedef struct dlg_iuid {
97 	unsigned int         h_id;		/*!< id in the hash table entry (seq nr in slot) */
98 	unsigned int         h_entry;	/*!< index of hash table entry (the slot number) */
99 } dlg_iuid_t;
100 
101 /*! entries in the dialog list */
102 typedef struct dlg_cell
103 {
104 	volatile int         ref;		/*!< reference counter */
105 	struct dlg_cell      *next;		/*!< next entry in the list */
106 	struct dlg_cell      *prev;		/*!< previous entry in the list */
107 	unsigned int         h_id;		/*!< id in the hash table entry (seq nr in slot) */
108 	unsigned int         h_entry;	/*!< index of hash table entry (the slot number) */
109 	unsigned int         state;		/*!< dialog state */
110 	unsigned int         lifetime;		/*!< dialog lifetime */
111 	unsigned int         init_ts;		/*!< init (creation) time (absolute UNIX ts)*/
112 	unsigned int         start_ts;		/*!< start time  (absolute UNIX ts)*/
113 	unsigned int         end_ts;		/*!< end time  (absolute UNIX ts)*/
114 	unsigned int         dflags;		/*!< internal dialog memory flags */
115 	unsigned int         iflags;		/*!< internal dialog persistent flags */
116 	unsigned int         sflags;		/*!< script dialog persistent flags */
117 	int                  toroute;		/*!< index of route that is executed on timeout */
118 	str                  toroute_name;	/*!< name of route that is executed on timeout */
119 	unsigned int         from_rr_nb;	/*!< information from record routing */
120 	struct dlg_tl        tl;			/*!< dialog timer list */
121 	str                  callid;		/*!< callid from SIP message */
122 	str                  from_uri;		/*!< from uri from SIP message */
123 	str                  to_uri;		/*!< to uri from SIP message */
124 	str                  req_uri;		/*!< r-uri from SIP message */
125 	str                  tag[2];		/*!< from tags of caller and to tag of callee */
126 	str                  cseq[2];		/*!< CSEQ of caller and callee */
127 	str                  route_set[2];	/*!< route set of caller and callee */
128 	str                  contact[2];	/*!< contact of caller and callee */
129 	struct socket_info * bind_addr[2];	/*! binded address of caller and callee */
130 	struct dlg_head_cbl  cbs;		/*!< dialog callbacks */
131 	struct dlg_profile_link *profile_links; /*!< dialog profiles */
132 	struct dlg_var       *vars;		/*!< dialog variables */
133 	unsigned int         ka_src_counter;	/*!< keepalive src (caller) counter */
134 	unsigned int         ka_dst_counter;	/*!< keepalive dst (callee) counter */
135 } dlg_cell_t;
136 
137 
138 /*! entries in the main dialog table */
139 typedef struct dlg_entry
140 {
141 	struct dlg_cell    *first;	/*!< dialog list */
142 	struct dlg_cell    *last;	/*!< optimisation, end of the dialog list */
143 	unsigned int       next_id;	/*!< next id */
144 	gen_lock_t lock;     /* mutex to access items in the slot */
145 	atomic_t locker_pid; /* pid of the process that holds the lock */
146 	int rec_lock_level;  /* recursive lock count */
147 } dlg_entry_t;
148 
149 
150 /*! main dialog table */
151 typedef struct dlg_table
152 {
153 	unsigned int       size;	/*!< size of the dialog table */
154 	struct dlg_entry   *entries;	/*!< dialog hash table */
155 } dlg_table_t;
156 
157 
158 typedef struct dlg_ka {
159 	dlg_iuid_t iuid;
160 	ticks_t katime;
161 	unsigned iflags;
162 	struct dlg_ka *next;
163 } dlg_ka_t;
164 
165 /*! global dialog table */
166 extern dlg_table_t *d_table;
167 
168 
169 /*!
170  * \brief Set a dialog lock (re-entrant)
171  * \param _table dialog table
172  * \param _entry locked entry
173  */
174 #define dlg_lock(_table, _entry) \
175 		do { \
176 			int mypid; \
177 			mypid = my_pid(); \
178 			if (likely(atomic_get( &(_entry)->locker_pid) != mypid)) { \
179 				lock_get( &(_entry)->lock); \
180 				atomic_set( &(_entry)->locker_pid, mypid); \
181 			} else { \
182 				/* locked within the same process that executed us */ \
183 				(_entry)->rec_lock_level++; \
184 			} \
185 		} while(0)
186 
187 
188 /*!
189  * \brief Release a dialog lock
190  * \param _table dialog table
191  * \param _entry locked entry
192  */
193 #define dlg_unlock(_table, _entry) \
194 		do { \
195 			if (likely((_entry)->rec_lock_level == 0)) { \
196 				atomic_set( &(_entry)->locker_pid, 0); \
197 				lock_release( &(_entry)->lock); \
198 			} else  { \
199 				/* recursive locked => decrease lock count */ \
200 				(_entry)->rec_lock_level--; \
201 			} \
202 		} while(0)
203 
204 /*!
205  * \brief Set a dialog lock (re-entrant)
206  * \param _dlg dialog cell
207  */
208 #define dlg_cell_lock(_dlg) \
209 	dlg_lock(d_table, &(d_table->entries[(_dlg)->h_entry]))
210 
211 /*!
212  * \brief Set a dialog lock (re-entrant)
213  * \param _dlg dialog cell
214  */
215 #define dlg_cell_unlock(_dlg) \
216 	dlg_unlock(d_table, &(d_table->entries[(_dlg)->h_entry]))
217 
218 
219 /*!
220  * \brief Unlink a dialog from the list without locking
221  * \see unref_dlg_unsafe
222  * \param d_entry unlinked entry
223  * \param dlg unlinked dialog
224  */
unlink_unsafe_dlg(dlg_entry_t * d_entry,dlg_cell_t * dlg)225 static inline void unlink_unsafe_dlg(dlg_entry_t *d_entry, dlg_cell_t *dlg)
226 {
227 	if (dlg->next)
228 		dlg->next->prev = dlg->prev;
229 	else
230 		d_entry->last = dlg->prev;
231 	if (dlg->prev)
232 		dlg->prev->next = dlg->next;
233 	else
234 		d_entry->first = dlg->next;
235 
236 	dlg->next = dlg->prev = 0;
237 
238 	return;
239 }
240 
241 
242 /*!
243  * \brief Destroy a dialog, run callbacks and free memory
244  * \param dlg destroyed dialog
245  */
246 void destroy_dlg(dlg_cell_t *dlg);
247 
248 
249 /*!
250  * \brief Initialize the global dialog table
251  * \param size size of the table
252  * \return 0 on success, -1 on failure
253  */
254 int init_dlg_table(unsigned int size);
255 
256 
257 /*!
258  * \brief Destroy the global dialog table
259  */
260 void destroy_dlg_table(void);
261 
262 
263 /*!
264  * \brief Create a new dialog structure for a SIP dialog
265  * \param callid dialog callid
266  * \param from_uri dialog from uri
267  * \param to_uri dialog to uri
268  * \param from_tag dialog from tag
269  * \param req_uri dialog r-uri
270  * \return created dialog structure on success, NULL otherwise
271  */
272 dlg_cell_t* build_new_dlg(str *callid, str *from_uri,
273 		str *to_uri, str *from_tag, str *req_uri);
274 
275 
276 /*!
277  * \brief Set the leg information for an existing dialog
278  * \param dlg dialog
279  * \param tag from tag or to tag
280  * \param rr record-routing information
281  * \param contact caller or callee contact
282  * \param cseq CSEQ of caller or callee
283  * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
284  * \return 0 on success, -1 on failure
285  */
286 int dlg_set_leg_info(dlg_cell_t *dlg, str* tag, str *rr, str *contact,
287 		str *cseq, unsigned int leg);
288 
289 
290 /*!
291  * \brief Update or set the Contact for an existing dialog
292  * \param dlg dialog
293  * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
294  * \param ct Contact of caller or callee
295  * \return 0 on success, -1 on failure
296  */
297 int dlg_update_contact(struct dlg_cell * dlg, unsigned int leg, str *ct);
298 
299 
300 /*!
301  * \brief Update or set the CSEQ for an existing dialog
302  * \param dlg dialog
303  * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
304  * \param cseq CSEQ of caller or callee
305  * \return 0 on success, -1 on failure
306  */
307 int dlg_update_cseq(dlg_cell_t *dlg, unsigned int leg, str *cseq);
308 
309 /*!
310  * \brief Update or set the routeset for an existing dialog
311  * \param dlg dialog
312  * \param leg must be either DLG_CALLER_LEG, or DLG_CALLEE_LEG
313  * \param rr routeset
314  * \return 0 on success, -1 on failure
315  */
316 int dlg_update_rr_set(struct dlg_cell * dlg, unsigned int leg, str *rr);
317 
318 /*!
319  * \brief Set time-out route
320  * \param dlg dialog
321  * \param route name of route
322  * \return 0 on success, -1 on failure
323  */
324 int dlg_set_toroute(dlg_cell_t *dlg, str *route);
325 
326 
327 /*!
328  * \brief Lookup a dialog in the global list
329  *
330  * Note that the caller is responsible for decrementing (or reusing)
331  * the reference counter by one again iff a dialog has been found.
332  * \param h_entry number of the hash table entry
333  * \param h_id id of the hash table entry
334  * \param lmode id if 0, then dlg table entry is unlocked, otherwise is locked
335  * \return dialog structure on success, NULL on failure
336  */
337 dlg_cell_t *dlg_lookup_mode(unsigned int h_entry, unsigned int h_id, int lmode);
338 
339 /*!
340  * \brief Lookup a dialog in the global list
341  *
342  * Note that the caller is responsible for decrementing (or reusing)
343  * the reference counter by one again if a dialog has been found.
344  * \param h_entry number of the hash table entry
345  * \param h_id id of the hash table entry
346  * \return dialog structure on success, NULL on failure
347  */
348 dlg_cell_t* dlg_lookup(unsigned int h_entry, unsigned int h_id);
349 
350 /*!
351  * \brief Search a dialog in the global list by iuid
352  *
353  * Note that the caller is responsible for decrementing (or reusing)
354  * the reference counter by one again if a dialog has been found.
355  * \param diuid internal unique id per dialog
356  * \param lmode id if 0, then dlg table entry is unlocked, otherwise is locked
357  * \return dialog structure on success, NULL on failure
358  */
359 dlg_cell_t* dlg_get_by_iuid_mode(dlg_iuid_t *diuid, int lmode);
360 
361 /*!
362  * \brief Search and return dialog in the global list by iuid
363  *
364  * Note that the caller is responsible for decrementing (or reusing)
365  * the reference counter by one again if a dialog has been found.
366  * \param diuid internal unique id per dialog
367  * \return dialog structure on success, NULL on failure
368  */
369 dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid);
370 
371 
372 /*!
373  * \brief Get dialog that correspond to CallId, From Tag and To Tag
374  *
375  * Get dialog that correspond to CallId, From Tag and To Tag.
376  * See RFC 3261, paragraph 4. Overview of Operation:
377  * "The combination of the To tag, From tag, and Call-ID completely
378  * defines a peer-to-peer SIP relationship between [two UAs] and is
379  * referred to as a dialog."
380  * Note that the caller is responsible for decrementing (or reusing)
381  * the reference counter by one again iff a dialog has been found.
382  * \param callid callid
383  * \param ftag from tag
384  * \param ttag to tag
385  * \param dir direction
386  * \return dialog structure on success, NULL on failure
387  */
388 dlg_cell_t* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
389 
390 
391 /*!
392  * \brief Search dialog that corresponds to CallId, From Tag and To Tag
393  *
394  * Get dialog that correspond to CallId, From Tag and To Tag.
395  * See RFC 3261, paragraph 4. Overview of Operation:
396  * "The combination of the To tag, From tag, and Call-ID completely
397  * defines a peer-to-peer SIP relationship between [two UAs] and is
398  * referred to as a dialog."
399  * Note that the caller is responsible for decrementing (or reusing)
400  * the reference counter by one again if a dialog has been found.
401  * Important: the hash slot is left locked (e.g., needed to allow
402  * linking the structure of a new dialog).
403  * \param callid callid
404  * \param ftag from tag
405  * \param ttag to tag
406  * \param dir direction
407  * \return dialog structure on success, NULL on failure (and slot locked)
408  */
409 dlg_cell_t* dlg_search(str *callid, str *ftag, str *ttag, unsigned int *dir);
410 
411 
412 /*!
413  * \brief Lock hash table slot by call-id
414  * \param callid call-id value
415  */
416 void dlg_hash_lock(str *callid);
417 
418 
419 /*!
420  * \brief Release hash table slot by call-id
421  * \param callid call-id value
422  */
423 void dlg_hash_release(str *callid);
424 
425 
426 /*!
427  * \brief Link a dialog structure
428  * \param dlg dialog
429  * \param n extra increments for the reference counter
430  * \param mode link in safe mode (0 - lock slot; 1 - don't)
431  */
432 void link_dlg(struct dlg_cell *dlg, int n, int mode);
433 
434 
435 /*!
436  * \brief Unreference a dialog with locking
437  * \see unref_dlg_unsafe
438  * \param dlg dialog
439  * \param cnt decrement for the reference counter
440  */
441 void dlg_unref_helper(dlg_cell_t *dlg, unsigned int cnt, const char *fname,
442 		int fline);
443 
444 #define dlg_unref(dlg, cnt) dlg_unref_helper((dlg), (cnt), __FILE__, __LINE__)
445 
446 /*!
447  * \brief Refefence a dialog with locking
448  * \see ref_dlg_unsafe
449  * \param dlg dialog
450  * \param cnt increment for the reference counter
451  */
452 void dlg_ref_helper(dlg_cell_t *dlg, unsigned int cnt, const char *fname,
453 		int fline);
454 
455 #define dlg_ref(dlg, cnt) dlg_ref_helper((dlg), (cnt), __FILE__, __LINE__)
456 
457 /*!
458  * \brief Release a dialog from ref counter by 1
459  * \see dlg_unref
460  * \param dlg dialog
461  */
462 void dlg_release(dlg_cell_t *dlg);
463 
464 /*!
465  * \brief Update a dialog state according a event and the old state
466  *
467  * This functions implement the main state machine that update a dialog
468  * state according a processed event and the current state. If necessary
469  * it will delete the processed dialog. The old and new state are also
470  * saved for reference.
471  * \param dlg updated dialog
472  * \param event current event
473  * \param old_state old dialog state
474  * \param new_state new dialog state
475  * \param unref set to 1 when the dialog was deleted, 0 otherwise
476  */
477 void next_state_dlg(dlg_cell_t *dlg, int event,
478 		int *old_state, int *new_state, int *unref);
479 
480 
481 /*!
482  * \brief Check if a dialog structure matches to a SIP message dialog
483  * \param dlg dialog structure
484  * \param callid SIP message Call-ID
485  * \param ftag SIP message from tag
486  * \param ttag SIP message to tag
487  * \param dir direction of the message, if DLG_DIR_NONE it will set
488  * \return 1 if dialog structure and message content matches, 0 otherwise
489  */
match_dialog(dlg_cell_t * dlg,str * callid,str * ftag,str * ttag,unsigned int * dir)490 static inline int match_dialog(dlg_cell_t *dlg, str *callid,
491 		str *ftag, str *ttag, unsigned int *dir)
492 {
493 	if (dlg->tag[DLG_CALLEE_LEG].len == 0) {
494 		// dialog to tag is undetermined ATM.
495 		if (*dir==DLG_DIR_DOWNSTREAM) {
496 			if (dlg->callid.len == callid->len &&
497 				dlg->tag[DLG_CALLER_LEG].len == ftag->len &&
498 				strncmp(dlg->callid.s, callid->s, callid->len)==0 &&
499 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ftag->s, ftag->len)==0) {
500 				return 1;
501 			}
502 		} else if (*dir==DLG_DIR_UPSTREAM) {
503 			if (dlg->callid.len == callid->len &&
504 				dlg->tag[DLG_CALLER_LEG].len == ttag->len &&
505 				strncmp(dlg->callid.s, callid->s, callid->len)==0 &&
506 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ttag->s, ttag->len)==0) {
507 				return 1;
508 			}
509 		} else {
510 			if (dlg->callid.len != callid->len)
511 				return 0;
512 
513 			if (dlg->tag[DLG_CALLER_LEG].len == ttag->len &&
514 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ttag->s, ttag->len)==0 &&
515 				strncmp(dlg->callid.s, callid->s, callid->len)==0) {
516 
517 				*dir = DLG_DIR_UPSTREAM;
518 				return 1;
519 			} else if (dlg->tag[DLG_CALLER_LEG].len == ftag->len
520 					&& strncmp(dlg->tag[DLG_CALLER_LEG].s, ftag->s, ftag->len)==0
521 					&& strncmp(dlg->callid.s, callid->s, callid->len)==0) {
522 
523 				*dir = DLG_DIR_DOWNSTREAM;
524 				return 1;
525 			}
526 		}
527 	} else {
528 		if (*dir==DLG_DIR_DOWNSTREAM) {
529 			if (dlg->callid.len == callid->len &&
530 				dlg->tag[DLG_CALLER_LEG].len == ftag->len &&
531 				dlg->tag[DLG_CALLEE_LEG].len == ttag->len &&
532 				strncmp(dlg->callid.s, callid->s, callid->len)==0 &&
533 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ftag->s, ftag->len)==0 &&
534 				strncmp(dlg->tag[DLG_CALLEE_LEG].s, ttag->s, ttag->len)==0) {
535 				return 1;
536 			}
537 		} else if (*dir==DLG_DIR_UPSTREAM) {
538 			if (dlg->callid.len == callid->len &&
539 				dlg->tag[DLG_CALLEE_LEG].len == ftag->len &&
540 				dlg->tag[DLG_CALLER_LEG].len == ttag->len &&
541 				strncmp(dlg->callid.s, callid->s, callid->len)==0 &&
542 				strncmp(dlg->tag[DLG_CALLEE_LEG].s, ftag->s, ftag->len)==0 &&
543 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ttag->s, ttag->len)==0) {
544 				return 1;
545 			}
546 		} else {
547 			if (dlg->callid.len != callid->len)
548 				return 0;
549 
550 			if (dlg->tag[DLG_CALLEE_LEG].len == ftag->len &&
551 				dlg->tag[DLG_CALLER_LEG].len == ttag->len &&
552 				strncmp(dlg->tag[DLG_CALLEE_LEG].s, ftag->s, ftag->len)==0 &&
553 				strncmp(dlg->tag[DLG_CALLER_LEG].s, ttag->s, ttag->len)==0 &&
554 				strncmp(dlg->callid.s, callid->s, callid->len)==0) {
555 
556 				*dir = DLG_DIR_UPSTREAM;
557 				return 1;
558 			} else if (dlg->tag[DLG_CALLER_LEG].len == ftag->len &&
559 						dlg->tag[DLG_CALLEE_LEG].len == ttag->len &&
560 						strncmp(dlg->tag[DLG_CALLER_LEG].s, ftag->s, ftag->len)==0 &&
561 						strncmp(dlg->tag[DLG_CALLEE_LEG].s, ttag->s, ttag->len)==0 &&
562 						strncmp(dlg->callid.s, callid->s, callid->len)==0) {
563 
564 				*dir = DLG_DIR_DOWNSTREAM;
565 				return 1;
566 			}
567 			/* if no ACK yet, might be a lookup of dlg from a TM callback that
568 			 * runs on 200ok but with initial INVITE that has no to-tag */
569 			if(ttag->len==0 && dlg->state==DLG_STATE_CONFIRMED_NA
570 					&& dlg->tag[DLG_CALLER_LEG].len == ftag->len &&
571 						strncmp(dlg->tag[DLG_CALLER_LEG].s, ftag->s, ftag->len)==0 &&
572 						strncmp(dlg->callid.s, callid->s, callid->len)==0) {
573 
574 				*dir = DLG_DIR_DOWNSTREAM;
575 				return 1;
576 			}
577 		}
578 	}
579 
580 	return 0;
581 }
582 
583 
584 /*!
585  * \brief Check if a downstream dialog structure matches a SIP message dialog
586  * \param dlg dialog structure
587  * \param callid SIP message callid
588  * \param ftag SIP message from tag
589  * \return 1 if dialog structure matches the SIP dialog, 0 otherwise
590  */
match_downstream_dialog(dlg_cell_t * dlg,str * callid,str * ftag)591 static inline int match_downstream_dialog(dlg_cell_t *dlg, str *callid, str *ftag)
592 {
593 	if(dlg==NULL || callid==NULL)
594 		return 0;
595 	if (ftag==NULL) {
596 		if (dlg->callid.len!=callid->len ||
597 			strncmp(dlg->callid.s,callid->s,callid->len)!=0)
598 			return 0;
599 	} else {
600 		if (dlg->callid.len!=callid->len ||
601 			dlg->tag[DLG_CALLER_LEG].len!=ftag->len  ||
602 			strncmp(dlg->callid.s,callid->s,callid->len)!=0 ||
603 			strncmp(dlg->tag[DLG_CALLER_LEG].s,ftag->s,ftag->len)!=0)
604 			return 0;
605 	}
606 	return 1;
607 }
608 
609 /*!
610  *
611  */
612 int dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
613 
614 
615 int dlg_ka_add(dlg_cell_t *dlg);
616 
617 int dlg_ka_run(ticks_t ti);
618 
619 int dlg_clean_run(ticks_t ti);
620 
621 /*!
622  * \brief Update dialog lifetime - for internal callers.
623  */
624 
625 int update_dlg_timeout(dlg_cell_t *, int);
626 
627 #endif
628