4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
38 #include "sip_miscdefs.h"
40 #include "sip_dialog.h"
41 #include "sip_parse_generic.h"
43 #define SIP_DLG_XCHG_FROM 0
44 #define SIP_DLG_XCHG_TO 1
47 * Dialog state change callback function
49 void (*sip_dlg_ulp_state_cb
)(sip_dialog_t
, sip_msg_t
, int, int) = NULL
;
50 void (*sip_ulp_dlg_del_cb
)(sip_dialog_t
, sip_msg_t
, void *) = NULL
;
52 boolean_t
sip_incomplete_dialog(sip_dialog_t
);
55 * Exchange From/To header
57 _sip_header_t
*sip_dlg_xchg_from_to(sip_msg_t
, int);
60 * Complete dialog hash table
62 sip_hash_t sip_dialog_hash
[SIP_HASH_SZ
];
65 * Partial dialog hash table
67 sip_hash_t sip_dialog_phash
[SIP_HASH_SZ
];
72 typedef struct sip_dlg_route_set_s
{
74 sip_str_t sip_dlg_ruri
;
75 boolean_t sip_dlg_route_lr
;
76 struct sip_dlg_route_set_s
*sip_dlg_route_next
;
79 sip_dialog_t
sip_seed_dialog(sip_conn_object_t
, _sip_msg_t
*,
81 sip_dialog_t
sip_complete_dialog(_sip_msg_t
*, _sip_dialog_t
*);
82 int sip_dialog_process(_sip_msg_t
*, sip_dialog_t
*);
83 void sip_dialog_delete(_sip_dialog_t
*);
84 void sip_dialog_init();
85 sip_dialog_t
sip_dialog_find(_sip_msg_t
*);
86 boolean_t
sip_dialog_match(void *, void *);
87 boolean_t
sip_dialog_free(void *, void *, int *);
88 sip_dialog_t
sip_update_dialog(sip_dialog_t
, _sip_msg_t
*);
89 char *sip_dialog_req_uri(sip_dialog_t
);
91 static void sip_release_dialog_res(_sip_dialog_t
*);
92 void sip_dlg_self_destruct(void *);
93 static int sip_dialog_get_route_set(_sip_dialog_t
*, _sip_msg_t
*,
95 static void sip_dialog_free_rset(sip_dlg_route_set_t
*);
98 * Timer object for partial dialogs
100 typedef struct sip_dialog_timer_obj_s
{
101 _sip_dialog_t
*dialog
;
102 void (*func
)(sip_dialog_t
, sip_msg_t
, void *);
103 } sip_dialog_timer_obj_t
;
106 * To avoid duplication all over the place
109 sip_release_dialog_res(_sip_dialog_t
*dialog
)
112 sip_msg_chain_t
*msg_chain
;
113 sip_msg_chain_t
*nmsg_chain
;
115 if (dialog
->sip_dlg_ref_cnt
!= 0) {
116 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
117 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
119 assert(dialog
->sip_dlg_ref_cnt
== 0);
120 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
121 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
122 if (dialog
->sip_dlg_call_id
!= NULL
)
123 sip_free_header(dialog
->sip_dlg_call_id
);
124 if (dialog
->sip_dlg_local_uri_tag
!= NULL
)
125 sip_free_header(dialog
->sip_dlg_local_uri_tag
);
126 if (dialog
->sip_dlg_remote_uri_tag
!= NULL
)
127 sip_free_header(dialog
->sip_dlg_remote_uri_tag
);
128 if (dialog
->sip_dlg_remote_target
!= NULL
)
129 sip_free_header(dialog
->sip_dlg_remote_target
);
130 if (dialog
->sip_dlg_local_contact
!= NULL
)
131 sip_free_header(dialog
->sip_dlg_local_contact
);
132 if (dialog
->sip_dlg_new_local_contact
!= NULL
)
133 sip_free_header(dialog
->sip_dlg_new_local_contact
);
134 if (dialog
->sip_dlg_route_set
!= NULL
)
135 sip_free_header(dialog
->sip_dlg_route_set
);
136 if (dialog
->sip_dlg_event
!= NULL
)
137 sip_free_header(dialog
->sip_dlg_event
);
138 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
139 free(dialog
->sip_dlg_req_uri
.sip_str_ptr
);
140 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
141 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
143 if (dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
) {
144 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
145 dialog
->sip_dlg_rset
.sip_str_len
= 0;
146 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
148 for (count
= 0; count
<= SIP_DLG_DESTROYED
; count
++) {
149 msg_chain
= dialog
->sip_dlg_log
[count
].sip_msgs
;
150 while (msg_chain
!= NULL
) {
151 nmsg_chain
= msg_chain
->next
;
152 if (msg_chain
->sip_msg
!= NULL
)
153 free(msg_chain
->sip_msg
);
155 msg_chain
= nmsg_chain
;
158 (void) pthread_mutex_destroy(&dialog
->sip_dlg_mutex
);
163 * Get the route information from the 'value' and add it to the route
166 static sip_dlg_route_set_t
*
167 sip_add_route_to_set(sip_hdr_value_t
*value
)
170 sip_dlg_route_set_t
*rset
;
172 const sip_param_t
*uri_param
;
175 rset
= calloc(1, sizeof (*rset
));
178 rset
->sip_dlg_route_next
= NULL
;
179 vlen
= value
->sip_value_end
- value
->sip_value_start
;
184 crlf
= value
->sip_value_end
- strlen(SIP_CRLF
);
185 while (crlf
!= NULL
&& strncmp(crlf
, SIP_CRLF
, strlen(SIP_CRLF
)) == 0) {
186 vlen
-= strlen(SIP_CRLF
);
187 crlf
-= strlen(SIP_CRLF
);
189 rset
->sip_dlg_route
= calloc(1, vlen
+ 1);
190 if (rset
->sip_dlg_route
== NULL
) {
197 rset
->sip_dlg_route_lr
= B_FALSE
;
198 (void) strncpy(rset
->sip_dlg_route
, value
->sip_value_start
, vlen
);
199 rset
->sip_dlg_ruri
.sip_str_ptr
= rset
->sip_dlg_route
+
200 (value
->cftr_uri
.sip_str_ptr
- value
->sip_value_start
);
201 rset
->sip_dlg_ruri
.sip_str_len
= value
->cftr_uri
.sip_str_len
;
202 rset
->sip_dlg_route
[vlen
] = '\0';
204 assert(value
->sip_value_parsed_uri
!= NULL
);
206 * Check if the 'lr' param is present for this route.
208 uri_param
= sip_get_uri_params(value
->sip_value_parsed_uri
, &error
);
210 free(rset
->sip_dlg_route
);
214 if (uri_param
!= NULL
) {
215 rset
->sip_dlg_route_lr
= sip_is_param_present(uri_param
, "lr",
222 * Depending on the route-set, determine the request URI.
225 sip_dialog_req_uri(sip_dialog_t dialog
)
227 const sip_str_t
*req_uri
;
229 _sip_dialog_t
*_dialog
;
231 _dialog
= (_sip_dialog_t
*)dialog
;
232 if (_dialog
->sip_dlg_route_set
== NULL
||
233 _dialog
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
234 const struct sip_value
*val
;
236 val
= sip_get_header_value(_dialog
->sip_dlg_remote_target
,
240 req_uri
= &((sip_hdr_value_t
*)val
)->cftr_uri
;
242 req_uri
= &_dialog
->sip_dlg_req_uri
;
244 uri
= (char *)malloc(req_uri
->sip_str_len
+ 1);
247 (void) strncpy(uri
, req_uri
->sip_str_ptr
, req_uri
->sip_str_len
);
248 uri
[req_uri
->sip_str_len
] = '\0';
254 * Free the route set.
257 sip_dialog_free_rset(sip_dlg_route_set_t
*rset
)
259 sip_dlg_route_set_t
*next
;
261 while (rset
!= NULL
) {
262 next
= rset
->sip_dlg_route_next
;
263 rset
->sip_dlg_route_next
= NULL
;
264 free(rset
->sip_dlg_route
);
271 * Recompute route-set
274 sip_dlg_recompute_rset(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
, int what
)
278 if (dialog
->sip_dlg_route_set
!= NULL
) {
279 sip_free_header(dialog
->sip_dlg_route_set
);
280 dialog
->sip_dlg_route_set
= NULL
;
282 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
283 free(dialog
->sip_dlg_req_uri
.sip_str_ptr
);
284 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
285 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
287 if (dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
) {
288 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
289 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
290 dialog
->sip_dlg_rset
.sip_str_len
= 0;
292 ret
= sip_dialog_get_route_set(dialog
, sip_msg
, what
);
297 * If the route set is empty, the UAC MUST place the remote target URI
298 * into the Request-URI. The UAC MUST NOT add a Route header field to
301 * If the route set is not empty, and the first URI in the route set
302 * contains the lr parameter (see Section 19.1.1), the UAC MUST place
303 * the remote target URI into the Request-URI and MUST include a Route
304 * header field containing the route set values in order, including all
307 * If the route set is not empty, and its first URI does not contain the
308 * lr parameter, the UAC MUST place the first URI from the route set
309 * into the Request-URI, stripping any parameters that are not allowed
310 * in a Request-URI. The UAC MUST add a Route header field containing
311 * the remainder of the route set values in order, including all
312 * parameters. The UAC MUST then place the remote target URI into the
313 * Route header field as the last value.
316 sip_dialog_set_route_hdr(_sip_dialog_t
*dialog
, sip_dlg_route_set_t
*rset_head
,
325 sip_dlg_route_set_t
*route
;
326 boolean_t first
= B_TRUE
;
327 const sip_str_t
*to_uri
;
333 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
334 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
338 dialog
->sip_dlg_rset
.sip_str_len
= rlen
+ rcnt
- 1;
339 dialog
->sip_dlg_rset
.sip_str_ptr
= malloc(rlen
+ rcnt
);
340 if (dialog
->sip_dlg_rset
.sip_str_ptr
== NULL
)
342 rsp
= dialog
->sip_dlg_rset
.sip_str_ptr
;
346 if (!route
->sip_dlg_route_lr
) {
347 const struct sip_value
*val
;
349 val
= sip_get_header_value(dialog
->sip_dlg_remote_target
, NULL
);
350 to_uri
= &((sip_hdr_value_t
*)val
)->cftr_uri
;
351 uri
= (char *)malloc(to_uri
->sip_str_len
+ 1);
353 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
354 dialog
->sip_dlg_rset
.sip_str_len
= 0;
355 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
358 (void) strncpy(uri
, to_uri
->sip_str_ptr
, to_uri
->sip_str_len
);
359 uri
[to_uri
->sip_str_len
] = '\0';
360 rset_len
= rlen
- strlen(route
->sip_dlg_route
) + strlen(uri
) +
361 SIP_SPACE_LEN
+ sizeof (char) + SIP_SPACE_LEN
+
363 count
= snprintf(rsp
, rspl
, "%s", route
->sip_dlg_route
);
364 dialog
->sip_dlg_req_uri
.sip_str_ptr
= malloc(
365 route
->sip_dlg_ruri
.sip_str_len
+ 1);
366 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
368 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
369 dialog
->sip_dlg_rset
.sip_str_len
= 0;
370 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
373 (void) strncpy(dialog
->sip_dlg_req_uri
.sip_str_ptr
, rsp
+
374 (route
->sip_dlg_ruri
.sip_str_ptr
- route
->sip_dlg_route
),
375 route
->sip_dlg_ruri
.sip_str_len
);
376 dialog
->sip_dlg_req_uri
.sip_str_ptr
[
377 route
->sip_dlg_ruri
.sip_str_len
] = '\0';
378 dialog
->sip_dlg_req_uri
.sip_str_len
=
379 route
->sip_dlg_ruri
.sip_str_len
;
383 route
= route
->sip_dlg_route_next
;
387 * rcnt - 1 is for the number of COMMAs
389 rset_len
+= strlen(SIP_ROUTE
) + SIP_SPACE_LEN
+ sizeof (char) +
390 SIP_SPACE_LEN
+ rcnt
- 1;
391 rset
= malloc(rset_len
+ 1);
393 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
394 dialog
->sip_dlg_rset
.sip_str_len
= 0;
395 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
398 rhdr
= sip_new_header(rset_len
+ strlen(SIP_CRLF
));
401 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
402 dialog
->sip_dlg_rset
.sip_str_len
= 0;
403 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
409 count
= snprintf(rp
, rpl
, "%s %c ", SIP_ROUTE
, SIP_HCOLON
);
413 while (route
!= NULL
) {
415 count
= snprintf(rp
, rpl
, "%s", route
->sip_dlg_route
);
420 count
= snprintf(rsp
, rspl
, "%c%s",
421 SIP_COMMA
, route
->sip_dlg_route
);
423 count
= snprintf(rsp
, rspl
, "%s",
424 route
->sip_dlg_route
);
429 count
= snprintf(rp
, rpl
, "%c%s", SIP_COMMA
,
430 route
->sip_dlg_route
);
433 count
= snprintf(rsp
, rspl
, "%c%s", SIP_COMMA
,
434 route
->sip_dlg_route
);
438 route
= route
->sip_dlg_route_next
;
440 if (rsp
> dialog
->sip_dlg_rset
.sip_str_ptr
+
441 dialog
->sip_dlg_rset
.sip_str_len
) {
442 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
443 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
445 assert(rsp
<= dialog
->sip_dlg_rset
.sip_str_ptr
+
446 dialog
->sip_dlg_rset
.sip_str_len
);
447 dialog
->sip_dlg_rset
.sip_str_ptr
[dialog
->sip_dlg_rset
.sip_str_len
] =
451 count
= snprintf(rp
, rpl
, "%c %s %c", SIP_LAQUOT
,
454 count
= snprintf(rp
, rpl
, "%c%c %s %c", SIP_COMMA
,
455 SIP_LAQUOT
, uri
, SIP_RAQUOT
);
461 if (rp
> rset
+ rset_len
) {
462 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
463 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
465 assert(rp
<= rset
+ rset_len
);
466 (void) snprintf(rhdr
->sip_hdr_start
, rset_len
+ strlen(SIP_CRLF
) + 1,
467 "%s%s", rset
, SIP_CRLF
);
469 dialog
->sip_dlg_route_set
= (sip_header_t
)rhdr
;
470 sip_dialog_free_rset(rset_head
);
476 * The route set MUST be set to the list of URIs in the Record-Route
477 * header field from the response, taken in reverse order and preserving
478 * all URI parameters.
481 * The route set MUST be set to the list of URIs in the Record-Route
482 * header field from the request, taken in order and preserving all URI
486 sip_dialog_get_route_set(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
, int what
)
489 sip_hdr_value_t
*value
;
491 sip_dlg_route_set_t
*rset_head
= NULL
;
492 sip_dlg_route_set_t
*rset_tail
= NULL
;
493 sip_dlg_route_set_t
*rset
;
497 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
498 rrhdr
= sip_search_for_header(sip_msg
, SIP_RECORD_ROUTE
, NULL
);
499 while (rrhdr
!= NULL
) {
500 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
501 value
= (sip_hdr_value_t
*)sip_get_header_value(rrhdr
, &error
);
502 while (value
!= NULL
&& error
== 0) {
505 if (value
->sip_value_state
== SIP_VALUE_BAD
) {
506 value
= (sip_hdr_value_t
*)sip_get_next_value(
507 (sip_header_value_t
)value
, &error
);
510 rset
= sip_add_route_to_set(value
);
517 rset_len
+= (value
->sip_value_end
-
518 value
->sip_value_start
);
522 crlf
= value
->sip_value_end
- strlen(SIP_CRLF
);
523 while (crlf
!= NULL
&&
524 strncmp(crlf
, SIP_CRLF
, strlen(SIP_CRLF
)) == 0) {
525 rset_len
-= strlen(SIP_CRLF
);
526 crlf
-= strlen(SIP_CRLF
);
528 if (rset_head
== NULL
) {
529 if (rset_tail
!= NULL
) {
530 sip_write_to_log((void *)dialog
,
531 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
534 assert(rset_tail
== NULL
);
535 rset_head
= rset_tail
= rset
;
536 } else if (what
== SIP_UAS_DIALOG
) {
537 rset_tail
->sip_dlg_route_next
= rset
;
539 } else if (what
== SIP_UAC_DIALOG
) {
540 rset
->sip_dlg_route_next
= rset_head
;
543 sip_write_to_log((void *)dialog
,
544 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
548 value
= (sip_hdr_value_t
*)sip_get_next_value(
549 (sip_header_value_t
)value
, &error
);
551 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
552 rrhdr
= sip_search_for_header(sip_msg
, SIP_RECORD_ROUTE
, rrhdr
);
554 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
557 if (sip_dialog_set_route_hdr(dialog
, rset_head
, rset_cnt
,
563 sip_dialog_free_rset(rset_head
);
569 * The remote sequence number MUST be set to the value of the sequence
570 * number in the CSeq header field of the request. The local sequence
571 * number MUST be empty. The call identifier component of the dialog ID
572 * MUST be set to the value of the Call-ID in the request. The local
573 * tag component of the dialog ID MUST be set to the tag in the To field
574 * in the response to the request (which always includes a tag), and the
575 * remote tag component of the dialog ID MUST be set to the tag from the
576 * From field in the request. A UAS MUST be prepared to receive a
577 * request without a tag in the From field, in which case the tag is
578 * considered to have a value of null.
579 * The remote URI MUST be set to the URI in the From field, and the
580 * local URI MUST be set to the URI in the To field.
581 * The remote target MUST be set to the URI from the Contact header field
585 * The local sequence number MUST be set to the value of the sequence
586 * number in the CSeq header field of the request. The remote sequence
587 * number MUST be empty (it is established when the remote UA sends a
588 * request within the dialog). The call identifier component of the
589 * dialog ID MUST be set to the value of the Call-ID in the request.
590 * The local tag component of the dialog ID MUST be set to the tag in
591 * the From field in the request, and the remote tag component of the
592 * dialog ID MUST be set to the tag in the To field of the response. A
593 * UAC MUST be prepared to receive a response without a tag in the To
594 * field, in which case the tag is considered to have a value of null.
595 * The remote URI MUST be set to the URI in the To field, and the local
596 * URI MUST be set to the URI in the From field.
597 * The remote target MUST be set to the URI from the Contact header field
603 * This is the routine that seeds a dialog.
606 sip_seed_dialog(sip_conn_object_t obj
, _sip_msg_t
*sip_msg
,
607 boolean_t dlg_on_fork
, int dlg_type
)
609 _sip_dialog_t
*dialog
;
611 sip_header_t fhdr
= NULL
;
612 sip_header_t thdr
= NULL
;
615 sip_header_t evhdr
= NULL
;
616 const struct sip_value
*value
;
617 sip_dialog_timer_obj_t
*tim_obj
= NULL
;
618 const sip_str_t
*callid
;
620 int timer1
= sip_timer_T1
;
623 if (!sip_msg_is_request((sip_msg_t
)sip_msg
, &error
))
626 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
628 * Only INVITE and SUBSCRIBE supported
630 if (error
!= 0 || (method
!= INVITE
&& method
!= SUBSCRIBE
))
634 * A request outside of a dialog MUST NOT contain a To tag
636 if (sip_get_to_tag((sip_msg_t
)sip_msg
, NULL
) != NULL
)
639 if (dlg_type
== SIP_UAS_DIALOG
) {
640 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
642 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
644 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
645 fhdr
= sip_search_for_header(sip_msg
, SIP_FROM
, NULL
);
647 cihdr
= sip_search_for_header(sip_msg
, SIP_CALL_ID
, NULL
);
648 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
649 if (method
== SUBSCRIBE
)
650 evhdr
= sip_search_for_header(sip_msg
, SIP_EVENT
, NULL
);
651 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
652 if ((fhdr
== NULL
&& thdr
== NULL
) || cihdr
== NULL
|| chdr
== NULL
||
653 (method
== SUBSCRIBE
&& evhdr
== NULL
)) {
655 sip_free_header(thdr
);
660 * Sanity check since we just store the headers in the dialog
662 if (sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
) == NULL
||
663 sip_get_from_uri_str((sip_msg_t
)sip_msg
, NULL
) == NULL
||
664 ((cseq
= sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
)) == -1) ||
665 (callid
= sip_get_callid((sip_msg_t
)sip_msg
, NULL
)) == NULL
||
666 sip_get_to_uri_str((sip_msg_t
)sip_msg
, NULL
) == NULL
||
667 ((value
= sip_get_header_value(chdr
, NULL
)) == NULL
) ||
668 sip_get_contact_uri_str((sip_header_value_t
)value
, NULL
) == NULL
) {
670 sip_free_header(thdr
);
674 tim_obj
= calloc(1, sizeof (sip_dialog_timer_obj_t
));
675 if (tim_obj
== NULL
) {
677 sip_free_header(thdr
);
680 dialog
= calloc(1, sizeof (_sip_dialog_t
));
681 if (dialog
== NULL
) {
683 sip_free_header(thdr
);
687 * We will take the TO header with the tag when we complete this
690 if (dlg_type
== SIP_UAS_DIALOG
) {
691 dialog
->sip_dlg_remote_uri_tag
= thdr
;
693 * We take the remote target from the incoming request on the
694 * UAS. For the UAC, we will take it from the response.
696 if ((dialog
->sip_dlg_remote_target
= sip_dup_header(chdr
)) ==
701 if ((dialog
->sip_dlg_local_uri_tag
= sip_dup_header(fhdr
)) ==
706 * We take the local contact from the originating request on
707 * UAC. For the UAS, we will take it from the response.
709 if ((dialog
->sip_dlg_local_contact
= sip_dup_header(chdr
)) ==
713 dialog
->sip_dlg_new_local_contact
= NULL
;
716 if ((dialog
->sip_dlg_call_id
= sip_dup_header(cihdr
)) == NULL
)
718 if (method
== SUBSCRIBE
) {
719 dialog
->sip_dlg_event
= sip_dup_header(evhdr
);
720 if (dialog
->sip_dlg_event
== NULL
) {
724 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
725 dialog
->sip_dlg_rset
.sip_str_len
= 0;
726 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
727 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
729 * Get the route set from the request, if present
731 if (dlg_type
== SIP_UAS_DIALOG
&&
732 sip_dialog_get_route_set(dialog
, sip_msg
, dlg_type
) != 0) {
735 if (dlg_type
== SIP_UAC_DIALOG
)
736 dialog
->sip_dlg_local_cseq
= cseq
;
738 dialog
->sip_dlg_remote_cseq
= cseq
;
739 dialog
->sip_dlg_type
= dlg_type
;
740 dialog
->sip_dlg_on_fork
= dlg_on_fork
;
741 dialog
->sip_dlg_method
= method
;
743 * Set the partial dialog timer with the INVITE timeout val
745 if (sip_conn_timer1
!= NULL
)
746 timer1
= sip_conn_timer1(obj
);
747 SIP_INIT_TIMER(dialog
->sip_dlg_timer
, 64 * timer1
);
748 tim_obj
->dialog
= dialog
;
750 * Since at the client we never pass the partial dialog, we need not
751 * invoke the callback when the partial dialog self-destructs.
753 if (dlg_type
== SIP_UAS_DIALOG
)
754 tim_obj
->func
= sip_ulp_dlg_del_cb
;
755 SIP_SCHED_TIMER(dialog
->sip_dlg_timer
, (void *)tim_obj
,
756 sip_dlg_self_destruct
);
757 if (!SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
759 (void) pthread_mutex_init(&dialog
->sip_dlg_mutex
, NULL
);
761 if (dlg_type
== SIP_UAC_DIALOG
) {
762 const sip_str_t
*local_tag
;
764 local_tag
= sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
);
765 if (local_tag
== NULL
) {
766 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
767 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
769 assert(local_tag
!= NULL
);
770 sip_md5_hash(local_tag
->sip_str_ptr
, local_tag
->sip_str_len
,
771 callid
->sip_str_ptr
, callid
->sip_str_len
,
772 NULL
, 0, NULL
, 0, NULL
, 0, NULL
, 0,
773 (uchar_t
*)dialog
->sip_dlg_id
);
777 * Add it to the partial hash table
779 if (sip_hash_add(sip_dialog_phash
, (void *)dialog
,
780 SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
)) != 0) {
785 dialog
->sip_dlg_msgcnt
= 1;
786 sip_add_log(&dialog
->sip_dlg_log
[dialog
->sip_dlg_state
],
787 (sip_msg_t
)sip_msg
, dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
789 SIP_DLG_REFCNT_INCR(dialog
);
790 return ((sip_dialog_t
)dialog
);
792 sip_release_dialog_res(dialog
);
793 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
794 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
801 * When creating a dialog from a NOTIFY request, we need to get the FROM
802 * header for the dialog from the TO header of the NOTIFY.
805 sip_dlg_xchg_from_to(sip_msg_t sip_msg
, int what
)
808 _sip_header_t
*newhdr
;
810 const struct sip_header
*hdr
;
814 hdr
= sip_get_header(sip_msg
, what
== SIP_DLG_XCHG_FROM
? SIP_FROM
:
815 SIP_TO
, NULL
, &error
);
816 if (error
!= 0 || hdr
== NULL
)
818 if (sip_parse_goto_values((_sip_header_t
*)hdr
) != 0)
820 len
= hdr
->sip_hdr_end
- hdr
->sip_hdr_current
;
821 if (what
== SIP_DLG_XCHG_FROM
) {
822 hdrsize
= len
+ strlen(SIP_TO
) + SIP_SPACE_LEN
+ sizeof (char) +
825 hdrsize
= len
+ strlen(SIP_FROM
) + SIP_SPACE_LEN
+
826 sizeof (char) + SIP_SPACE_LEN
;
828 newhdr
= sip_new_header(hdrsize
);
831 if (what
== SIP_DLG_XCHG_FROM
) {
832 cnt
= snprintf(newhdr
->sip_hdr_current
, hdrsize
+ 1,
833 "%s %c ", SIP_TO
, SIP_HCOLON
);
835 cnt
= snprintf(newhdr
->sip_hdr_current
, hdrsize
+ 1,
836 "%s %c ", SIP_FROM
, SIP_HCOLON
);
838 newhdr
->sip_hdr_current
+= cnt
;
839 (void) strncpy(newhdr
->sip_hdr_current
, hdr
->sip_hdr_current
, len
);
840 newhdr
->sip_hdr_current
+= len
;
841 assert(newhdr
->sip_hdr_current
== newhdr
->sip_hdr_end
);
842 assert(hdr
->sip_header_functions
!= NULL
);
845 * FROM and TO have common parsing functions
847 newhdr
->sip_header_functions
= hdr
->sip_header_functions
;
848 newhdr
->sip_hdr_current
= newhdr
->sip_hdr_start
;
854 * This is the response that completes the dialog that was created
855 * in sip_seed_dialog().
858 sip_complete_dialog(_sip_msg_t
*sip_msg
, _sip_dialog_t
*dialog
)
861 _sip_header_t
*evhdr
= NULL
;
862 _sip_header_t
*substate
= NULL
;
863 sip_header_t chdr
= NULL
;
865 const sip_str_t
*ttag
;
866 const sip_str_t
*remtag
;
867 const sip_str_t
*callid
;
868 const struct sip_value
*val
;
872 boolean_t alloc_thdr
= B_FALSE
;
874 if (sip_msg_is_request((sip_msg_t
)sip_msg
, &error
) && error
== 0)
875 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
877 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
878 if (error
!= 0 || dialog
== NULL
||
879 (sip_msg_is_request((sip_msg_t
)sip_msg
, &error
) &&
880 (dialog
->sip_dlg_method
== INVITE
|| method
!= NOTIFY
))) {
883 if ((dialog
->sip_dlg_type
== SIP_UAC_DIALOG
&& method
!= NOTIFY
&&
884 sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
) !=
885 dialog
->sip_dlg_local_cseq
) ||
886 (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
&& method
!= NOTIFY
&&
887 sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
) !=
888 dialog
->sip_dlg_remote_cseq
)) {
891 if (method
== NOTIFY
) {
892 const sip_str_t
*sstate
;
894 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
899 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
900 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
902 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
903 sip_free_header(thdr
);
906 evhdr
= sip_search_for_header(sip_msg
, SIP_EVENT
, NULL
);
908 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
909 sip_free_header(thdr
);
912 substate
= sip_search_for_header(sip_msg
,
913 SIP_SUBSCRIPTION_STATE
, NULL
);
914 if (substate
== NULL
) {
915 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
916 sip_free_header(thdr
);
919 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
920 sstate
= sip_get_substate((sip_msg_t
)sip_msg
, &error
);
921 if (sstate
== NULL
|| error
!= 0) {
922 sip_free_header(thdr
);
925 if ((sstate
->sip_str_len
!= strlen("pending") &&
926 sstate
->sip_str_len
!= strlen("active")) ||
927 ((sstate
->sip_str_len
== strlen("pending") &&
928 strncasecmp(sstate
->sip_str_ptr
, "pending",
929 strlen("pending")) != 0) ||
930 (sstate
->sip_str_len
== strlen("active") &&
931 strncasecmp(sstate
->sip_str_ptr
, "active",
932 strlen("active")) != 0))) {
933 sip_free_header(thdr
);
936 ttag
= sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
);
938 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
939 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
943 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
944 thdr
= sip_search_for_header(sip_msg
, SIP_TO
, NULL
);
945 if (dialog
->sip_dlg_remote_target
== NULL
) {
946 chdr
= sip_search_for_header(sip_msg
,
949 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
952 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
955 ttag
= sip_get_to_tag((sip_msg_t
)sip_msg
, NULL
);
959 sip_free_header(thdr
);
962 prev_state
= dialog
->sip_dlg_state
;
964 if (method
== NOTIFY
) {
966 const sip_str_t
*dlg_id_val
= NULL
;
967 const sip_str_t
*event
;
968 const sip_str_t
*id_val
= NULL
;
969 sip_header_value_t ev_val
;
970 sip_hdr_value_t
*dlg_ev_val
= NULL
;
972 event
= sip_get_event((sip_msg_t
)sip_msg
, &error
);
973 if (event
== NULL
|| error
!= 0) {
974 sip_free_header(thdr
);
977 ev_val
= (sip_header_value_t
)sip_get_header_value(evhdr
,
980 id_val
= sip_get_param_value(ev_val
, "id", &error
);
982 dlg_ev_val
= (sip_hdr_value_t
*)sip_get_header_value(
983 dialog
->sip_dlg_event
, &error
);
985 if (dlg_ev_val
== NULL
|| error
!= 0) {
986 sip_free_header(thdr
);
989 dlg_id_val
= sip_get_param_value((sip_header_value_t
)dlg_ev_val
,
992 dlg_ev_val
->str_val_len
!= event
->sip_str_len
||
993 strncmp(dlg_ev_val
->str_val_ptr
, event
->sip_str_ptr
,
994 event
->sip_str_len
!= 0)) {
995 sip_free_header(thdr
);
998 if ((dlg_id_val
== NULL
&& id_val
!= NULL
) ||
999 (dlg_id_val
!= NULL
&& id_val
== NULL
)) {
1000 sip_free_header(thdr
);
1002 } else if (dlg_id_val
!= NULL
&& id_val
!= NULL
) {
1003 if (dlg_id_val
->sip_str_len
!= id_val
->sip_str_len
||
1004 strncasecmp(dlg_id_val
->sip_str_ptr
,
1005 id_val
->sip_str_ptr
, dlg_id_val
->sip_str_len
) !=
1007 sip_free_header(thdr
);
1011 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1012 dialog
->sip_dlg_remote_uri_tag
= thdr
;
1013 if ((dialog
->sip_dlg_remote_target
=
1014 sip_dup_header(chdr
)) == NULL
) {
1015 sip_free_header(thdr
);
1019 dialog
->sip_dlg_local_uri_tag
= thdr
;
1021 dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1023 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1024 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1025 if (dialog
->sip_dlg_state
!= SIP_DLG_NEW
) {
1026 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1027 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1029 assert(dialog
->sip_dlg_state
== SIP_DLG_NEW
);
1030 if (dialog
->sip_dlg_remote_target
== NULL
&& chdr
!= NULL
) {
1031 if (dialog
->sip_dlg_type
!= SIP_UAC_DIALOG
) {
1032 sip_write_to_log((void *)dialog
,
1033 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
1034 __FILE__
, __LINE__
);
1036 assert(dialog
->sip_dlg_type
== SIP_UAC_DIALOG
);
1037 if ((dialog
->sip_dlg_remote_target
=
1038 sip_dup_header(chdr
)) == NULL
) {
1039 (void) pthread_mutex_unlock(
1040 &dialog
->sip_dlg_mutex
);
1042 sip_free_header(thdr
);
1043 goto terminate_new_dlg
;
1045 if (sip_dialog_get_route_set(dialog
, sip_msg
,
1046 dialog
->sip_dlg_type
) != 0) {
1047 (void) pthread_mutex_unlock(
1048 &dialog
->sip_dlg_mutex
);
1050 sip_free_header(thdr
);
1051 goto terminate_new_dlg
;
1054 if (SIP_PROVISIONAL_RESP(resp_code
)) {
1055 dialog
->sip_dlg_state
= SIP_DLG_EARLY
;
1056 } else if (SIP_OK_RESP(resp_code
)) {
1058 * Per 12.1 the UAS must include the contact header
1059 * for a dialog establishing response, so if we
1060 * don't find one, we terminate it.
1062 if (dialog
->sip_dlg_remote_target
== NULL
) {
1063 (void) pthread_mutex_unlock(
1064 &dialog
->sip_dlg_mutex
);
1065 if (sip_ulp_dlg_del_cb
!= NULL
) {
1066 sip_ulp_dlg_del_cb(dialog
,
1067 (sip_msg_t
)sip_msg
, NULL
);
1070 sip_free_header(thdr
);
1071 goto terminate_new_dlg
;
1073 dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1075 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1076 if (sip_ulp_dlg_del_cb
!= NULL
) {
1077 sip_ulp_dlg_del_cb(dialog
, (sip_msg_t
)sip_msg
,
1081 sip_free_header(thdr
);
1082 goto terminate_new_dlg
;
1084 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
1085 dialog
->sip_dlg_local_uri_tag
= thdr
;
1087 if ((dialog
->sip_dlg_remote_uri_tag
=
1088 sip_dup_header(thdr
)) == NULL
) {
1089 (void) pthread_mutex_unlock(
1090 &dialog
->sip_dlg_mutex
);
1091 goto terminate_new_dlg
;
1097 * We take the local contact for UAS Dialog from the response (either
1098 * NOTIFY for SUBSCRIBE request or from final response 2xx to INVITE
1101 if ((dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) && (dialog
->sip_dlg_state
1102 == SIP_DLG_CONFIRMED
)) {
1104 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1105 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
,
1107 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1109 if ((chdr
== NULL
) || ((dialog
->sip_dlg_local_contact
=
1110 sip_dup_header(chdr
)) == NULL
)) {
1111 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1113 sip_free_header(thdr
);
1114 goto terminate_new_dlg
;
1119 * Cancel the partial dialog timer
1121 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
1122 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
1124 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1125 val
= sip_get_header_value(dialog
->sip_dlg_local_uri_tag
,
1128 val
= sip_get_header_value(dialog
->sip_dlg_remote_uri_tag
,
1131 if (val
== NULL
|| error
!= 0) {
1132 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1133 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1135 assert(val
!= NULL
&& error
== 0);
1136 remtag
= sip_get_param_value((sip_header_value_t
)val
, "tag", &error
);
1138 val
= sip_get_header_value(dialog
->sip_dlg_call_id
, &error
);
1139 callid
= &((sip_hdr_value_t
*)val
)->str_val
;
1142 * Get an ID for this dialog
1144 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1145 sip_md5_hash(remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1146 ttag
->sip_str_ptr
, ttag
->sip_str_len
,
1147 callid
->sip_str_ptr
, callid
->sip_str_len
,
1148 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)dialog
->sip_dlg_id
);
1150 sip_md5_hash(ttag
->sip_str_ptr
, ttag
->sip_str_len
,
1151 remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1152 callid
->sip_str_ptr
, callid
->sip_str_len
,
1153 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)dialog
->sip_dlg_id
);
1156 SIP_DLG_REFCNT_INCR(dialog
);
1157 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1160 * Add it to the hash table
1162 if (sip_hash_add(sip_dialog_hash
, (void *)dialog
,
1163 SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
)) != 0) {
1166 * So that sip_dialog_delete() does not try to remove
1167 * this from the hash table.
1169 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1170 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
1171 if (dialog
->sip_dlg_local_uri_tag
!= NULL
) {
1172 sip_free_header(dialog
->sip_dlg_local_uri_tag
);
1173 dialog
->sip_dlg_local_uri_tag
= NULL
;
1176 if (dialog
->sip_dlg_remote_uri_tag
!= NULL
) {
1177 sip_free_header(dialog
->sip_dlg_remote_uri_tag
);
1178 dialog
->sip_dlg_remote_uri_tag
= NULL
;
1181 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1182 sip_dialog_terminate(dialog
, (sip_msg_t
)sip_msg
);
1185 if (sip_dlg_ulp_state_cb
!= NULL
) {
1186 sip_dlg_ulp_state_cb((sip_dialog_t
)dialog
,
1187 (sip_msg_t
)sip_msg
, prev_state
, dialog
->sip_dlg_state
);
1189 return ((sip_dialog_t
)dialog
);
1193 * Check if this dialog is a match.
1196 sip_dialog_match(void *obj
, void *hindex
)
1198 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1200 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1201 if (dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
) {
1202 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1205 if (bcmp(dialog
->sip_dlg_id
, hindex
,
1206 sizeof (dialog
->sip_dlg_id
)) == 0) {
1207 SIP_DLG_REFCNT_INCR(dialog
);
1208 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1211 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1216 * Don't delete, just take it out of the hash
1219 sip_dialog_dontfree(void *obj
, void *hindex
, int *found
)
1221 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1224 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1225 if (bcmp(dialog
->sip_dlg_id
, hindex
, sizeof (dialog
->sip_dlg_id
))
1228 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1231 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1236 * Free resources associated with the dialog, the object will be removed
1237 * from the hash list by sip_hash_delete.
1240 sip_dialog_free(void *obj
, void *hindex
, int *found
)
1242 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1245 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1246 if (bcmp(dialog
->sip_dlg_id
, hindex
, sizeof (dialog
->sip_dlg_id
))
1249 if (dialog
->sip_dlg_state
!= SIP_DLG_DESTROYED
) {
1250 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1251 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1253 assert(dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
);
1254 if (dialog
->sip_dlg_ref_cnt
!= 0) {
1255 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1258 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
, NULL
, 0);
1259 sip_release_dialog_res(dialog
);
1262 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1267 * The UAS will receive the request from the transaction layer. If the
1268 * request has a tag in the To header field, the UAS core computes the
1269 * dialog identifier corresponding to the request and compares it with
1270 * existing dialogs. If there is a match, this is a mid-dialog request.
1273 sip_dialog_find(_sip_msg_t
*sip_msg
)
1275 const sip_str_t
*localtag
;
1276 const sip_str_t
*remtag
;
1277 const sip_str_t
*callid
;
1279 _sip_dialog_t
*dialog
;
1280 boolean_t is_request
;
1283 is_request
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1287 localtag
= sip_get_to_tag((sip_msg_t
)sip_msg
, &error
);
1289 remtag
= sip_get_from_tag((sip_msg_t
)sip_msg
, &error
);
1291 remtag
= sip_get_to_tag((sip_msg_t
)sip_msg
, &error
);
1293 localtag
= sip_get_from_tag((sip_msg_t
)sip_msg
, &error
);
1297 callid
= sip_get_callid((sip_msg_t
)sip_msg
, &error
);
1298 if (error
!= 0 || remtag
== NULL
|| localtag
== NULL
||
1302 sip_md5_hash(localtag
->sip_str_ptr
, localtag
->sip_str_len
,
1303 remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1304 callid
->sip_str_ptr
, callid
->sip_str_len
,
1305 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)digest
);
1307 dialog
= (_sip_dialog_t
*)sip_hash_find(sip_dialog_hash
,
1308 (void *)digest
, SIP_DIGEST_TO_HASH(digest
), sip_dialog_match
);
1309 if (dialog
== NULL
) {
1310 sip_md5_hash(localtag
->sip_str_ptr
, localtag
->sip_str_len
,
1311 NULL
, 0, callid
->sip_str_ptr
, callid
->sip_str_len
,
1312 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)digest
);
1313 dialog
= (_sip_dialog_t
*)sip_hash_find(sip_dialog_phash
,
1314 (void *)digest
, SIP_DIGEST_TO_HASH(digest
),
1317 return ((sip_dialog_t
)dialog
);
1321 * We keep this partial dialog for the duration of the INVITE
1322 * transaction timeout duration, i.e. Timer B.
1325 sip_dlg_self_destruct(void *args
)
1327 sip_dialog_timer_obj_t
*tim_obj
= (sip_dialog_timer_obj_t
*)args
;
1328 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)tim_obj
->dialog
;
1331 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1332 if (dialog
->sip_dlg_state
!= SIP_DLG_NEW
) {
1333 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1334 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1336 assert(dialog
->sip_dlg_state
== SIP_DLG_NEW
);
1337 dialog
->sip_dlg_state
= SIP_DLG_DESTROYED
;
1338 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1339 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1340 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1341 sip_hash_delete(sip_dialog_phash
, (void *)dialog
->sip_dlg_id
,
1342 index
, sip_dialog_dontfree
);
1344 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1346 if (tim_obj
->func
!= NULL
)
1347 tim_obj
->func(dialog
, NULL
, NULL
);
1349 SIP_DLG_REFCNT_DECR(dialog
);
1353 * Terminate a dialog
1356 sip_dialog_terminate(_sip_dialog_t
*dialog
, sip_msg_t sip_msg
)
1360 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1361 prev_state
= dialog
->sip_dlg_state
;
1362 dialog
->sip_dlg_state
= SIP_DLG_DESTROYED
;
1363 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1364 if (sip_dlg_ulp_state_cb
!= NULL
) {
1365 sip_dlg_ulp_state_cb((sip_dialog_t
)dialog
, sip_msg
, prev_state
,
1366 dialog
->sip_dlg_state
);
1368 SIP_DLG_REFCNT_DECR(dialog
);
1375 sip_dialog_delete(_sip_dialog_t
*dialog
)
1380 * partial dialog, not in the hash table
1382 if (dialog
->sip_dlg_local_uri_tag
== NULL
||
1383 dialog
->sip_dlg_remote_uri_tag
== NULL
) {
1385 * Cancel the partial dialog timer
1387 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
1388 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
1389 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
, NULL
, 0);
1390 sip_release_dialog_res(dialog
);
1393 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1394 sip_hash_delete(sip_dialog_hash
, (void *)dialog
->sip_dlg_id
, index
,
1399 * Get the remote target from the CONTACT header from the 200 OK response
1402 sip_get_rtarg(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
)
1406 if (dialog
->sip_dlg_remote_target
!= NULL
)
1409 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1410 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
1411 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1414 if ((dialog
->sip_dlg_remote_target
= sip_dup_header(chdr
)) == NULL
)
1421 * Process an incoming request/response
1425 sip_dialog_process(_sip_msg_t
*sip_msg
, sip_dialog_t
*sip_dialog
)
1428 _sip_dialog_t
*_dialog
;
1431 _dialog
= (_sip_dialog_t
*)*sip_dialog
;
1433 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1434 _dialog
->sip_dlg_msgcnt
++;
1435 sip_add_log(&_dialog
->sip_dlg_log
[_dialog
->sip_dlg_state
],
1436 (sip_msg_t
)sip_msg
, _dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
1437 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1439 request
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1444 sip_method_t method
;
1446 cseq
= sip_get_callseq_num((sip_msg_t
)sip_msg
, &error
);
1449 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
1452 if (sip_get_request_method((sip_msg_t
)sip_msg
, &error
) !=
1456 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1458 * Requests that do not change in any way the state
1459 * of a dialog may be received within a dialog.
1460 * They are processed as if they had been received
1461 * outside the dialog.
1462 * For dialogs that have been established with an
1463 * INVITE, the only target refresh request defined is
1466 if (_dialog
->sip_dlg_method
== INVITE
&&
1467 method
== INVITE
&& _dialog
->sip_dlg_remote_cseq
!= 0 &&
1468 SIP_CSEQ_LT(cseq
, _dialog
->sip_dlg_remote_cseq
)) {
1469 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1473 * Target-Refresh request
1475 if (_dialog
->sip_dlg_method
== INVITE
&& method
== INVITE
) {
1479 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1480 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
,
1482 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1484 (nchdr
= sip_dup_header(chdr
)) != NULL
) {
1485 if (_dialog
->sip_dlg_remote_target
!= NULL
) {
1487 _dialog
->sip_dlg_remote_target
);
1489 _dialog
->sip_dlg_remote_target
= nchdr
;
1492 _dialog
->sip_dlg_remote_cseq
= cseq
;
1493 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1496 sip_method_t method
;
1499 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1501 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
,
1507 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1508 if (_dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
) {
1509 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1512 if (_dialog
->sip_dlg_state
!= SIP_DLG_EARLY
&&
1513 _dialog
->sip_dlg_state
!= SIP_DLG_CONFIRMED
) {
1514 sip_write_to_log((void *)_dialog
, SIP_DIALOG_LOG
|
1515 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1517 assert(_dialog
->sip_dlg_state
== SIP_DLG_EARLY
||
1518 _dialog
->sip_dlg_state
== SIP_DLG_CONFIRMED
);
1520 * Let the user delete the dialog if it is not a 1XX/2XX resp
1521 * for an early INVITE dialog.
1523 if (SIP_OK_RESP(resp_code
)) {
1524 if (method
== INVITE
) {
1525 if (!sip_get_rtarg(_dialog
, sip_msg
)) {
1526 (void) pthread_mutex_unlock(
1527 &_dialog
->sip_dlg_mutex
);
1528 if (sip_ulp_dlg_del_cb
!= NULL
) {
1530 (sip_dialog_t
)_dialog
,
1531 (sip_msg_t
)sip_msg
, NULL
);
1533 sip_dialog_terminate(_dialog
,
1534 (sip_msg_t
)sip_msg
);
1537 if (_dialog
->sip_dlg_state
== SIP_DLG_EARLY
) {
1538 _dialog
->sip_dlg_state
=
1540 (void) sip_dlg_recompute_rset(_dialog
,
1541 sip_msg
, SIP_UAC_DIALOG
);
1542 (void) pthread_mutex_unlock(
1543 &_dialog
->sip_dlg_mutex
);
1544 if (sip_dlg_ulp_state_cb
!= NULL
) {
1545 sip_dlg_ulp_state_cb(
1546 (sip_dialog_t
)_dialog
,
1547 sip_msg
, SIP_DLG_EARLY
,
1548 _dialog
->sip_dlg_state
);
1551 } else if (_dialog
->sip_dlg_new_local_contact
1553 if (_dialog
->sip_dlg_local_contact
==
1555 (void) sip_write_to_log((void *)
1556 _dialog
, SIP_DIALOG_LOG
|
1557 SIP_ASSERT_ERROR
, __FILE__
,
1560 assert(_dialog
->sip_dlg_local_contact
1562 sip_free_header(_dialog
->
1563 sip_dlg_local_contact
);
1564 _dialog
->sip_dlg_local_contact
=
1565 _dialog
->sip_dlg_new_local_contact
;
1566 _dialog
->sip_dlg_new_local_contact
=
1571 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1577 * Copy partial dialog to create a complete dialog
1580 sip_copy_partial_dialog(_sip_dialog_t
*dialog
)
1582 _sip_dialog_t
*new_dlg
;
1584 new_dlg
= calloc(1, sizeof (_sip_dialog_t
));
1585 if (new_dlg
== NULL
)
1587 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
1588 new_dlg
->sip_dlg_req_uri
.sip_str_ptr
=
1589 malloc(dialog
->sip_dlg_req_uri
.sip_str_len
+ 1);
1590 if (new_dlg
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
1594 (void) strncpy(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
,
1595 dialog
->sip_dlg_req_uri
.sip_str_ptr
,
1596 dialog
->sip_dlg_req_uri
.sip_str_len
);
1597 new_dlg
->sip_dlg_req_uri
.sip_str_ptr
[
1598 dialog
->sip_dlg_req_uri
.sip_str_len
] = '\0';
1599 new_dlg
->sip_dlg_req_uri
.sip_str_len
=
1600 dialog
->sip_dlg_req_uri
.sip_str_len
;
1602 if (dialog
->sip_dlg_route_set
!= NULL
) {
1603 if (dialog
->sip_dlg_rset
.sip_str_ptr
== NULL
) {
1604 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1605 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1607 assert(dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
);
1608 new_dlg
->sip_dlg_rset
.sip_str_ptr
=
1609 malloc(dialog
->sip_dlg_rset
.sip_str_len
+ 1);
1610 if (new_dlg
->sip_dlg_rset
.sip_str_ptr
== NULL
) {
1611 if (new_dlg
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
)
1612 free(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
);
1616 (void) strncpy(new_dlg
->sip_dlg_rset
.sip_str_ptr
,
1617 dialog
->sip_dlg_rset
.sip_str_ptr
,
1618 dialog
->sip_dlg_rset
.sip_str_len
);
1619 new_dlg
->sip_dlg_rset
.sip_str_ptr
[
1620 dialog
->sip_dlg_rset
.sip_str_len
] = '\0';
1621 new_dlg
->sip_dlg_rset
.sip_str_len
=
1622 dialog
->sip_dlg_rset
.sip_str_len
;
1624 new_dlg
->sip_dlg_route_set
=
1625 sip_dup_header(dialog
->sip_dlg_route_set
);
1626 if (new_dlg
->sip_dlg_route_set
== NULL
) {
1627 free(new_dlg
->sip_dlg_rset
.sip_str_ptr
);
1628 if (new_dlg
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
)
1629 free(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
);
1634 if ((new_dlg
->sip_dlg_local_uri_tag
=
1635 sip_dup_header(dialog
->sip_dlg_local_uri_tag
)) == NULL
||
1636 (new_dlg
->sip_dlg_remote_target
=
1637 sip_dup_header(dialog
->sip_dlg_remote_target
)) == NULL
||
1638 (new_dlg
->sip_dlg_local_contact
=
1639 sip_dup_header(dialog
->sip_dlg_local_contact
)) == NULL
||
1640 (new_dlg
->sip_dlg_call_id
=
1641 sip_dup_header(dialog
->sip_dlg_call_id
)) == NULL
) {
1642 sip_release_dialog_res(new_dlg
);
1645 if (dialog
->sip_dlg_event
!= NULL
) {
1646 new_dlg
->sip_dlg_event
= sip_dup_header(dialog
->sip_dlg_event
);
1647 if (new_dlg
->sip_dlg_event
== NULL
) {
1648 sip_release_dialog_res(new_dlg
);
1652 new_dlg
->sip_dlg_local_cseq
= dialog
->sip_dlg_local_cseq
;
1653 new_dlg
->sip_dlg_type
= dialog
->sip_dlg_type
;
1654 new_dlg
->sip_dlg_on_fork
= B_FALSE
;
1655 (void) pthread_mutex_init(&new_dlg
->sip_dlg_mutex
, NULL
);
1661 * Update the dialog using the response
1664 sip_update_dialog(sip_dialog_t dialog
, _sip_msg_t
*sip_msg
)
1666 _sip_dialog_t
*_dialog
;
1668 sip_method_t method
;
1671 boolean_t decr_ref
= B_FALSE
;
1674 _dialog
= (_sip_dialog_t
*)dialog
;
1675 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1676 _dialog
->sip_dlg_msgcnt
++;
1677 sip_add_log(&_dialog
->sip_dlg_log
[_dialog
->sip_dlg_state
],
1678 (sip_msg_t
)sip_msg
, _dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
1679 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1681 isreq
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1684 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1686 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
1687 if (error
!= 0 || _dialog
->sip_dlg_method
!= SUBSCRIBE
||
1689 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1693 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1695 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1698 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
1700 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1704 prev_state
= _dialog
->sip_dlg_state
;
1705 if (_dialog
->sip_dlg_state
== SIP_DLG_CONFIRMED
) {
1706 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1707 } else if (_dialog
->sip_dlg_state
== SIP_DLG_EARLY
) {
1709 * Let the user delete the dialog if it is not a 1XX/2XX resp
1710 * for an early dialog.
1713 sip_write_to_log((void *)_dialog
, SIP_DIALOG_LOG
|
1714 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1717 if (SIP_OK_RESP(resp_code
)) {
1718 _dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1720 * If we recieved provisional response before we would
1721 * not have captured local contact. So store it now.
1723 if (_dialog
->sip_dlg_type
== SIP_UAS_DIALOG
&& _dialog
->
1724 sip_dlg_method
== INVITE
&& method
== INVITE
) {
1726 (void) pthread_mutex_lock(&sip_msg
->
1728 chdr
= sip_search_for_header(sip_msg
,
1730 (void) pthread_mutex_unlock(&sip_msg
->
1733 _dialog
->sip_dlg_local_contact
1734 = sip_dup_header(chdr
);
1735 _dialog
->sip_dlg_new_local_contact
=
1739 (void) sip_dlg_recompute_rset(_dialog
, sip_msg
,
1741 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1742 if (sip_dlg_ulp_state_cb
!= NULL
) {
1743 sip_dlg_ulp_state_cb(dialog
, (sip_msg_t
)sip_msg
,
1744 prev_state
, dialog
->sip_dlg_state
);
1747 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1749 } else if (_dialog
->sip_dlg_state
== SIP_DLG_NEW
) {
1750 if (!isreq
&& _dialog
->sip_dlg_method
== SUBSCRIBE
&&
1751 SIP_PROVISIONAL_RESP(resp_code
)) {
1752 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1755 if (_dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1756 _sip_dialog_t
*new_dlg
;
1758 if (_dialog
->sip_dlg_on_fork
) {
1759 new_dlg
= sip_copy_partial_dialog(_dialog
);
1760 if (new_dlg
== NULL
) {
1761 (void) pthread_mutex_unlock(
1762 &_dialog
->sip_dlg_mutex
);
1766 * This decr/incr dance is because the caller
1767 * has incremented the ref on the partial
1768 * dialog, we release it here and incr the
1769 * ref on the new dialog which will be
1770 * released by the caller.
1772 (void) pthread_mutex_unlock(
1773 &_dialog
->sip_dlg_mutex
);
1774 SIP_DLG_REFCNT_DECR(_dialog
);
1776 (void) pthread_mutex_lock(
1777 &_dialog
->sip_dlg_mutex
);
1778 SIP_DLG_REFCNT_INCR(_dialog
);
1783 * take it out of the list so that further
1784 * responses will not result in a dialog.
1785 * We will have an extra refcount when we
1786 * come back from sip_complete_dialog(), i.e.
1787 * one when the partial dialog was created -
1788 * in sip_seed_dialog(), one held by the caller
1789 * and one that will be added by
1790 * sip_complete_dialog(). We need to release
1791 * the one added by the sip_seed_dialog(),
1792 * since the one in sip_complete_dialog()
1793 * is for the same purpose.
1795 if (SIP_IS_TIMER_RUNNING(
1796 _dialog
->sip_dlg_timer
)) {
1798 _dialog
->sip_dlg_timer
);
1800 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1801 (void) pthread_mutex_unlock(
1802 &_dialog
->sip_dlg_mutex
);
1803 sip_hash_delete(sip_dialog_phash
,
1804 (void *)_dialog
->sip_dlg_id
,
1805 index
, sip_dialog_dontfree
);
1806 (void) pthread_mutex_lock(
1807 &_dialog
->sip_dlg_mutex
);
1813 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1814 if ((dialog
= sip_complete_dialog(sip_msg
, _dialog
)) ==
1816 if (_dialog
->sip_dlg_type
== SIP_UAC_DIALOG
&& decr_ref
)
1817 SIP_DLG_REFCNT_DECR(_dialog
);
1821 SIP_DLG_REFCNT_DECR(_dialog
);
1823 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1829 * Initialize the hash table
1832 sip_dialog_init(void (*ulp_dlg_del
) (sip_dialog_t
, sip_msg_t
, void *),
1833 void (*ulp_state_cb
)(sip_dialog_t
, sip_msg_t
, int, int))
1837 for (cnt
= 0; cnt
< SIP_HASH_SZ
; cnt
++) {
1838 sip_dialog_hash
[cnt
].hash_count
= 0;
1839 sip_dialog_hash
[cnt
].hash_head
= NULL
;
1840 sip_dialog_hash
[cnt
].hash_tail
= NULL
;
1841 (void) pthread_mutex_init(
1842 &sip_dialog_hash
[cnt
].sip_hash_mutex
, NULL
);
1843 sip_dialog_phash
[cnt
].hash_count
= 0;
1844 sip_dialog_phash
[cnt
].hash_head
= NULL
;
1845 sip_dialog_phash
[cnt
].hash_tail
= NULL
;
1846 (void) pthread_mutex_init(
1847 &sip_dialog_phash
[cnt
].sip_hash_mutex
, NULL
);
1849 if (ulp_dlg_del
!= NULL
)
1850 sip_ulp_dlg_del_cb
= ulp_dlg_del
;
1852 if (ulp_state_cb
!= NULL
)
1853 sip_dlg_ulp_state_cb
= ulp_state_cb
;
1857 * Copy the new contact header of re-INVITE
1860 sip_dialog_add_new_contact(sip_dialog_t dialog
, _sip_msg_t
*sip_msg
)
1862 sip_header_t chdr
= NULL
;
1863 sip_header_t nhdr
= NULL
;
1865 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1866 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
1867 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1872 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1873 if (dialog
->sip_dlg_method
!= INVITE
|| dialog
->sip_dlg_state
1874 != SIP_DLG_CONFIRMED
) {
1875 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1879 if (((nhdr
= sip_dup_header(chdr
)) != NULL
)) {
1880 if (dialog
->sip_dlg_new_local_contact
!= NULL
)
1881 sip_free_header(dialog
->sip_dlg_new_local_contact
);
1882 dialog
->sip_dlg_new_local_contact
= nhdr
;
1884 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1888 * Given a state, return the string - This is mostly for debug purposes
1891 sip_get_dialog_state_str(int state
)
1895 return ("SIP_DLG_NEW");
1897 return ("SIP_DLG_EARLY");
1898 case SIP_DLG_CONFIRMED
:
1899 return ("SIP_DLG_CONFIRMED");
1900 case SIP_DLG_DESTROYED
:
1901 return ("SIP_DLG_DESTROYED");