1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program 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  * This program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <pjsip/sip_ua_layer.h>
21 #include <pjsip/sip_module.h>
22 #include <pjsip/sip_dialog.h>
23 #include <pjsip/sip_endpoint.h>
24 #include <pjsip/sip_errno.h>
25 #include <pjsip/sip_transaction.h>
26 #include <pj/os.h>
27 #include <pj/hash.h>
28 #include <pj/assert.h>
29 #include <pj/string.h>
30 #include <pj/pool.h>
31 #include <pj/log.h>
32 
33 
34 #define THIS_FILE    "sip_ua_layer.c"
35 
36 /*
37  * Static prototypes.
38  */
39 static pj_status_t mod_ua_load(pjsip_endpoint *endpt);
40 static pj_status_t mod_ua_unload(void);
41 static pj_bool_t   mod_ua_on_rx_request(pjsip_rx_data *rdata);
42 static pj_bool_t   mod_ua_on_rx_response(pjsip_rx_data *rdata);
43 static void	   mod_ua_on_tsx_state(pjsip_transaction*, pjsip_event*);
44 
45 
46 extern long pjsip_dlg_lock_tls_id;	/* defined in sip_dialog.c */
47 
48 /* This struct is used to represent list of dialog inside a dialog set.
49  * We don't want to use pjsip_dialog for this purpose, to save some
50  * memory (about 100 bytes per dialog set).
51  */
52 struct dlg_set_head
53 {
54     PJ_DECL_LIST_MEMBER(pjsip_dialog);
55 };
56 
57 /* This struct represents a dialog set.
58  * This is the value that will be put in the UA's hash table.
59  */
60 struct dlg_set
61 {
62     /* To put this node in free dlg_set nodes in UA. */
63     PJ_DECL_LIST_MEMBER(struct dlg_set);
64 
65     /* This is the buffer to store this entry in the hash table. */
66     pj_hash_entry_buf ht_entry;
67 
68     /* List of dialog in this dialog set. */
69     struct dlg_set_head  dlg_list;
70 };
71 
72 
73 /*
74  * Module interface.
75  */
76 static struct user_agent
77 {
78     pjsip_module	 mod;
79     pj_pool_t		*pool;
80     pjsip_endpoint	*endpt;
81     pj_mutex_t		*mutex;
82     pj_hash_table_t	*dlg_table;
83     pjsip_ua_init_param  param;
84     struct dlg_set	 free_dlgset_nodes;
85 
86 } mod_ua =
87 {
88   {
89     NULL, NULL,		    /* prev, next.			*/
90     { "mod-ua", 6 },	    /* Name.				*/
91     -1,			    /* Id				*/
92     PJSIP_MOD_PRIORITY_UA_PROXY_LAYER,	/* Priority		*/
93     &mod_ua_load,	    /* load()				*/
94     NULL,		    /* start()				*/
95     NULL,		    /* stop()				*/
96     &mod_ua_unload,	    /* unload()				*/
97     &mod_ua_on_rx_request,  /* on_rx_request()			*/
98     &mod_ua_on_rx_response, /* on_rx_response()			*/
99     NULL,		    /* on_tx_request.			*/
100     NULL,		    /* on_tx_response()			*/
101     &mod_ua_on_tsx_state,   /* on_tsx_state()			*/
102   }
103 };
104 
105 /*
106  * mod_ua_load()
107  *
108  * Called when module is being loaded by endpoint.
109  */
mod_ua_load(pjsip_endpoint * endpt)110 static pj_status_t mod_ua_load(pjsip_endpoint *endpt)
111 {
112     pj_status_t status;
113 
114     /* Initialize the user agent. */
115     mod_ua.endpt = endpt;
116     mod_ua.pool = pjsip_endpt_create_pool( endpt, "ua%p", PJSIP_POOL_LEN_UA,
117 					   PJSIP_POOL_INC_UA);
118     if (mod_ua.pool == NULL)
119 	return PJ_ENOMEM;
120 
121     status = pj_mutex_create_recursive(mod_ua.pool, " ua%p", &mod_ua.mutex);
122     if (status != PJ_SUCCESS)
123 	return status;
124 
125     mod_ua.dlg_table = pj_hash_create(mod_ua.pool, PJSIP_MAX_DIALOG_COUNT);
126     if (mod_ua.dlg_table == NULL)
127 	return PJ_ENOMEM;
128 
129     pj_list_init(&mod_ua.free_dlgset_nodes);
130 
131     /* Initialize dialog lock. */
132     status = pj_thread_local_alloc(&pjsip_dlg_lock_tls_id);
133     if (status != PJ_SUCCESS)
134 	return status;
135 
136     pj_thread_local_set(pjsip_dlg_lock_tls_id, NULL);
137 
138     return PJ_SUCCESS;
139 
140 }
141 
142 /*
143  * mod_ua_unload()
144  *
145  * Called when module is being unloaded.
146  */
mod_ua_unload(void)147 static pj_status_t mod_ua_unload(void)
148 {
149     pj_thread_local_free(pjsip_dlg_lock_tls_id);
150     pj_mutex_destroy(mod_ua.mutex);
151 
152     /* Release pool */
153     if (mod_ua.pool) {
154 	pjsip_endpt_release_pool( mod_ua.endpt, mod_ua.pool );
155     }
156     return PJ_SUCCESS;
157 }
158 
159 /*
160  * mod_ua_on_tsx_stats()
161  *
162  * Called on changed on transaction state.
163  */
mod_ua_on_tsx_state(pjsip_transaction * tsx,pjsip_event * e)164 static void mod_ua_on_tsx_state( pjsip_transaction *tsx, pjsip_event *e)
165 {
166     pjsip_dialog *dlg;
167 
168     /* Get the dialog where this transaction belongs. */
169     dlg = (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];
170 
171     /* If dialog instance has gone, it could mean that the dialog
172      * may has been destroyed.
173      */
174     if (dlg == NULL)
175 	return;
176 
177     /* Hand over the event to the dialog. */
178     pjsip_dlg_on_tsx_state(dlg, tsx, e);
179 }
180 
181 
182 /*
183  * Init user agent module and register it to the endpoint.
184  */
pjsip_ua_init_module(pjsip_endpoint * endpt,const pjsip_ua_init_param * prm)185 PJ_DEF(pj_status_t) pjsip_ua_init_module( pjsip_endpoint *endpt,
186 					  const pjsip_ua_init_param *prm)
187 {
188     pj_status_t status;
189 
190     /* Check if module already registered. */
191     PJ_ASSERT_RETURN(mod_ua.mod.id == -1, PJ_EINVALIDOP);
192 
193     /* Copy param, if exists. */
194     if (prm)
195 	pj_memcpy(&mod_ua.param, prm, sizeof(pjsip_ua_init_param));
196 
197     /* Register the module. */
198     status = pjsip_endpt_register_module(endpt, &mod_ua.mod);
199 
200     return status;
201 }
202 
203 /*
204  * Get the instance of the user agent.
205  *
206  */
pjsip_ua_instance(void)207 PJ_DEF(pjsip_user_agent*) pjsip_ua_instance(void)
208 {
209     return &mod_ua.mod;
210 }
211 
212 
213 /*
214  * Get the endpoint where this UA is currently registered.
215  */
pjsip_ua_get_endpt(pjsip_user_agent * ua)216 PJ_DEF(pjsip_endpoint*) pjsip_ua_get_endpt(pjsip_user_agent *ua)
217 {
218     PJ_UNUSED_ARG(ua);
219     pj_assert(ua == &mod_ua.mod);
220     return mod_ua.endpt;
221 }
222 
223 
224 /*
225  * Destroy the user agent layer.
226  */
pjsip_ua_destroy(void)227 PJ_DEF(pj_status_t) pjsip_ua_destroy(void)
228 {
229     /* Check if module already destroyed. */
230     PJ_ASSERT_RETURN(mod_ua.mod.id != -1, PJ_EINVALIDOP);
231 
232     return pjsip_endpt_unregister_module(mod_ua.endpt, &mod_ua.mod);
233 }
234 
235 
236 
237 /*
238  * Create key to identify dialog set.
239  */
240 /*
241 PJ_DEF(void) pjsip_ua_create_dlg_set_key( pj_pool_t *pool,
242 					  pj_str_t *set_key,
243 					  const pj_str_t *call_id,
244 					  const pj_str_t *local_tag)
245 {
246     PJ_ASSERT_ON_FAIL(pool && set_key && call_id && local_tag, return;);
247 
248     set_key->slen = call_id->slen + local_tag->slen + 1;
249     set_key->ptr = (char*) pj_pool_alloc(pool, set_key->slen);
250     pj_assert(set_key->ptr != NULL);
251 
252     pj_memcpy(set_key->ptr, call_id->ptr, call_id->slen);
253     set_key->ptr[call_id->slen] = '$';
254     pj_memcpy(set_key->ptr + call_id->slen + 1,
255 	      local_tag->ptr, local_tag->slen);
256 }
257 */
258 
259 /*
260  * Acquire one dlg_set node to be put in the hash table.
261  * This will first look in the free nodes list, then allocate
262  * a new one from UA's pool when one is not available.
263  */
alloc_dlgset_node(void)264 static struct dlg_set *alloc_dlgset_node(void)
265 {
266     struct dlg_set *set;
267 
268     if (!pj_list_empty(&mod_ua.free_dlgset_nodes)) {
269 	set = mod_ua.free_dlgset_nodes.next;
270 	pj_list_erase(set);
271 	return set;
272     } else {
273 	set = PJ_POOL_ALLOC_T(mod_ua.pool, struct dlg_set);
274 	return set;
275     }
276 }
277 
278 /*
279  * Register new dialog. Called by pjsip_dlg_create_uac() and
280  * pjsip_dlg_create_uas_and_inc_lock();
281  */
pjsip_ua_register_dlg(pjsip_user_agent * ua,pjsip_dialog * dlg)282 PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
283 					   pjsip_dialog *dlg )
284 {
285     /* Sanity check. */
286     PJ_ASSERT_RETURN(ua && dlg, PJ_EINVAL);
287 
288     /* For all dialogs, local tag (inc hash) must has been initialized. */
289     PJ_ASSERT_RETURN(dlg->local.info && dlg->local.info->tag.slen &&
290 		     dlg->local.tag_hval != 0, PJ_EBUG);
291 
292     /* For UAS dialog, remote tag (inc hash) must have been initialized. */
293     //PJ_ASSERT_RETURN(dlg->role==PJSIP_ROLE_UAC ||
294     //		     (dlg->role==PJSIP_ROLE_UAS && dlg->remote.info->tag.slen
295     //		      && dlg->remote.tag_hval != 0), PJ_EBUG);
296 
297     /* Lock the user agent. */
298     pj_mutex_lock(mod_ua.mutex);
299 
300     /* For UAC, check if there is existing dialog in the same set. */
301     if (dlg->role == PJSIP_ROLE_UAC) {
302 	struct dlg_set *dlg_set;
303 
304 	dlg_set = (struct dlg_set*)
305 		  pj_hash_get_lower( mod_ua.dlg_table,
306                                      dlg->local.info->tag.ptr,
307 			             (unsigned)dlg->local.info->tag.slen,
308 			             &dlg->local.tag_hval);
309 
310 	if (dlg_set) {
311 	    /* This is NOT the first dialog in the dialog set.
312 	     * Just add this dialog in the list.
313 	     */
314 	    pj_assert(dlg_set->dlg_list.next != (void*)&dlg_set->dlg_list);
315 	    pj_list_push_back(&dlg_set->dlg_list, dlg);
316 
317 	    dlg->dlg_set = dlg_set;
318 
319 	} else {
320 	    /* This is the first dialog in the dialog set.
321 	     * Create the dialog set and add this dialog to it.
322 	     */
323 	    dlg_set = alloc_dlgset_node();
324 	    pj_list_init(&dlg_set->dlg_list);
325 	    pj_list_push_back(&dlg_set->dlg_list, dlg);
326 
327 	    dlg->dlg_set = dlg_set;
328 
329 	    /* Register the dialog set in the hash table. */
330 	    pj_hash_set_np_lower(mod_ua.dlg_table,
331 			         dlg->local.info->tag.ptr,
332                                  (unsigned)dlg->local.info->tag.slen,
333 			         dlg->local.tag_hval, dlg_set->ht_entry,
334                                  dlg_set);
335 	}
336 
337     } else {
338 	/* For UAS, create the dialog set with a single dialog as member. */
339 	struct dlg_set *dlg_set;
340 
341 	dlg_set = alloc_dlgset_node();
342 	pj_list_init(&dlg_set->dlg_list);
343 	pj_list_push_back(&dlg_set->dlg_list, dlg);
344 
345 	dlg->dlg_set = dlg_set;
346 
347 	pj_hash_set_np_lower(mod_ua.dlg_table,
348 		             dlg->local.info->tag.ptr,
349                              (unsigned)dlg->local.info->tag.slen,
350 		             dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);
351     }
352 
353     /* Unlock user agent. */
354     pj_mutex_unlock(mod_ua.mutex);
355 
356     /* Done. */
357     return PJ_SUCCESS;
358 }
359 
360 
pjsip_ua_unregister_dlg(pjsip_user_agent * ua,pjsip_dialog * dlg)361 PJ_DEF(pj_status_t) pjsip_ua_unregister_dlg( pjsip_user_agent *ua,
362 					     pjsip_dialog *dlg )
363 {
364     struct dlg_set *dlg_set;
365     pjsip_dialog *d;
366 
367     /* Sanity-check arguments. */
368     PJ_ASSERT_RETURN(ua && dlg, PJ_EINVAL);
369 
370     /* Check that dialog has been registered. */
371     PJ_ASSERT_RETURN(dlg->dlg_set, PJ_EINVALIDOP);
372 
373     /* Lock user agent. */
374     pj_mutex_lock(mod_ua.mutex);
375 
376     /* Find this dialog from the dialog set. */
377     dlg_set = (struct dlg_set*) dlg->dlg_set;
378     d = dlg_set->dlg_list.next;
379     while (d != (pjsip_dialog*)&dlg_set->dlg_list && d != dlg) {
380 	d = d->next;
381     }
382 
383     if (d != dlg) {
384 	pj_assert(!"Dialog is not registered!");
385 	pj_mutex_unlock(mod_ua.mutex);
386 	return PJ_EINVALIDOP;
387     }
388 
389     /* Remove this dialog from the list. */
390     pj_list_erase(dlg);
391 
392     /* If dialog list is empty, remove the dialog set from the hash table. */
393     if (pj_list_empty(&dlg_set->dlg_list)) {
394 	pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,
395 		          (unsigned)dlg->local.info->tag.slen,
396 			  dlg->local.tag_hval, NULL);
397 
398 	/* Return dlg_set to free nodes. */
399 	pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);
400     }
401 
402     /* Unlock user agent. */
403     pj_mutex_unlock(mod_ua.mutex);
404 
405     /* Done. */
406     return PJ_SUCCESS;
407 }
408 
409 
pjsip_rdata_get_dlg(pjsip_rx_data * rdata)410 PJ_DEF(pjsip_dialog*) pjsip_rdata_get_dlg( pjsip_rx_data *rdata )
411 {
412     return (pjsip_dialog*) rdata->endpt_info.mod_data[mod_ua.mod.id];
413 }
414 
pjsip_tdata_get_dlg(pjsip_tx_data * tdata)415 PJ_DEF(pjsip_dialog*) pjsip_tdata_get_dlg( pjsip_tx_data *tdata )
416 {
417     return (pjsip_dialog*) tdata->mod_data[mod_ua.mod.id];
418 }
419 
pjsip_tsx_get_dlg(pjsip_transaction * tsx)420 PJ_DEF(pjsip_dialog*) pjsip_tsx_get_dlg( pjsip_transaction *tsx )
421 {
422     return (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];
423 }
424 
425 
426 /*
427  * Retrieve the current number of dialog-set currently registered
428  * in the hash table.
429  */
pjsip_ua_get_dlg_set_count(void)430 PJ_DEF(unsigned) pjsip_ua_get_dlg_set_count(void)
431 {
432     unsigned count;
433 
434     PJ_ASSERT_RETURN(mod_ua.endpt, 0);
435 
436     pj_mutex_lock(mod_ua.mutex);
437     count = pj_hash_count(mod_ua.dlg_table);
438     pj_mutex_unlock(mod_ua.mutex);
439 
440     return count;
441 }
442 
443 
444 /*
445  * Find a dialog.
446  */
pjsip_ua_find_dialog(const pj_str_t * call_id,const pj_str_t * local_tag,const pj_str_t * remote_tag,pj_bool_t lock_dialog)447 PJ_DEF(pjsip_dialog*) pjsip_ua_find_dialog(const pj_str_t *call_id,
448 					   const pj_str_t *local_tag,
449 					   const pj_str_t *remote_tag,
450 					   pj_bool_t lock_dialog)
451 {
452     struct dlg_set *dlg_set;
453     pjsip_dialog *dlg;
454 
455     PJ_ASSERT_RETURN(call_id && local_tag && remote_tag, NULL);
456 
457     /* Lock user agent. */
458     pj_mutex_lock(mod_ua.mutex);
459 
460     /* Lookup the dialog set. */
461     dlg_set = (struct dlg_set*)
462     	      pj_hash_get_lower(mod_ua.dlg_table, local_tag->ptr,
463                                 (unsigned)local_tag->slen, NULL);
464     if (dlg_set == NULL) {
465 	/* Not found */
466 	pj_mutex_unlock(mod_ua.mutex);
467 	return NULL;
468     }
469 
470     /* Dialog set is found, now find the matching dialog based on the
471      * remote tag.
472      */
473     dlg = dlg_set->dlg_list.next;
474     while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {
475 	if (pj_stricmp(&dlg->remote.info->tag, remote_tag) == 0)
476 	    break;
477 	dlg = dlg->next;
478     }
479 
480     if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {
481 	/* Not found */
482 	pj_mutex_unlock(mod_ua.mutex);
483 	return NULL;
484     }
485 
486     /* Dialog has been found. It SHOULD have the right Call-ID!! */
487     if (pj_strcmp(&dlg->call_id->id, call_id)!=0) {
488 
489 	PJ_LOG(6, (THIS_FILE, "Dialog not found: local and remote tags "
490 		              "matched but not call id"));
491 
492         pj_mutex_unlock(mod_ua.mutex);
493         return NULL;
494     }
495 
496     if (lock_dialog) {
497 	if (pjsip_dlg_try_inc_lock(dlg) != PJ_SUCCESS) {
498 
499 	    /*
500 	     * Unable to acquire dialog's lock while holding the user
501 	     * agent's mutex. Release the UA mutex before retrying once
502 	     * more.
503 	     *
504 	     * THIS MAY CAUSE RACE CONDITION!
505 	     */
506 
507 	    /* Unlock user agent. */
508 	    pj_mutex_unlock(mod_ua.mutex);
509 	    /* Lock dialog */
510 	    pjsip_dlg_inc_lock(dlg);
511 
512 	} else {
513 	    /* Unlock user agent. */
514 	    pj_mutex_unlock(mod_ua.mutex);
515 	}
516 
517     } else {
518 	/* Unlock user agent. */
519 	pj_mutex_unlock(mod_ua.mutex);
520     }
521 
522     return dlg;
523 }
524 
525 
526 /*
527  * Find the first dialog in dialog set in hash table for an incoming message.
528  */
find_dlg_set_for_msg(pjsip_rx_data * rdata)529 static struct dlg_set *find_dlg_set_for_msg( pjsip_rx_data *rdata )
530 {
531     /* CANCEL message doesn't have To tag, so we must lookup the dialog
532      * by finding the INVITE UAS transaction being cancelled.
533      */
534     if (rdata->msg_info.cseq->method.id == PJSIP_CANCEL_METHOD) {
535 
536 	pjsip_dialog *dlg;
537 
538 	/* Create key for the rdata, but this time, use INVITE as the
539 	 * method.
540 	 */
541 	pj_str_t key;
542 	pjsip_role_e role;
543 	pjsip_transaction *tsx;
544 
545 	if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG)
546 	    role = PJSIP_ROLE_UAS;
547 	else
548 	    role = PJSIP_ROLE_UAC;
549 
550 	pjsip_tsx_create_key(rdata->tp_info.pool, &key, role,
551 			     pjsip_get_invite_method(), rdata);
552 
553 	/* Lookup the INVITE transaction */
554 	tsx = pjsip_tsx_layer_find_tsx2(&key, PJ_TRUE);
555 
556 	/* We should find the dialog attached to the INVITE transaction */
557 	if (tsx) {
558 	    dlg = (pjsip_dialog*) tsx->mod_data[mod_ua.mod.id];
559 	    pj_grp_lock_dec_ref(tsx->grp_lock);
560 
561 	    /* Dlg may be NULL on some extreme condition
562 	     * (e.g. during debugging where initially there is a dialog)
563 	     */
564 	    return dlg ? (struct dlg_set*) dlg->dlg_set : NULL;
565 
566 	} else {
567 	    return NULL;
568 	}
569 
570 
571     } else {
572 	pj_str_t *tag;
573 	struct dlg_set *dlg_set;
574 
575 	if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG)
576 	    tag = &rdata->msg_info.to->tag;
577 	else
578 	    tag = &rdata->msg_info.from->tag;
579 
580 	/* Lookup the dialog set. */
581 	dlg_set = (struct dlg_set*)
582 		  pj_hash_get_lower(mod_ua.dlg_table, tag->ptr,
583 				    (unsigned)tag->slen, NULL);
584 	return dlg_set;
585     }
586 }
587 
588 /* On received requests. */
mod_ua_on_rx_request(pjsip_rx_data * rdata)589 static pj_bool_t mod_ua_on_rx_request(pjsip_rx_data *rdata)
590 {
591     struct dlg_set *dlg_set;
592     pj_str_t *from_tag;
593     pjsip_dialog *dlg;
594     pj_status_t status;
595 
596     /* Optimized path: bail out early if request is not CANCEL and it doesn't
597      * have To tag
598      */
599     if (rdata->msg_info.to->tag.slen == 0 &&
600 	rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)
601     {
602 	return PJ_FALSE;
603     }
604 
605     /* Incoming REGISTER may have tags in it */
606     if (rdata->msg_info.msg->line.req.method.id == PJSIP_REGISTER_METHOD)
607 	return PJ_FALSE;
608 
609 retry_on_deadlock:
610 
611     /* Lock user agent before looking up the dialog hash table. */
612     pj_mutex_lock(mod_ua.mutex);
613 
614     /* Lookup the dialog set, based on the To tag header. */
615     dlg_set = find_dlg_set_for_msg(rdata);
616 
617     /* If dialog is not found, respond with 481 (Call/Transaction
618      * Does Not Exist).
619      */
620     if (dlg_set == NULL) {
621 	/* Unable to find dialog. */
622 	pj_mutex_unlock(mod_ua.mutex);
623 
624 	if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
625 	    PJ_LOG(5,(THIS_FILE,
626 		      "Unable to find dialogset for %s, answering with 481",
627 		      pjsip_rx_data_get_info(rdata)));
628 
629 	    /* Respond with 481 . */
630 	    pjsip_endpt_respond_stateless( mod_ua.endpt, rdata, 481, NULL,
631 					   NULL, NULL );
632 	}
633 	return PJ_TRUE;
634     }
635 
636     /* Dialog set has been found.
637      * Find the dialog in the dialog set based on the content of the remote
638      * tag.
639      */
640     from_tag = &rdata->msg_info.from->tag;
641     dlg = dlg_set->dlg_list.next;
642     while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {
643 
644 	if (pj_stricmp(&dlg->remote.info->tag, from_tag) == 0)
645 	    break;
646 
647 	dlg = dlg->next;
648     }
649 
650     /* Dialog may not be found, e.g. in this case:
651      *	- UAC sends SUBSCRIBE, then UAS sends NOTIFY before answering
652      *    SUBSCRIBE request with 2xx.
653      *
654      * In this case, we can accept the request ONLY when the original
655      * dialog still has empty To tag.
656      */
657     if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {
658 
659 	pjsip_dialog *first_dlg = dlg_set->dlg_list.next;
660 
661 	if (first_dlg->remote.info->tag.slen != 0) {
662 	    /* Not found. Mulfunction UAC? */
663 	    pj_mutex_unlock(mod_ua.mutex);
664 
665 	    if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
666 		PJ_LOG(5,(THIS_FILE,
667 		          "Unable to find dialog for %s, answering with 481",
668 		          pjsip_rx_data_get_info(rdata)));
669 
670 		pjsip_endpt_respond_stateless(mod_ua.endpt, rdata,
671 					      PJSIP_SC_CALL_TSX_DOES_NOT_EXIST,
672 					      NULL, NULL, NULL);
673 	    } else {
674 		PJ_LOG(5,(THIS_FILE,
675 		          "Unable to find dialog for %s",
676 		          pjsip_rx_data_get_info(rdata)));
677 	    }
678 	    return PJ_TRUE;
679 	}
680 
681 	dlg = first_dlg;
682     }
683 
684     /* Mark the dialog id of the request. */
685     rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg;
686 
687     /* Try to lock the dialog */
688     PJ_LOG(6,(dlg->obj_name, "UA layer acquiring dialog lock for request"));
689     status = pjsip_dlg_try_inc_lock(dlg);
690     if (status != PJ_SUCCESS) {
691 	/* Failed to acquire dialog mutex immediately, this could be
692 	 * because of deadlock. Release UA mutex, yield, and retry
693 	 * the whole thing once again.
694 	 */
695 	pj_mutex_unlock(mod_ua.mutex);
696 	pj_thread_sleep(0);
697 	goto retry_on_deadlock;
698     }
699 
700     /* Done with processing in UA layer, release lock */
701     pj_mutex_unlock(mod_ua.mutex);
702 
703     /* Pass to dialog. */
704     pjsip_dlg_on_rx_request(dlg, rdata);
705 
706     /* Unlock the dialog. This may destroy the dialog */
707     pjsip_dlg_dec_lock(dlg);
708 
709     /* Report as handled. */
710     return PJ_TRUE;
711 }
712 
713 
714 /* On rx response notification.
715  */
mod_ua_on_rx_response(pjsip_rx_data * rdata)716 static pj_bool_t mod_ua_on_rx_response(pjsip_rx_data *rdata)
717 {
718     pjsip_transaction *tsx;
719     struct dlg_set *dlg_set;
720     pjsip_dialog *dlg;
721     pj_status_t status;
722 
723     /*
724      * Find the dialog instance for the response.
725      * All outgoing dialog requests are sent statefully, which means
726      * there will be an UAC transaction associated with this response,
727      * and the dialog instance will be recorded in that transaction.
728      *
729      * But even when transaction is found, there is possibility that
730      * the response is a forked response.
731      */
732 
733 retry_on_deadlock:
734 
735     dlg = NULL;
736 
737     /* Lock user agent dlg table before we're doing anything. */
738     pj_mutex_lock(mod_ua.mutex);
739 
740     /* Check if transaction is present. */
741     tsx = pjsip_rdata_get_tsx(rdata);
742     if (tsx) {
743 	/* Check if dialog is present in the transaction. */
744 	dlg = pjsip_tsx_get_dlg(tsx);
745 	if (!dlg) {
746 	    /* Unlock dialog hash table. */
747 	    pj_mutex_unlock(mod_ua.mutex);
748 	    return PJ_FALSE;
749 	}
750 
751 	/* Get the dialog set. */
752 	dlg_set = (struct dlg_set*) dlg->dlg_set;
753 
754 	/* Even if transaction is found and (candidate) dialog has been
755 	 * identified, it's possible that the request has forked.
756 	 */
757 
758     } else {
759 	/* Transaction is not present.
760 	 * Check if this is a 2xx/OK response to INVITE, which in this
761 	 * case the response will be handled directly by the
762 	 * dialog.
763 	 */
764 	pjsip_cseq_hdr *cseq_hdr = rdata->msg_info.cseq;
765 
766 	if (cseq_hdr->method.id != PJSIP_INVITE_METHOD ||
767 	    rdata->msg_info.msg->line.status.code / 100 != 2)
768 	{
769 	    /* Not a 2xx response to INVITE.
770 	     * This must be some stateless response sent by other modules,
771 	     * or a very late response.
772 	     */
773 	    /* Unlock dialog hash table. */
774 	    pj_mutex_unlock(mod_ua.mutex);
775 	    return PJ_FALSE;
776 	}
777 
778 
779 	/* Get the dialog set. */
780 	dlg_set = (struct dlg_set*)
781 		  pj_hash_get_lower(mod_ua.dlg_table,
782 			            rdata->msg_info.from->tag.ptr,
783 			            (unsigned)rdata->msg_info.from->tag.slen,
784 			            NULL);
785 
786 	if (!dlg_set) {
787 	    /* Unlock dialog hash table. */
788 	    pj_mutex_unlock(mod_ua.mutex);
789 
790 	    /* Strayed 2xx response!! */
791 	    PJ_LOG(4,(THIS_FILE,
792 		      "Received strayed 2xx response (no dialog is found)"
793 		      " from %s:%d: %s",
794 		      rdata->pkt_info.src_name, rdata->pkt_info.src_port,
795 		      pjsip_rx_data_get_info(rdata)));
796 
797 	    return PJ_TRUE;
798 	}
799     }
800 
801     /* At this point, we must have the dialog set, and the dialog set
802      * must have a dialog in the list.
803      */
804     pj_assert(dlg_set && !pj_list_empty(&dlg_set->dlg_list));
805 
806     /* Check for forked response.
807      * Request will fork only for the initial INVITE request.
808      */
809 
810     //This doesn't work when there is authentication challenge, since
811     //first_cseq evaluation will yield false.
812     //if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD &&
813     //	rdata->msg_info.cseq->cseq == dlg_set->dlg_list.next->local.first_cseq)
814 
815     if (rdata->msg_info.cseq->method.id == PJSIP_INVITE_METHOD) {
816 
817 	int st_code = rdata->msg_info.msg->line.status.code;
818 	pj_str_t *to_tag = &rdata->msg_info.to->tag;
819 
820 	dlg = dlg_set->dlg_list.next;
821 
822 	while (dlg != (pjsip_dialog*)&dlg_set->dlg_list) {
823 
824 	    /* If there is dialog with no remote tag (i.e. dialog has not
825 	     * been established yet), then send this response to that
826 	     * dialog.
827 	     */
828 	    if (dlg->remote.info->tag.slen == 0)
829 		break;
830 
831 	    /* Otherwise find the one with matching To tag. */
832 	    if (pj_stricmp(to_tag, &dlg->remote.info->tag) == 0)
833 		break;
834 
835 	    dlg = dlg->next;
836 	}
837 
838 	/* If no dialog with matching remote tag is found, this must be
839 	 * a forked response. Respond to this ONLY when response is non-100
840 	 * provisional response OR a 2xx response.
841 	 */
842 	if (dlg == (pjsip_dialog*)&dlg_set->dlg_list &&
843 	    ((st_code/100==1 && st_code!=100) || st_code/100==2))
844 	{
845 
846 	    PJ_LOG(5,(THIS_FILE,
847 		      "Received forked %s for existing dialog %s",
848 		      pjsip_rx_data_get_info(rdata),
849 		      dlg_set->dlg_list.next->obj_name));
850 
851 	    /* Report to application about forked condition.
852 	     * Application can either create a dialog or ignore the response.
853 	     */
854 	    if (mod_ua.param.on_dlg_forked) {
855 		dlg = (*mod_ua.param.on_dlg_forked)(dlg_set->dlg_list.next,
856 						    rdata);
857 		if (dlg == NULL) {
858 		    pj_mutex_unlock(mod_ua.mutex);
859 		    return PJ_TRUE;
860 		}
861 	    } else {
862 		dlg = dlg_set->dlg_list.next;
863 
864 		PJ_LOG(4,(THIS_FILE,
865 			  "Unhandled forked %s from %s:%d, response will be "
866 			  "handed over to the first dialog",
867 			  pjsip_rx_data_get_info(rdata),
868 			  rdata->pkt_info.src_name, rdata->pkt_info.src_port));
869 	    }
870 
871 	} else if (dlg == (pjsip_dialog*)&dlg_set->dlg_list) {
872 
873 	    /* For 100 or non-2xx response which has different To tag,
874 	     * pass the response to the first dialog.
875 	     */
876 
877 	    dlg = dlg_set->dlg_list.next;
878 
879 	}
880 
881     } else {
882 	/* Either this is a non-INVITE response, or subsequent INVITE
883 	 * within dialog. The dialog should have been identified when
884 	 * the transaction was found.
885 	 */
886 	pj_assert(tsx != NULL);
887 	pj_assert(dlg != NULL);
888     }
889 
890     /* The dialog must have been found. */
891     pj_assert(dlg != NULL);
892 
893     /* Put the dialog instance in the rdata. */
894     rdata->endpt_info.mod_data[mod_ua.mod.id] = dlg;
895 
896     /* Attempt to acquire lock to the dialog. */
897     PJ_LOG(6,(dlg->obj_name, "UA layer acquiring dialog lock for response"));
898     status = pjsip_dlg_try_inc_lock(dlg);
899     if (status != PJ_SUCCESS) {
900 	/* Failed to acquire dialog mutex. This could indicate a deadlock
901 	 * situation, and for safety, try to avoid deadlock by releasing
902 	 * UA mutex, yield, and retry the whole processing once again.
903 	 */
904 	pj_mutex_unlock(mod_ua.mutex);
905 	pj_thread_sleep(0);
906 	goto retry_on_deadlock;
907     }
908 
909     /* We're done with processing in the UA layer, we can release the mutex */
910     pj_mutex_unlock(mod_ua.mutex);
911 
912     /* Pass the response to the dialog. */
913     pjsip_dlg_on_rx_response(dlg, rdata);
914 
915     /* Unlock the dialog. This may destroy the dialog. */
916     pjsip_dlg_dec_lock(dlg);
917 
918     /* Done. */
919     return PJ_TRUE;
920 }
921 
922 
923 #if PJ_LOG_MAX_LEVEL >= 3
print_dialog(const char * title,pjsip_dialog * dlg,char * buf,pj_size_t size)924 static void print_dialog( const char *title,
925 			  pjsip_dialog *dlg, char *buf, pj_size_t size)
926 {
927     int len;
928     char userinfo[PJSIP_MAX_URL_SIZE];
929 
930     len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
931     if (len < 0)
932 	pj_ansi_strcpy(userinfo, "<--uri too long-->");
933     else
934 	userinfo[len] = '\0';
935 
936     len = pj_ansi_snprintf(buf, size, "%s[%s]  %s",
937 			   title,
938 			   (dlg->state==PJSIP_DIALOG_STATE_NULL ? " - " :
939 							     "est"),
940 		      userinfo);
941     if (len < 1 || len >= (int)size) {
942 	pj_ansi_strcpy(buf, "<--uri too long-->");
943     } else
944 	buf[len] = '\0';
945 }
946 #endif
947 
948 /*
949  * Dump user agent contents (e.g. all dialogs).
950  */
pjsip_ua_dump(pj_bool_t detail)951 PJ_DEF(void) pjsip_ua_dump(pj_bool_t detail)
952 {
953 #if PJ_LOG_MAX_LEVEL >= 3
954     pj_hash_iterator_t itbuf, *it;
955     char dlginfo[128];
956 
957     pj_mutex_lock(mod_ua.mutex);
958 
959     PJ_LOG(3, (THIS_FILE, "Number of dialog sets: %u",
960 			  pj_hash_count(mod_ua.dlg_table)));
961 
962     if (detail && pj_hash_count(mod_ua.dlg_table)) {
963 	PJ_LOG(3, (THIS_FILE, "Dumping dialog sets:"));
964 	it = pj_hash_first(mod_ua.dlg_table, &itbuf);
965 	for (; it != NULL; it = pj_hash_next(mod_ua.dlg_table, it))  {
966 	    struct dlg_set *dlg_set;
967 	    pjsip_dialog *dlg;
968 	    const char *title;
969 
970 	    dlg_set = (struct dlg_set*) pj_hash_this(mod_ua.dlg_table, it);
971 	    if (!dlg_set || pj_list_empty(&dlg_set->dlg_list)) continue;
972 
973 	    /* First dialog in dialog set. */
974 	    dlg = dlg_set->dlg_list.next;
975 	    if (dlg->role == PJSIP_ROLE_UAC)
976 		title = "  [out] ";
977 	    else
978 		title = "  [in]  ";
979 
980 	    print_dialog(title, dlg, dlginfo, sizeof(dlginfo));
981 	    PJ_LOG(3,(THIS_FILE, "%s", dlginfo));
982 
983 	    /* Next dialog in dialog set (forked) */
984 	    dlg = dlg->next;
985 	    while (dlg != (pjsip_dialog*) &dlg_set->dlg_list) {
986 		print_dialog("    [forked] ", dlg, dlginfo, sizeof(dlginfo));
987 		dlg = dlg->next;
988 	    }
989 	}
990     }
991 
992     pj_mutex_unlock(mod_ua.mutex);
993 #endif
994 }
995 
996