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.
36 #include "sip_miscdefs.h"
38 #include "sip_dialog.h"
39 #include "sip_parse_generic.h"
41 #define SIP_DLG_XCHG_FROM 0
42 #define SIP_DLG_XCHG_TO 1
45 * Dialog state change callback function
47 void (*sip_dlg_ulp_state_cb
)(sip_dialog_t
, sip_msg_t
, int, int) = NULL
;
48 void (*sip_ulp_dlg_del_cb
)(sip_dialog_t
, sip_msg_t
, void *) = NULL
;
50 boolean_t
sip_incomplete_dialog(sip_dialog_t
);
53 * Exchange From/To header
55 _sip_header_t
*sip_dlg_xchg_from_to(sip_msg_t
, int);
58 * Complete dialog hash table
60 sip_hash_t sip_dialog_hash
[SIP_HASH_SZ
];
63 * Partial dialog hash table
65 sip_hash_t sip_dialog_phash
[SIP_HASH_SZ
];
70 typedef struct sip_dlg_route_set_s
{
72 sip_str_t sip_dlg_ruri
;
73 boolean_t sip_dlg_route_lr
;
74 struct sip_dlg_route_set_s
*sip_dlg_route_next
;
77 sip_dialog_t
sip_seed_dialog(sip_conn_object_t
, _sip_msg_t
*,
79 sip_dialog_t
sip_complete_dialog(_sip_msg_t
*, _sip_dialog_t
*);
80 int sip_dialog_process(_sip_msg_t
*, sip_dialog_t
*);
81 void sip_dialog_delete(_sip_dialog_t
*);
82 void sip_dialog_init();
83 sip_dialog_t
sip_dialog_find(_sip_msg_t
*);
84 boolean_t
sip_dialog_match(void *, void *);
85 boolean_t
sip_dialog_free(void *, void *, int *);
86 sip_dialog_t
sip_update_dialog(sip_dialog_t
, _sip_msg_t
*);
87 char *sip_dialog_req_uri(sip_dialog_t
);
89 static void sip_release_dialog_res(_sip_dialog_t
*);
90 void sip_dlg_self_destruct(void *);
91 static int sip_dialog_get_route_set(_sip_dialog_t
*, _sip_msg_t
*,
93 static void sip_dialog_free_rset(sip_dlg_route_set_t
*);
96 * Timer object for partial dialogs
98 typedef struct sip_dialog_timer_obj_s
{
99 _sip_dialog_t
*dialog
;
100 void (*func
)(sip_dialog_t
, sip_msg_t
, void *);
101 } sip_dialog_timer_obj_t
;
104 * To avoid duplication all over the place
107 sip_release_dialog_res(_sip_dialog_t
*dialog
)
110 sip_msg_chain_t
*msg_chain
;
111 sip_msg_chain_t
*nmsg_chain
;
113 if (dialog
->sip_dlg_ref_cnt
!= 0) {
114 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
115 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
117 assert(dialog
->sip_dlg_ref_cnt
== 0);
118 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
119 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
120 if (dialog
->sip_dlg_call_id
!= NULL
)
121 sip_free_header(dialog
->sip_dlg_call_id
);
122 if (dialog
->sip_dlg_local_uri_tag
!= NULL
)
123 sip_free_header(dialog
->sip_dlg_local_uri_tag
);
124 if (dialog
->sip_dlg_remote_uri_tag
!= NULL
)
125 sip_free_header(dialog
->sip_dlg_remote_uri_tag
);
126 if (dialog
->sip_dlg_remote_target
!= NULL
)
127 sip_free_header(dialog
->sip_dlg_remote_target
);
128 if (dialog
->sip_dlg_local_contact
!= NULL
)
129 sip_free_header(dialog
->sip_dlg_local_contact
);
130 if (dialog
->sip_dlg_new_local_contact
!= NULL
)
131 sip_free_header(dialog
->sip_dlg_new_local_contact
);
132 if (dialog
->sip_dlg_route_set
!= NULL
)
133 sip_free_header(dialog
->sip_dlg_route_set
);
134 if (dialog
->sip_dlg_event
!= NULL
)
135 sip_free_header(dialog
->sip_dlg_event
);
136 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
137 free(dialog
->sip_dlg_req_uri
.sip_str_ptr
);
138 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
139 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
141 if (dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
) {
142 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
143 dialog
->sip_dlg_rset
.sip_str_len
= 0;
144 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
146 for (count
= 0; count
<= SIP_DLG_DESTROYED
; count
++) {
147 msg_chain
= dialog
->sip_dlg_log
[count
].sip_msgs
;
148 while (msg_chain
!= NULL
) {
149 nmsg_chain
= msg_chain
->next
;
150 free(msg_chain
->sip_msg
);
152 msg_chain
= nmsg_chain
;
155 (void) pthread_mutex_destroy(&dialog
->sip_dlg_mutex
);
160 * Get the route information from the 'value' and add it to the route
163 static sip_dlg_route_set_t
*
164 sip_add_route_to_set(sip_hdr_value_t
*value
)
167 sip_dlg_route_set_t
*rset
;
169 const sip_param_t
*uri_param
;
172 rset
= calloc(1, sizeof (*rset
));
175 rset
->sip_dlg_route_next
= NULL
;
176 vlen
= value
->sip_value_end
- value
->sip_value_start
;
181 crlf
= value
->sip_value_end
- strlen(SIP_CRLF
);
182 while (crlf
!= NULL
&& strncmp(crlf
, SIP_CRLF
, strlen(SIP_CRLF
)) == 0) {
183 vlen
-= strlen(SIP_CRLF
);
184 crlf
-= strlen(SIP_CRLF
);
186 rset
->sip_dlg_route
= calloc(1, vlen
+ 1);
187 if (rset
->sip_dlg_route
== NULL
) {
194 rset
->sip_dlg_route_lr
= B_FALSE
;
195 (void) strncpy(rset
->sip_dlg_route
, value
->sip_value_start
, vlen
);
196 rset
->sip_dlg_ruri
.sip_str_ptr
= rset
->sip_dlg_route
+
197 (value
->cftr_uri
.sip_str_ptr
- value
->sip_value_start
);
198 rset
->sip_dlg_ruri
.sip_str_len
= value
->cftr_uri
.sip_str_len
;
199 rset
->sip_dlg_route
[vlen
] = '\0';
201 assert(value
->sip_value_parsed_uri
!= NULL
);
203 * Check if the 'lr' param is present for this route.
205 uri_param
= sip_get_uri_params(value
->sip_value_parsed_uri
, &error
);
207 free(rset
->sip_dlg_route
);
211 if (uri_param
!= NULL
) {
212 rset
->sip_dlg_route_lr
= sip_is_param_present(uri_param
, "lr",
219 * Depending on the route-set, determine the request URI.
222 sip_dialog_req_uri(sip_dialog_t dialog
)
224 const sip_str_t
*req_uri
;
226 _sip_dialog_t
*_dialog
;
228 _dialog
= (_sip_dialog_t
*)dialog
;
229 if (_dialog
->sip_dlg_route_set
== NULL
||
230 _dialog
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
231 const struct sip_value
*val
;
233 val
= sip_get_header_value(_dialog
->sip_dlg_remote_target
,
237 req_uri
= &((sip_hdr_value_t
*)val
)->cftr_uri
;
239 req_uri
= &_dialog
->sip_dlg_req_uri
;
241 uri
= (char *)malloc(req_uri
->sip_str_len
+ 1);
244 (void) strncpy(uri
, req_uri
->sip_str_ptr
, req_uri
->sip_str_len
);
245 uri
[req_uri
->sip_str_len
] = '\0';
251 * Free the route set.
254 sip_dialog_free_rset(sip_dlg_route_set_t
*rset
)
256 sip_dlg_route_set_t
*next
;
258 while (rset
!= NULL
) {
259 next
= rset
->sip_dlg_route_next
;
260 rset
->sip_dlg_route_next
= NULL
;
261 free(rset
->sip_dlg_route
);
268 * Recompute route-set
271 sip_dlg_recompute_rset(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
, int what
)
275 if (dialog
->sip_dlg_route_set
!= NULL
) {
276 sip_free_header(dialog
->sip_dlg_route_set
);
277 dialog
->sip_dlg_route_set
= NULL
;
279 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
280 free(dialog
->sip_dlg_req_uri
.sip_str_ptr
);
281 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
282 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
284 if (dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
) {
285 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
286 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
287 dialog
->sip_dlg_rset
.sip_str_len
= 0;
289 ret
= sip_dialog_get_route_set(dialog
, sip_msg
, what
);
294 * If the route set is empty, the UAC MUST place the remote target URI
295 * into the Request-URI. The UAC MUST NOT add a Route header field to
298 * If the route set is not empty, and the first URI in the route set
299 * contains the lr parameter (see Section 19.1.1), the UAC MUST place
300 * the remote target URI into the Request-URI and MUST include a Route
301 * header field containing the route set values in order, including all
304 * If the route set is not empty, and its first URI does not contain the
305 * lr parameter, the UAC MUST place the first URI from the route set
306 * into the Request-URI, stripping any parameters that are not allowed
307 * in a Request-URI. The UAC MUST add a Route header field containing
308 * the remainder of the route set values in order, including all
309 * parameters. The UAC MUST then place the remote target URI into the
310 * Route header field as the last value.
313 sip_dialog_set_route_hdr(_sip_dialog_t
*dialog
, sip_dlg_route_set_t
*rset_head
,
322 sip_dlg_route_set_t
*route
;
323 boolean_t first
= B_TRUE
;
324 const sip_str_t
*to_uri
;
330 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
331 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
335 dialog
->sip_dlg_rset
.sip_str_len
= rlen
+ rcnt
- 1;
336 dialog
->sip_dlg_rset
.sip_str_ptr
= malloc(rlen
+ rcnt
);
337 if (dialog
->sip_dlg_rset
.sip_str_ptr
== NULL
)
339 rsp
= dialog
->sip_dlg_rset
.sip_str_ptr
;
343 if (!route
->sip_dlg_route_lr
) {
344 const struct sip_value
*val
;
346 val
= sip_get_header_value(dialog
->sip_dlg_remote_target
, NULL
);
347 to_uri
= &((sip_hdr_value_t
*)val
)->cftr_uri
;
348 uri
= (char *)malloc(to_uri
->sip_str_len
+ 1);
350 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
351 dialog
->sip_dlg_rset
.sip_str_len
= 0;
352 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
355 (void) strncpy(uri
, to_uri
->sip_str_ptr
, to_uri
->sip_str_len
);
356 uri
[to_uri
->sip_str_len
] = '\0';
357 rset_len
= rlen
- strlen(route
->sip_dlg_route
) + strlen(uri
) +
358 SIP_SPACE_LEN
+ sizeof (char) + SIP_SPACE_LEN
+
360 count
= snprintf(rsp
, rspl
, "%s", route
->sip_dlg_route
);
361 dialog
->sip_dlg_req_uri
.sip_str_ptr
= malloc(
362 route
->sip_dlg_ruri
.sip_str_len
+ 1);
363 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
365 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
366 dialog
->sip_dlg_rset
.sip_str_len
= 0;
367 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
370 (void) strncpy(dialog
->sip_dlg_req_uri
.sip_str_ptr
, rsp
+
371 (route
->sip_dlg_ruri
.sip_str_ptr
- route
->sip_dlg_route
),
372 route
->sip_dlg_ruri
.sip_str_len
);
373 dialog
->sip_dlg_req_uri
.sip_str_ptr
[
374 route
->sip_dlg_ruri
.sip_str_len
] = '\0';
375 dialog
->sip_dlg_req_uri
.sip_str_len
=
376 route
->sip_dlg_ruri
.sip_str_len
;
380 route
= route
->sip_dlg_route_next
;
384 * rcnt - 1 is for the number of COMMAs
386 rset_len
+= strlen(SIP_ROUTE
) + SIP_SPACE_LEN
+ sizeof (char) +
387 SIP_SPACE_LEN
+ rcnt
- 1;
388 rset
= malloc(rset_len
+ 1);
390 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
391 dialog
->sip_dlg_rset
.sip_str_len
= 0;
392 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
395 rhdr
= sip_new_header(rset_len
+ strlen(SIP_CRLF
));
398 free(dialog
->sip_dlg_rset
.sip_str_ptr
);
399 dialog
->sip_dlg_rset
.sip_str_len
= 0;
400 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
406 count
= snprintf(rp
, rpl
, "%s %c ", SIP_ROUTE
, SIP_HCOLON
);
410 while (route
!= NULL
) {
412 count
= snprintf(rp
, rpl
, "%s", route
->sip_dlg_route
);
417 count
= snprintf(rsp
, rspl
, "%c%s",
418 SIP_COMMA
, route
->sip_dlg_route
);
420 count
= snprintf(rsp
, rspl
, "%s",
421 route
->sip_dlg_route
);
426 count
= snprintf(rp
, rpl
, "%c%s", SIP_COMMA
,
427 route
->sip_dlg_route
);
430 count
= snprintf(rsp
, rspl
, "%c%s", SIP_COMMA
,
431 route
->sip_dlg_route
);
435 route
= route
->sip_dlg_route_next
;
437 if (rsp
> dialog
->sip_dlg_rset
.sip_str_ptr
+
438 dialog
->sip_dlg_rset
.sip_str_len
) {
439 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
440 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
442 assert(rsp
<= dialog
->sip_dlg_rset
.sip_str_ptr
+
443 dialog
->sip_dlg_rset
.sip_str_len
);
444 dialog
->sip_dlg_rset
.sip_str_ptr
[dialog
->sip_dlg_rset
.sip_str_len
] =
448 count
= snprintf(rp
, rpl
, "%c %s %c", SIP_LAQUOT
,
451 count
= snprintf(rp
, rpl
, "%c%c %s %c", SIP_COMMA
,
452 SIP_LAQUOT
, uri
, SIP_RAQUOT
);
458 if (rp
> rset
+ rset_len
) {
459 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
460 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
462 assert(rp
<= rset
+ rset_len
);
463 (void) snprintf(rhdr
->sip_hdr_start
, rset_len
+ strlen(SIP_CRLF
) + 1,
464 "%s%s", rset
, SIP_CRLF
);
466 dialog
->sip_dlg_route_set
= (sip_header_t
)rhdr
;
467 sip_dialog_free_rset(rset_head
);
473 * The route set MUST be set to the list of URIs in the Record-Route
474 * header field from the response, taken in reverse order and preserving
475 * all URI parameters.
478 * The route set MUST be set to the list of URIs in the Record-Route
479 * header field from the request, taken in order and preserving all URI
483 sip_dialog_get_route_set(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
, int what
)
486 sip_hdr_value_t
*value
;
488 sip_dlg_route_set_t
*rset_head
= NULL
;
489 sip_dlg_route_set_t
*rset_tail
= NULL
;
490 sip_dlg_route_set_t
*rset
;
494 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
495 rrhdr
= sip_search_for_header(sip_msg
, SIP_RECORD_ROUTE
, NULL
);
496 while (rrhdr
!= NULL
) {
497 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
498 value
= (sip_hdr_value_t
*)sip_get_header_value(rrhdr
, &error
);
499 while (value
!= NULL
&& error
== 0) {
502 if (value
->sip_value_state
== SIP_VALUE_BAD
) {
503 value
= (sip_hdr_value_t
*)sip_get_next_value(
504 (sip_header_value_t
)value
, &error
);
507 rset
= sip_add_route_to_set(value
);
514 rset_len
+= (value
->sip_value_end
-
515 value
->sip_value_start
);
519 crlf
= value
->sip_value_end
- strlen(SIP_CRLF
);
520 while (crlf
!= NULL
&&
521 strncmp(crlf
, SIP_CRLF
, strlen(SIP_CRLF
)) == 0) {
522 rset_len
-= strlen(SIP_CRLF
);
523 crlf
-= strlen(SIP_CRLF
);
525 if (rset_head
== NULL
) {
526 if (rset_tail
!= NULL
) {
527 sip_write_to_log((void *)dialog
,
528 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
531 assert(rset_tail
== NULL
);
532 rset_head
= rset_tail
= rset
;
533 } else if (what
== SIP_UAS_DIALOG
) {
534 rset_tail
->sip_dlg_route_next
= rset
;
536 } else if (what
== SIP_UAC_DIALOG
) {
537 rset
->sip_dlg_route_next
= rset_head
;
540 sip_write_to_log((void *)dialog
,
541 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
545 value
= (sip_hdr_value_t
*)sip_get_next_value(
546 (sip_header_value_t
)value
, &error
);
548 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
549 rrhdr
= sip_search_for_header(sip_msg
, SIP_RECORD_ROUTE
, rrhdr
);
551 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
554 if (sip_dialog_set_route_hdr(dialog
, rset_head
, rset_cnt
,
560 sip_dialog_free_rset(rset_head
);
566 * The remote sequence number MUST be set to the value of the sequence
567 * number in the CSeq header field of the request. The local sequence
568 * number MUST be empty. The call identifier component of the dialog ID
569 * MUST be set to the value of the Call-ID in the request. The local
570 * tag component of the dialog ID MUST be set to the tag in the To field
571 * in the response to the request (which always includes a tag), and the
572 * remote tag component of the dialog ID MUST be set to the tag from the
573 * From field in the request. A UAS MUST be prepared to receive a
574 * request without a tag in the From field, in which case the tag is
575 * considered to have a value of null.
576 * The remote URI MUST be set to the URI in the From field, and the
577 * local URI MUST be set to the URI in the To field.
578 * The remote target MUST be set to the URI from the Contact header field
582 * The local sequence number MUST be set to the value of the sequence
583 * number in the CSeq header field of the request. The remote sequence
584 * number MUST be empty (it is established when the remote UA sends a
585 * request within the dialog). The call identifier component of the
586 * dialog ID MUST be set to the value of the Call-ID in the request.
587 * The local tag component of the dialog ID MUST be set to the tag in
588 * the From field in the request, and the remote tag component of the
589 * dialog ID MUST be set to the tag in the To field of the response. A
590 * UAC MUST be prepared to receive a response without a tag in the To
591 * field, in which case the tag is considered to have a value of null.
592 * The remote URI MUST be set to the URI in the To field, and the local
593 * URI MUST be set to the URI in the From field.
594 * The remote target MUST be set to the URI from the Contact header field
600 * This is the routine that seeds a dialog.
603 sip_seed_dialog(sip_conn_object_t obj
, _sip_msg_t
*sip_msg
,
604 boolean_t dlg_on_fork
, int dlg_type
)
606 _sip_dialog_t
*dialog
;
608 sip_header_t fhdr
= NULL
;
609 sip_header_t thdr
= NULL
;
612 sip_header_t evhdr
= NULL
;
613 const struct sip_value
*value
;
614 sip_dialog_timer_obj_t
*tim_obj
= NULL
;
615 const sip_str_t
*callid
;
617 int timer1
= sip_timer_T1
;
620 if (!sip_msg_is_request((sip_msg_t
)sip_msg
, &error
))
623 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
625 * Only INVITE and SUBSCRIBE supported
627 if (error
!= 0 || (method
!= INVITE
&& method
!= SUBSCRIBE
))
631 * A request outside of a dialog MUST NOT contain a To tag
633 if (sip_get_to_tag((sip_msg_t
)sip_msg
, NULL
) != NULL
)
636 if (dlg_type
== SIP_UAS_DIALOG
) {
637 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
639 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
641 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
642 fhdr
= sip_search_for_header(sip_msg
, SIP_FROM
, NULL
);
644 cihdr
= sip_search_for_header(sip_msg
, SIP_CALL_ID
, NULL
);
645 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
646 if (method
== SUBSCRIBE
)
647 evhdr
= sip_search_for_header(sip_msg
, SIP_EVENT
, NULL
);
648 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
649 if ((fhdr
== NULL
&& thdr
== NULL
) || cihdr
== NULL
|| chdr
== NULL
||
650 (method
== SUBSCRIBE
&& evhdr
== NULL
)) {
652 sip_free_header(thdr
);
657 * Sanity check since we just store the headers in the dialog
659 if (sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
) == NULL
||
660 sip_get_from_uri_str((sip_msg_t
)sip_msg
, NULL
) == NULL
||
661 ((cseq
= sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
)) == -1) ||
662 (callid
= sip_get_callid((sip_msg_t
)sip_msg
, NULL
)) == NULL
||
663 sip_get_to_uri_str((sip_msg_t
)sip_msg
, NULL
) == NULL
||
664 ((value
= sip_get_header_value(chdr
, NULL
)) == NULL
) ||
665 sip_get_contact_uri_str((sip_header_value_t
)value
, NULL
) == NULL
) {
667 sip_free_header(thdr
);
671 tim_obj
= calloc(1, sizeof (sip_dialog_timer_obj_t
));
672 if (tim_obj
== NULL
) {
674 sip_free_header(thdr
);
677 dialog
= calloc(1, sizeof (_sip_dialog_t
));
678 if (dialog
== NULL
) {
680 sip_free_header(thdr
);
684 * We will take the TO header with the tag when we complete this
687 if (dlg_type
== SIP_UAS_DIALOG
) {
688 dialog
->sip_dlg_remote_uri_tag
= thdr
;
690 * We take the remote target from the incoming request on the
691 * UAS. For the UAC, we will take it from the response.
693 if ((dialog
->sip_dlg_remote_target
= sip_dup_header(chdr
)) ==
698 if ((dialog
->sip_dlg_local_uri_tag
= sip_dup_header(fhdr
)) ==
703 * We take the local contact from the originating request on
704 * UAC. For the UAS, we will take it from the response.
706 if ((dialog
->sip_dlg_local_contact
= sip_dup_header(chdr
)) ==
710 dialog
->sip_dlg_new_local_contact
= NULL
;
713 if ((dialog
->sip_dlg_call_id
= sip_dup_header(cihdr
)) == NULL
)
715 if (method
== SUBSCRIBE
) {
716 dialog
->sip_dlg_event
= sip_dup_header(evhdr
);
717 if (dialog
->sip_dlg_event
== NULL
) {
721 dialog
->sip_dlg_rset
.sip_str_ptr
= NULL
;
722 dialog
->sip_dlg_rset
.sip_str_len
= 0;
723 dialog
->sip_dlg_req_uri
.sip_str_ptr
= NULL
;
724 dialog
->sip_dlg_req_uri
.sip_str_len
= 0;
726 * Get the route set from the request, if present
728 if (dlg_type
== SIP_UAS_DIALOG
&&
729 sip_dialog_get_route_set(dialog
, sip_msg
, dlg_type
) != 0) {
732 if (dlg_type
== SIP_UAC_DIALOG
)
733 dialog
->sip_dlg_local_cseq
= cseq
;
735 dialog
->sip_dlg_remote_cseq
= cseq
;
736 dialog
->sip_dlg_type
= dlg_type
;
737 dialog
->sip_dlg_on_fork
= dlg_on_fork
;
738 dialog
->sip_dlg_method
= method
;
740 * Set the partial dialog timer with the INVITE timeout val
742 if (sip_conn_timer1
!= NULL
)
743 timer1
= sip_conn_timer1(obj
);
744 SIP_INIT_TIMER(dialog
->sip_dlg_timer
, 64 * timer1
);
745 tim_obj
->dialog
= dialog
;
747 * Since at the client we never pass the partial dialog, we need not
748 * invoke the callback when the partial dialog self-destructs.
750 if (dlg_type
== SIP_UAS_DIALOG
)
751 tim_obj
->func
= sip_ulp_dlg_del_cb
;
752 SIP_SCHED_TIMER(dialog
->sip_dlg_timer
, (void *)tim_obj
,
753 sip_dlg_self_destruct
);
754 if (!SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
756 (void) pthread_mutex_init(&dialog
->sip_dlg_mutex
, NULL
);
758 if (dlg_type
== SIP_UAC_DIALOG
) {
759 const sip_str_t
*local_tag
;
761 local_tag
= sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
);
762 if (local_tag
== NULL
) {
763 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
764 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
766 assert(local_tag
!= NULL
);
767 sip_md5_hash(local_tag
->sip_str_ptr
, local_tag
->sip_str_len
,
768 callid
->sip_str_ptr
, callid
->sip_str_len
,
769 NULL
, 0, NULL
, 0, NULL
, 0, NULL
, 0,
770 (uchar_t
*)dialog
->sip_dlg_id
);
774 * Add it to the partial hash table
776 if (sip_hash_add(sip_dialog_phash
, (void *)dialog
,
777 SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
)) != 0) {
782 dialog
->sip_dlg_msgcnt
= 1;
783 sip_add_log(&dialog
->sip_dlg_log
[dialog
->sip_dlg_state
],
784 (sip_msg_t
)sip_msg
, dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
786 SIP_DLG_REFCNT_INCR(dialog
);
787 return ((sip_dialog_t
)dialog
);
789 sip_release_dialog_res(dialog
);
790 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
791 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
797 * When creating a dialog from a NOTIFY request, we need to get the FROM
798 * header for the dialog from the TO header of the NOTIFY.
801 sip_dlg_xchg_from_to(sip_msg_t sip_msg
, int what
)
804 _sip_header_t
*newhdr
;
806 const struct sip_header
*hdr
;
810 hdr
= sip_get_header(sip_msg
, what
== SIP_DLG_XCHG_FROM
? SIP_FROM
:
811 SIP_TO
, NULL
, &error
);
812 if (error
!= 0 || hdr
== NULL
)
814 if (sip_parse_goto_values((_sip_header_t
*)hdr
) != 0)
816 len
= hdr
->sip_hdr_end
- hdr
->sip_hdr_current
;
817 if (what
== SIP_DLG_XCHG_FROM
) {
818 hdrsize
= len
+ strlen(SIP_TO
) + SIP_SPACE_LEN
+ sizeof (char) +
821 hdrsize
= len
+ strlen(SIP_FROM
) + SIP_SPACE_LEN
+
822 sizeof (char) + SIP_SPACE_LEN
;
824 newhdr
= sip_new_header(hdrsize
);
827 if (what
== SIP_DLG_XCHG_FROM
) {
828 cnt
= snprintf(newhdr
->sip_hdr_current
, hdrsize
+ 1,
829 "%s %c ", SIP_TO
, SIP_HCOLON
);
831 cnt
= snprintf(newhdr
->sip_hdr_current
, hdrsize
+ 1,
832 "%s %c ", SIP_FROM
, SIP_HCOLON
);
834 newhdr
->sip_hdr_current
+= cnt
;
835 (void) strncpy(newhdr
->sip_hdr_current
, hdr
->sip_hdr_current
, len
);
836 newhdr
->sip_hdr_current
+= len
;
837 assert(newhdr
->sip_hdr_current
== newhdr
->sip_hdr_end
);
838 assert(hdr
->sip_header_functions
!= NULL
);
841 * FROM and TO have common parsing functions
843 newhdr
->sip_header_functions
= hdr
->sip_header_functions
;
844 newhdr
->sip_hdr_current
= newhdr
->sip_hdr_start
;
850 * This is the response that completes the dialog that was created
851 * in sip_seed_dialog().
854 sip_complete_dialog(_sip_msg_t
*sip_msg
, _sip_dialog_t
*dialog
)
857 _sip_header_t
*evhdr
= NULL
;
858 _sip_header_t
*substate
= NULL
;
859 sip_header_t chdr
= NULL
;
861 const sip_str_t
*ttag
;
862 const sip_str_t
*remtag
;
863 const sip_str_t
*callid
;
864 const struct sip_value
*val
;
868 boolean_t alloc_thdr
= B_FALSE
;
870 if (sip_msg_is_request((sip_msg_t
)sip_msg
, &error
) && error
== 0)
871 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
873 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
874 if (error
!= 0 || dialog
== NULL
||
875 (sip_msg_is_request((sip_msg_t
)sip_msg
, &error
) &&
876 (dialog
->sip_dlg_method
== INVITE
|| method
!= NOTIFY
))) {
879 if ((dialog
->sip_dlg_type
== SIP_UAC_DIALOG
&& method
!= NOTIFY
&&
880 sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
) !=
881 dialog
->sip_dlg_local_cseq
) ||
882 (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
&& method
!= NOTIFY
&&
883 sip_get_callseq_num((sip_msg_t
)sip_msg
, NULL
) !=
884 dialog
->sip_dlg_remote_cseq
)) {
887 if (method
== NOTIFY
) {
888 const sip_str_t
*sstate
;
890 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
895 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
896 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
898 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
899 sip_free_header(thdr
);
902 evhdr
= sip_search_for_header(sip_msg
, SIP_EVENT
, NULL
);
904 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
905 sip_free_header(thdr
);
908 substate
= sip_search_for_header(sip_msg
,
909 SIP_SUBSCRIPTION_STATE
, NULL
);
910 if (substate
== NULL
) {
911 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
912 sip_free_header(thdr
);
915 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
916 sstate
= sip_get_substate((sip_msg_t
)sip_msg
, &error
);
917 if (sstate
== NULL
|| error
!= 0) {
918 sip_free_header(thdr
);
921 if ((sstate
->sip_str_len
!= strlen("pending") &&
922 sstate
->sip_str_len
!= strlen("active")) ||
923 ((sstate
->sip_str_len
== strlen("pending") &&
924 strncasecmp(sstate
->sip_str_ptr
, "pending",
925 strlen("pending")) != 0) ||
926 (sstate
->sip_str_len
== strlen("active") &&
927 strncasecmp(sstate
->sip_str_ptr
, "active",
928 strlen("active")) != 0))) {
929 sip_free_header(thdr
);
932 ttag
= sip_get_from_tag((sip_msg_t
)sip_msg
, NULL
);
934 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
935 thdr
= sip_dlg_xchg_from_to((sip_msg_t
)sip_msg
,
939 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
940 thdr
= sip_search_for_header(sip_msg
, SIP_TO
, NULL
);
941 if (dialog
->sip_dlg_remote_target
== NULL
) {
942 chdr
= sip_search_for_header(sip_msg
,
945 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
948 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
951 ttag
= sip_get_to_tag((sip_msg_t
)sip_msg
, NULL
);
955 sip_free_header(thdr
);
958 prev_state
= dialog
->sip_dlg_state
;
960 if (method
== NOTIFY
) {
962 const sip_str_t
*dlg_id_val
= NULL
;
963 const sip_str_t
*event
;
964 const sip_str_t
*id_val
= NULL
;
965 sip_header_value_t ev_val
;
966 sip_hdr_value_t
*dlg_ev_val
= NULL
;
968 event
= sip_get_event((sip_msg_t
)sip_msg
, &error
);
969 if (event
== NULL
|| error
!= 0) {
970 sip_free_header(thdr
);
973 ev_val
= (sip_header_value_t
)sip_get_header_value(evhdr
,
976 id_val
= sip_get_param_value(ev_val
, "id", &error
);
978 dlg_ev_val
= (sip_hdr_value_t
*)sip_get_header_value(
979 dialog
->sip_dlg_event
, &error
);
981 if (dlg_ev_val
== NULL
|| error
!= 0) {
982 sip_free_header(thdr
);
985 dlg_id_val
= sip_get_param_value((sip_header_value_t
)dlg_ev_val
,
988 dlg_ev_val
->str_val_len
!= event
->sip_str_len
||
989 strncmp(dlg_ev_val
->str_val_ptr
, event
->sip_str_ptr
,
990 event
->sip_str_len
!= 0)) {
991 sip_free_header(thdr
);
994 if ((dlg_id_val
== NULL
&& id_val
!= NULL
) ||
995 (dlg_id_val
!= NULL
&& id_val
== NULL
)) {
996 sip_free_header(thdr
);
998 } else if (dlg_id_val
!= NULL
&& id_val
!= NULL
) {
999 if (dlg_id_val
->sip_str_len
!= id_val
->sip_str_len
||
1000 strncasecmp(dlg_id_val
->sip_str_ptr
,
1001 id_val
->sip_str_ptr
, dlg_id_val
->sip_str_len
) !=
1003 sip_free_header(thdr
);
1007 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1008 dialog
->sip_dlg_remote_uri_tag
= thdr
;
1009 if ((dialog
->sip_dlg_remote_target
=
1010 sip_dup_header(chdr
)) == NULL
) {
1011 sip_free_header(thdr
);
1015 dialog
->sip_dlg_local_uri_tag
= thdr
;
1017 dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1019 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1020 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1021 if (dialog
->sip_dlg_state
!= SIP_DLG_NEW
) {
1022 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1023 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1025 assert(dialog
->sip_dlg_state
== SIP_DLG_NEW
);
1026 if (dialog
->sip_dlg_remote_target
== NULL
&& chdr
!= NULL
) {
1027 if (dialog
->sip_dlg_type
!= SIP_UAC_DIALOG
) {
1028 sip_write_to_log((void *)dialog
,
1029 SIP_DIALOG_LOG
| SIP_ASSERT_ERROR
,
1030 __FILE__
, __LINE__
);
1032 assert(dialog
->sip_dlg_type
== SIP_UAC_DIALOG
);
1033 if ((dialog
->sip_dlg_remote_target
=
1034 sip_dup_header(chdr
)) == NULL
) {
1035 (void) pthread_mutex_unlock(
1036 &dialog
->sip_dlg_mutex
);
1038 sip_free_header(thdr
);
1039 goto terminate_new_dlg
;
1041 if (sip_dialog_get_route_set(dialog
, sip_msg
,
1042 dialog
->sip_dlg_type
) != 0) {
1043 (void) pthread_mutex_unlock(
1044 &dialog
->sip_dlg_mutex
);
1046 sip_free_header(thdr
);
1047 goto terminate_new_dlg
;
1050 if (SIP_PROVISIONAL_RESP(resp_code
)) {
1051 dialog
->sip_dlg_state
= SIP_DLG_EARLY
;
1052 } else if (SIP_OK_RESP(resp_code
)) {
1054 * Per 12.1 the UAS must include the contact header
1055 * for a dialog establishing response, so if we
1056 * don't find one, we terminate it.
1058 if (dialog
->sip_dlg_remote_target
== NULL
) {
1059 (void) pthread_mutex_unlock(
1060 &dialog
->sip_dlg_mutex
);
1061 if (sip_ulp_dlg_del_cb
!= NULL
) {
1062 sip_ulp_dlg_del_cb(dialog
,
1063 (sip_msg_t
)sip_msg
, NULL
);
1066 sip_free_header(thdr
);
1067 goto terminate_new_dlg
;
1069 dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1071 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1072 if (sip_ulp_dlg_del_cb
!= NULL
) {
1073 sip_ulp_dlg_del_cb(dialog
, (sip_msg_t
)sip_msg
,
1077 sip_free_header(thdr
);
1078 goto terminate_new_dlg
;
1080 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
1081 dialog
->sip_dlg_local_uri_tag
= thdr
;
1083 if ((dialog
->sip_dlg_remote_uri_tag
=
1084 sip_dup_header(thdr
)) == NULL
) {
1085 (void) pthread_mutex_unlock(
1086 &dialog
->sip_dlg_mutex
);
1087 goto terminate_new_dlg
;
1093 * We take the local contact for UAS Dialog from the response (either
1094 * NOTIFY for SUBSCRIBE request or from final response 2xx to INVITE
1097 if ((dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) && (dialog
->sip_dlg_state
1098 == SIP_DLG_CONFIRMED
)) {
1100 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1101 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
,
1103 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1105 if ((chdr
== NULL
) || ((dialog
->sip_dlg_local_contact
=
1106 sip_dup_header(chdr
)) == NULL
)) {
1107 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1109 sip_free_header(thdr
);
1110 goto terminate_new_dlg
;
1115 * Cancel the partial dialog timer
1117 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
1118 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
1120 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1121 val
= sip_get_header_value(dialog
->sip_dlg_local_uri_tag
,
1124 val
= sip_get_header_value(dialog
->sip_dlg_remote_uri_tag
,
1127 if (val
== NULL
|| error
!= 0) {
1128 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1129 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1131 assert(val
!= NULL
&& error
== 0);
1132 remtag
= sip_get_param_value((sip_header_value_t
)val
, "tag", &error
);
1134 val
= sip_get_header_value(dialog
->sip_dlg_call_id
, &error
);
1135 callid
= &((sip_hdr_value_t
*)val
)->str_val
;
1138 * Get an ID for this dialog
1140 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1141 sip_md5_hash(remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1142 ttag
->sip_str_ptr
, ttag
->sip_str_len
,
1143 callid
->sip_str_ptr
, callid
->sip_str_len
,
1144 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)dialog
->sip_dlg_id
);
1146 sip_md5_hash(ttag
->sip_str_ptr
, ttag
->sip_str_len
,
1147 remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1148 callid
->sip_str_ptr
, callid
->sip_str_len
,
1149 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)dialog
->sip_dlg_id
);
1152 SIP_DLG_REFCNT_INCR(dialog
);
1153 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1156 * Add it to the hash table
1158 if (sip_hash_add(sip_dialog_hash
, (void *)dialog
,
1159 SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
)) != 0) {
1162 * So that sip_dialog_delete() does not try to remove
1163 * this from the hash table.
1165 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1166 if (dialog
->sip_dlg_type
== SIP_UAS_DIALOG
) {
1167 if (dialog
->sip_dlg_local_uri_tag
!= NULL
) {
1168 sip_free_header(dialog
->sip_dlg_local_uri_tag
);
1169 dialog
->sip_dlg_local_uri_tag
= NULL
;
1172 if (dialog
->sip_dlg_remote_uri_tag
!= NULL
) {
1173 sip_free_header(dialog
->sip_dlg_remote_uri_tag
);
1174 dialog
->sip_dlg_remote_uri_tag
= NULL
;
1177 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1178 sip_dialog_terminate(dialog
, (sip_msg_t
)sip_msg
);
1181 if (sip_dlg_ulp_state_cb
!= NULL
) {
1182 sip_dlg_ulp_state_cb((sip_dialog_t
)dialog
,
1183 (sip_msg_t
)sip_msg
, prev_state
, dialog
->sip_dlg_state
);
1185 return ((sip_dialog_t
)dialog
);
1189 * Check if this dialog is a match.
1192 sip_dialog_match(void *obj
, void *hindex
)
1194 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1196 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1197 if (dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
) {
1198 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1201 if (bcmp(dialog
->sip_dlg_id
, hindex
,
1202 sizeof (dialog
->sip_dlg_id
)) == 0) {
1203 SIP_DLG_REFCNT_INCR(dialog
);
1204 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1207 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1212 * Don't delete, just take it out of the hash
1215 sip_dialog_dontfree(void *obj
, void *hindex
, int *found
)
1217 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1220 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1221 if (bcmp(dialog
->sip_dlg_id
, hindex
, sizeof (dialog
->sip_dlg_id
))
1224 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1227 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1232 * Free resources associated with the dialog, the object will be removed
1233 * from the hash list by sip_hash_delete.
1236 sip_dialog_free(void *obj
, void *hindex
, int *found
)
1238 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)obj
;
1241 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1242 if (bcmp(dialog
->sip_dlg_id
, hindex
, sizeof (dialog
->sip_dlg_id
))
1245 if (dialog
->sip_dlg_state
!= SIP_DLG_DESTROYED
) {
1246 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1247 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1249 assert(dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
);
1250 if (dialog
->sip_dlg_ref_cnt
!= 0) {
1251 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1254 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
, NULL
, 0);
1255 sip_release_dialog_res(dialog
);
1258 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1263 * The UAS will receive the request from the transaction layer. If the
1264 * request has a tag in the To header field, the UAS core computes the
1265 * dialog identifier corresponding to the request and compares it with
1266 * existing dialogs. If there is a match, this is a mid-dialog request.
1269 sip_dialog_find(_sip_msg_t
*sip_msg
)
1271 const sip_str_t
*localtag
;
1272 const sip_str_t
*remtag
;
1273 const sip_str_t
*callid
;
1275 _sip_dialog_t
*dialog
;
1276 boolean_t is_request
;
1279 is_request
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1283 localtag
= sip_get_to_tag((sip_msg_t
)sip_msg
, &error
);
1285 remtag
= sip_get_from_tag((sip_msg_t
)sip_msg
, &error
);
1287 remtag
= sip_get_to_tag((sip_msg_t
)sip_msg
, &error
);
1289 localtag
= sip_get_from_tag((sip_msg_t
)sip_msg
, &error
);
1293 callid
= sip_get_callid((sip_msg_t
)sip_msg
, &error
);
1294 if (error
!= 0 || remtag
== NULL
|| localtag
== NULL
||
1298 sip_md5_hash(localtag
->sip_str_ptr
, localtag
->sip_str_len
,
1299 remtag
->sip_str_ptr
, remtag
->sip_str_len
,
1300 callid
->sip_str_ptr
, callid
->sip_str_len
,
1301 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)digest
);
1303 dialog
= (_sip_dialog_t
*)sip_hash_find(sip_dialog_hash
,
1304 (void *)digest
, SIP_DIGEST_TO_HASH(digest
), sip_dialog_match
);
1305 if (dialog
== NULL
) {
1306 sip_md5_hash(localtag
->sip_str_ptr
, localtag
->sip_str_len
,
1307 NULL
, 0, callid
->sip_str_ptr
, callid
->sip_str_len
,
1308 NULL
, 0, NULL
, 0, NULL
, 0, (uchar_t
*)digest
);
1309 dialog
= (_sip_dialog_t
*)sip_hash_find(sip_dialog_phash
,
1310 (void *)digest
, SIP_DIGEST_TO_HASH(digest
),
1313 return ((sip_dialog_t
)dialog
);
1317 * We keep this partial dialog for the duration of the INVITE
1318 * transaction timeout duration, i.e. Timer B.
1321 sip_dlg_self_destruct(void *args
)
1323 sip_dialog_timer_obj_t
*tim_obj
= (sip_dialog_timer_obj_t
*)args
;
1324 _sip_dialog_t
*dialog
= (_sip_dialog_t
*)tim_obj
->dialog
;
1327 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1328 if (dialog
->sip_dlg_state
!= SIP_DLG_NEW
) {
1329 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1330 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1332 assert(dialog
->sip_dlg_state
== SIP_DLG_NEW
);
1333 dialog
->sip_dlg_state
= SIP_DLG_DESTROYED
;
1334 if (dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1335 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1336 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1337 sip_hash_delete(sip_dialog_phash
, (void *)dialog
->sip_dlg_id
,
1338 index
, sip_dialog_dontfree
);
1340 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1342 if (tim_obj
->func
!= NULL
)
1343 tim_obj
->func(dialog
, NULL
, NULL
);
1345 SIP_DLG_REFCNT_DECR(dialog
);
1349 * Terminate a dialog
1352 sip_dialog_terminate(_sip_dialog_t
*dialog
, sip_msg_t sip_msg
)
1356 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1357 prev_state
= dialog
->sip_dlg_state
;
1358 dialog
->sip_dlg_state
= SIP_DLG_DESTROYED
;
1359 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1360 if (sip_dlg_ulp_state_cb
!= NULL
) {
1361 sip_dlg_ulp_state_cb((sip_dialog_t
)dialog
, sip_msg
, prev_state
,
1362 dialog
->sip_dlg_state
);
1364 SIP_DLG_REFCNT_DECR(dialog
);
1371 sip_dialog_delete(_sip_dialog_t
*dialog
)
1376 * partial dialog, not in the hash table
1378 if (dialog
->sip_dlg_local_uri_tag
== NULL
||
1379 dialog
->sip_dlg_remote_uri_tag
== NULL
) {
1381 * Cancel the partial dialog timer
1383 if (SIP_IS_TIMER_RUNNING(dialog
->sip_dlg_timer
))
1384 SIP_CANCEL_TIMER(dialog
->sip_dlg_timer
);
1385 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
, NULL
, 0);
1386 sip_release_dialog_res(dialog
);
1389 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1390 sip_hash_delete(sip_dialog_hash
, (void *)dialog
->sip_dlg_id
, index
,
1395 * Get the remote target from the CONTACT header from the 200 OK response
1398 sip_get_rtarg(_sip_dialog_t
*dialog
, _sip_msg_t
*sip_msg
)
1402 if (dialog
->sip_dlg_remote_target
!= NULL
)
1405 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1406 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
1407 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1410 if ((dialog
->sip_dlg_remote_target
= sip_dup_header(chdr
)) == NULL
)
1417 * Process an incoming request/response
1421 sip_dialog_process(_sip_msg_t
*sip_msg
, sip_dialog_t
*sip_dialog
)
1424 _sip_dialog_t
*_dialog
;
1427 _dialog
= (_sip_dialog_t
*)*sip_dialog
;
1429 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1430 _dialog
->sip_dlg_msgcnt
++;
1431 sip_add_log(&_dialog
->sip_dlg_log
[_dialog
->sip_dlg_state
],
1432 (sip_msg_t
)sip_msg
, _dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
1433 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1435 request
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1440 sip_method_t method
;
1442 cseq
= sip_get_callseq_num((sip_msg_t
)sip_msg
, &error
);
1445 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
1448 if (sip_get_request_method((sip_msg_t
)sip_msg
, &error
) !=
1452 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1454 * Requests that do not change in any way the state
1455 * of a dialog may be received within a dialog.
1456 * They are processed as if they had been received
1457 * outside the dialog.
1458 * For dialogs that have been established with an
1459 * INVITE, the only target refresh request defined is
1462 if (_dialog
->sip_dlg_method
== INVITE
&&
1463 method
== INVITE
&& _dialog
->sip_dlg_remote_cseq
!= 0 &&
1464 SIP_CSEQ_LT(cseq
, _dialog
->sip_dlg_remote_cseq
)) {
1465 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1469 * Target-Refresh request
1471 if (_dialog
->sip_dlg_method
== INVITE
&& method
== INVITE
) {
1475 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1476 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
,
1478 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1480 (nchdr
= sip_dup_header(chdr
)) != NULL
) {
1481 if (_dialog
->sip_dlg_remote_target
!= NULL
) {
1483 _dialog
->sip_dlg_remote_target
);
1485 _dialog
->sip_dlg_remote_target
= nchdr
;
1488 _dialog
->sip_dlg_remote_cseq
= cseq
;
1489 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1492 sip_method_t method
;
1495 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1497 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
,
1503 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1504 if (_dialog
->sip_dlg_state
== SIP_DLG_DESTROYED
) {
1505 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1508 if (_dialog
->sip_dlg_state
!= SIP_DLG_EARLY
&&
1509 _dialog
->sip_dlg_state
!= SIP_DLG_CONFIRMED
) {
1510 sip_write_to_log((void *)_dialog
, SIP_DIALOG_LOG
|
1511 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1513 assert(_dialog
->sip_dlg_state
== SIP_DLG_EARLY
||
1514 _dialog
->sip_dlg_state
== SIP_DLG_CONFIRMED
);
1516 * Let the user delete the dialog if it is not a 1XX/2XX resp
1517 * for an early INVITE dialog.
1519 if (SIP_OK_RESP(resp_code
)) {
1520 if (method
== INVITE
) {
1521 if (!sip_get_rtarg(_dialog
, sip_msg
)) {
1522 (void) pthread_mutex_unlock(
1523 &_dialog
->sip_dlg_mutex
);
1524 if (sip_ulp_dlg_del_cb
!= NULL
) {
1526 (sip_dialog_t
)_dialog
,
1527 (sip_msg_t
)sip_msg
, NULL
);
1529 sip_dialog_terminate(_dialog
,
1530 (sip_msg_t
)sip_msg
);
1533 if (_dialog
->sip_dlg_state
== SIP_DLG_EARLY
) {
1534 _dialog
->sip_dlg_state
=
1536 (void) sip_dlg_recompute_rset(_dialog
,
1537 sip_msg
, SIP_UAC_DIALOG
);
1538 (void) pthread_mutex_unlock(
1539 &_dialog
->sip_dlg_mutex
);
1540 if (sip_dlg_ulp_state_cb
!= NULL
) {
1541 sip_dlg_ulp_state_cb(
1542 (sip_dialog_t
)_dialog
,
1543 sip_msg
, SIP_DLG_EARLY
,
1544 _dialog
->sip_dlg_state
);
1547 } else if (_dialog
->sip_dlg_new_local_contact
1549 if (_dialog
->sip_dlg_local_contact
==
1551 (void) sip_write_to_log((void *)
1552 _dialog
, SIP_DIALOG_LOG
|
1553 SIP_ASSERT_ERROR
, __FILE__
,
1556 assert(_dialog
->sip_dlg_local_contact
1558 sip_free_header(_dialog
->
1559 sip_dlg_local_contact
);
1560 _dialog
->sip_dlg_local_contact
=
1561 _dialog
->sip_dlg_new_local_contact
;
1562 _dialog
->sip_dlg_new_local_contact
=
1567 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1573 * Copy partial dialog to create a complete dialog
1576 sip_copy_partial_dialog(_sip_dialog_t
*dialog
)
1578 _sip_dialog_t
*new_dlg
;
1580 new_dlg
= calloc(1, sizeof (_sip_dialog_t
));
1581 if (new_dlg
== NULL
)
1583 if (dialog
->sip_dlg_req_uri
.sip_str_ptr
!= NULL
) {
1584 new_dlg
->sip_dlg_req_uri
.sip_str_ptr
=
1585 malloc(dialog
->sip_dlg_req_uri
.sip_str_len
+ 1);
1586 if (new_dlg
->sip_dlg_req_uri
.sip_str_ptr
== NULL
) {
1590 (void) strncpy(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
,
1591 dialog
->sip_dlg_req_uri
.sip_str_ptr
,
1592 dialog
->sip_dlg_req_uri
.sip_str_len
);
1593 new_dlg
->sip_dlg_req_uri
.sip_str_ptr
[
1594 dialog
->sip_dlg_req_uri
.sip_str_len
] = '\0';
1595 new_dlg
->sip_dlg_req_uri
.sip_str_len
=
1596 dialog
->sip_dlg_req_uri
.sip_str_len
;
1598 if (dialog
->sip_dlg_route_set
!= NULL
) {
1599 if (dialog
->sip_dlg_rset
.sip_str_ptr
== NULL
) {
1600 sip_write_to_log((void *)dialog
, SIP_DIALOG_LOG
|
1601 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1603 assert(dialog
->sip_dlg_rset
.sip_str_ptr
!= NULL
);
1604 new_dlg
->sip_dlg_rset
.sip_str_ptr
=
1605 malloc(dialog
->sip_dlg_rset
.sip_str_len
+ 1);
1606 if (new_dlg
->sip_dlg_rset
.sip_str_ptr
== NULL
) {
1607 free(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
);
1611 (void) strncpy(new_dlg
->sip_dlg_rset
.sip_str_ptr
,
1612 dialog
->sip_dlg_rset
.sip_str_ptr
,
1613 dialog
->sip_dlg_rset
.sip_str_len
);
1614 new_dlg
->sip_dlg_rset
.sip_str_ptr
[
1615 dialog
->sip_dlg_rset
.sip_str_len
] = '\0';
1616 new_dlg
->sip_dlg_rset
.sip_str_len
=
1617 dialog
->sip_dlg_rset
.sip_str_len
;
1619 new_dlg
->sip_dlg_route_set
=
1620 sip_dup_header(dialog
->sip_dlg_route_set
);
1621 if (new_dlg
->sip_dlg_route_set
== NULL
) {
1622 free(new_dlg
->sip_dlg_rset
.sip_str_ptr
);
1623 free(new_dlg
->sip_dlg_req_uri
.sip_str_ptr
);
1628 if ((new_dlg
->sip_dlg_local_uri_tag
=
1629 sip_dup_header(dialog
->sip_dlg_local_uri_tag
)) == NULL
||
1630 (new_dlg
->sip_dlg_remote_target
=
1631 sip_dup_header(dialog
->sip_dlg_remote_target
)) == NULL
||
1632 (new_dlg
->sip_dlg_local_contact
=
1633 sip_dup_header(dialog
->sip_dlg_local_contact
)) == NULL
||
1634 (new_dlg
->sip_dlg_call_id
=
1635 sip_dup_header(dialog
->sip_dlg_call_id
)) == NULL
) {
1636 sip_release_dialog_res(new_dlg
);
1639 if (dialog
->sip_dlg_event
!= NULL
) {
1640 new_dlg
->sip_dlg_event
= sip_dup_header(dialog
->sip_dlg_event
);
1641 if (new_dlg
->sip_dlg_event
== NULL
) {
1642 sip_release_dialog_res(new_dlg
);
1646 new_dlg
->sip_dlg_local_cseq
= dialog
->sip_dlg_local_cseq
;
1647 new_dlg
->sip_dlg_type
= dialog
->sip_dlg_type
;
1648 new_dlg
->sip_dlg_on_fork
= B_FALSE
;
1649 (void) pthread_mutex_init(&new_dlg
->sip_dlg_mutex
, NULL
);
1655 * Update the dialog using the response
1658 sip_update_dialog(sip_dialog_t dialog
, _sip_msg_t
*sip_msg
)
1660 _sip_dialog_t
*_dialog
;
1662 sip_method_t method
;
1665 boolean_t decr_ref
= B_FALSE
;
1668 _dialog
= (_sip_dialog_t
*)dialog
;
1669 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1670 _dialog
->sip_dlg_msgcnt
++;
1671 sip_add_log(&_dialog
->sip_dlg_log
[_dialog
->sip_dlg_state
],
1672 (sip_msg_t
)sip_msg
, _dialog
->sip_dlg_msgcnt
, SIP_DIALOG_LOG
);
1673 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1675 isreq
= sip_msg_is_request((sip_msg_t
)sip_msg
, &error
);
1678 (void) pthread_mutex_lock(&_dialog
->sip_dlg_mutex
);
1680 method
= sip_get_request_method((sip_msg_t
)sip_msg
, &error
);
1681 if (error
!= 0 || _dialog
->sip_dlg_method
!= SUBSCRIBE
||
1683 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1687 resp_code
= sip_get_response_code((sip_msg_t
)sip_msg
, &error
);
1689 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1692 method
= sip_get_callseq_method((sip_msg_t
)sip_msg
, &error
);
1694 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1698 prev_state
= _dialog
->sip_dlg_state
;
1699 if (_dialog
->sip_dlg_state
== SIP_DLG_CONFIRMED
) {
1700 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1701 } else if (_dialog
->sip_dlg_state
== SIP_DLG_EARLY
) {
1703 * Let the user delete the dialog if it is not a 1XX/2XX resp
1704 * for an early dialog.
1707 sip_write_to_log((void *)_dialog
, SIP_DIALOG_LOG
|
1708 SIP_ASSERT_ERROR
, __FILE__
, __LINE__
);
1711 if (SIP_OK_RESP(resp_code
)) {
1712 _dialog
->sip_dlg_state
= SIP_DLG_CONFIRMED
;
1714 * If we recieved provisional response before we would
1715 * not have captured local contact. So store it now.
1717 if (_dialog
->sip_dlg_type
== SIP_UAS_DIALOG
&& _dialog
->
1718 sip_dlg_method
== INVITE
&& method
== INVITE
) {
1720 (void) pthread_mutex_lock(&sip_msg
->
1722 chdr
= sip_search_for_header(sip_msg
,
1724 (void) pthread_mutex_unlock(&sip_msg
->
1727 _dialog
->sip_dlg_local_contact
1728 = sip_dup_header(chdr
);
1729 _dialog
->sip_dlg_new_local_contact
=
1733 (void) sip_dlg_recompute_rset(_dialog
, sip_msg
,
1735 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1736 if (sip_dlg_ulp_state_cb
!= NULL
) {
1737 sip_dlg_ulp_state_cb(dialog
, (sip_msg_t
)sip_msg
,
1738 prev_state
, dialog
->sip_dlg_state
);
1741 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1743 } else if (_dialog
->sip_dlg_state
== SIP_DLG_NEW
) {
1744 if (!isreq
&& _dialog
->sip_dlg_method
== SUBSCRIBE
&&
1745 SIP_PROVISIONAL_RESP(resp_code
)) {
1746 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1749 if (_dialog
->sip_dlg_type
== SIP_UAC_DIALOG
) {
1750 _sip_dialog_t
*new_dlg
;
1752 if (_dialog
->sip_dlg_on_fork
) {
1753 new_dlg
= sip_copy_partial_dialog(_dialog
);
1754 if (new_dlg
== NULL
) {
1755 (void) pthread_mutex_unlock(
1756 &_dialog
->sip_dlg_mutex
);
1760 * This decr/incr dance is because the caller
1761 * has incremented the ref on the partial
1762 * dialog, we release it here and incr the
1763 * ref on the new dialog which will be
1764 * released by the caller.
1766 (void) pthread_mutex_unlock(
1767 &_dialog
->sip_dlg_mutex
);
1768 SIP_DLG_REFCNT_DECR(_dialog
);
1770 (void) pthread_mutex_lock(
1771 &_dialog
->sip_dlg_mutex
);
1772 SIP_DLG_REFCNT_INCR(_dialog
);
1777 * take it out of the list so that further
1778 * responses will not result in a dialog.
1779 * We will have an extra refcount when we
1780 * come back from sip_complete_dialog(), i.e.
1781 * one when the partial dialog was created -
1782 * in sip_seed_dialog(), one held by the caller
1783 * and one that will be added by
1784 * sip_complete_dialog(). We need to release
1785 * the one added by the sip_seed_dialog(),
1786 * since the one in sip_complete_dialog()
1787 * is for the same purpose.
1789 if (SIP_IS_TIMER_RUNNING(
1790 _dialog
->sip_dlg_timer
)) {
1792 _dialog
->sip_dlg_timer
);
1794 index
= SIP_DIGEST_TO_HASH(dialog
->sip_dlg_id
);
1795 (void) pthread_mutex_unlock(
1796 &_dialog
->sip_dlg_mutex
);
1797 sip_hash_delete(sip_dialog_phash
,
1798 (void *)_dialog
->sip_dlg_id
,
1799 index
, sip_dialog_dontfree
);
1800 (void) pthread_mutex_lock(
1801 &_dialog
->sip_dlg_mutex
);
1807 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1808 if ((dialog
= sip_complete_dialog(sip_msg
, _dialog
)) ==
1810 if (_dialog
->sip_dlg_type
== SIP_UAC_DIALOG
&& decr_ref
)
1811 SIP_DLG_REFCNT_DECR(_dialog
);
1815 SIP_DLG_REFCNT_DECR(_dialog
);
1817 (void) pthread_mutex_unlock(&_dialog
->sip_dlg_mutex
);
1823 * Initialize the hash table
1826 sip_dialog_init(void (*ulp_dlg_del
) (sip_dialog_t
, sip_msg_t
, void *),
1827 void (*ulp_state_cb
)(sip_dialog_t
, sip_msg_t
, int, int))
1831 for (cnt
= 0; cnt
< SIP_HASH_SZ
; cnt
++) {
1832 sip_dialog_hash
[cnt
].hash_count
= 0;
1833 sip_dialog_hash
[cnt
].hash_head
= NULL
;
1834 sip_dialog_hash
[cnt
].hash_tail
= NULL
;
1835 (void) pthread_mutex_init(
1836 &sip_dialog_hash
[cnt
].sip_hash_mutex
, NULL
);
1837 sip_dialog_phash
[cnt
].hash_count
= 0;
1838 sip_dialog_phash
[cnt
].hash_head
= NULL
;
1839 sip_dialog_phash
[cnt
].hash_tail
= NULL
;
1840 (void) pthread_mutex_init(
1841 &sip_dialog_phash
[cnt
].sip_hash_mutex
, NULL
);
1843 if (ulp_dlg_del
!= NULL
)
1844 sip_ulp_dlg_del_cb
= ulp_dlg_del
;
1846 if (ulp_state_cb
!= NULL
)
1847 sip_dlg_ulp_state_cb
= ulp_state_cb
;
1851 * Copy the new contact header of re-INVITE
1854 sip_dialog_add_new_contact(sip_dialog_t dialog
, _sip_msg_t
*sip_msg
)
1856 sip_header_t chdr
= NULL
;
1857 sip_header_t nhdr
= NULL
;
1859 (void) pthread_mutex_lock(&sip_msg
->sip_msg_mutex
);
1860 chdr
= sip_search_for_header(sip_msg
, SIP_CONTACT
, NULL
);
1861 (void) pthread_mutex_unlock(&sip_msg
->sip_msg_mutex
);
1866 (void) pthread_mutex_lock(&dialog
->sip_dlg_mutex
);
1867 if (dialog
->sip_dlg_method
!= INVITE
|| dialog
->sip_dlg_state
1868 != SIP_DLG_CONFIRMED
) {
1869 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1873 if (((nhdr
= sip_dup_header(chdr
)) != NULL
)) {
1874 if (dialog
->sip_dlg_new_local_contact
!= NULL
)
1875 sip_free_header(dialog
->sip_dlg_new_local_contact
);
1876 dialog
->sip_dlg_new_local_contact
= nhdr
;
1878 (void) pthread_mutex_unlock(&dialog
->sip_dlg_mutex
);
1882 * Given a state, return the string - This is mostly for debug purposes
1885 sip_get_dialog_state_str(int state
)
1889 return ("SIP_DLG_NEW");
1891 return ("SIP_DLG_EARLY");
1892 case SIP_DLG_CONFIRMED
:
1893 return ("SIP_DLG_CONFIRMED");
1894 case SIP_DLG_DESTROYED
:
1895 return ("SIP_DLG_DESTROYED");