xref: /titanic_50/usr/src/lib/libsip/common/sip_dialog.c (revision 549ec3fff108310966327d1dc9004551b63210b7)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <pthread.h>
34 #include <strings.h>
35 #include <sip.h>
36 
37 #include "sip_msg.h"
38 #include "sip_miscdefs.h"
39 #include "sip_hash.h"
40 #include "sip_dialog.h"
41 #include "sip_parse_generic.h"
42 
43 #define	SIP_DLG_XCHG_FROM	0
44 #define	SIP_DLG_XCHG_TO		1
45 
46 /*
47  * Dialog state change callback function
48  */
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;
51 
52 boolean_t	sip_incomplete_dialog(sip_dialog_t);
53 
54 /*
55  * Exchange From/To header
56  */
57 _sip_header_t *sip_dlg_xchg_from_to(sip_msg_t, int);
58 
59 /*
60  * Complete dialog hash table
61  */
62 sip_hash_t sip_dialog_hash[SIP_HASH_SZ];
63 
64 /*
65  * Partial dialog hash table
66  */
67 sip_hash_t sip_dialog_phash[SIP_HASH_SZ];
68 
69 /*
70  * Route set structure
71  */
72 typedef struct sip_dlg_route_set_s  {
73 	char		*sip_dlg_route;
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;
77 }sip_dlg_route_set_t;
78 
79 sip_dialog_t		sip_seed_dialog(sip_conn_object_t, _sip_msg_t *,
80 			    boolean_t, int);
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);
90 
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 *,
94 			    int);
95 static void		sip_dialog_free_rset(sip_dlg_route_set_t *);
96 
97 /*
98  * Timer object for partial dialogs
99  */
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;
104 
105 /*
106  * To avoid duplication all over the place
107  */
108 static void
109 sip_release_dialog_res(_sip_dialog_t *dialog)
110 {
111 
112 	assert(dialog->sip_dlg_ref_cnt == 0);
113 	if (SIP_IS_TIMER_RUNNING(dialog->sip_dlg_timer))
114 		SIP_CANCEL_TIMER(dialog->sip_dlg_timer);
115 	if (dialog->sip_dlg_call_id != NULL)
116 		sip_free_header(dialog->sip_dlg_call_id);
117 	if (dialog->sip_dlg_local_uri_tag != NULL)
118 		sip_free_header(dialog->sip_dlg_local_uri_tag);
119 	if (dialog->sip_dlg_remote_uri_tag != NULL)
120 		sip_free_header(dialog->sip_dlg_remote_uri_tag);
121 	if (dialog->sip_dlg_remote_target != NULL)
122 		sip_free_header(dialog->sip_dlg_remote_target);
123 	if (dialog->sip_dlg_route_set != NULL)
124 		sip_free_header(dialog->sip_dlg_route_set);
125 	if (dialog->sip_dlg_event != NULL)
126 		sip_free_header(dialog->sip_dlg_event);
127 	if (dialog->sip_dlg_req_uri.sip_str_ptr != NULL) {
128 		free(dialog->sip_dlg_req_uri.sip_str_ptr);
129 		dialog->sip_dlg_req_uri.sip_str_ptr = NULL;
130 		dialog->sip_dlg_req_uri.sip_str_len = 0;
131 	}
132 	if (dialog->sip_dlg_rset.sip_str_ptr != NULL) {
133 		free(dialog->sip_dlg_rset.sip_str_ptr);
134 		dialog->sip_dlg_rset.sip_str_len = 0;
135 		dialog->sip_dlg_rset.sip_str_ptr = NULL;
136 	}
137 	(void) pthread_mutex_destroy(&dialog->sip_dlg_mutex);
138 	free(dialog);
139 }
140 
141 /*
142  * Get the route information from the 'value' and add it to the route
143  * set.
144  */
145 static sip_dlg_route_set_t *
146 sip_add_route_to_set(sip_hdr_value_t *value)
147 {
148 	int			vlen = 0;
149 	sip_dlg_route_set_t	*rset;
150 	char			*crlf;
151 	const sip_param_t	*uri_param;
152 	int			error;
153 
154 	rset = calloc(1, sizeof (*rset));
155 	if (rset == NULL)
156 		return (NULL);
157 	rset->sip_dlg_route_next = NULL;
158 	vlen = value->sip_value_end - value->sip_value_start;
159 
160 	/*
161 	 * check for CRLF
162 	 */
163 	crlf = value->sip_value_end - strlen(SIP_CRLF);
164 	while (crlf != NULL && strncmp(crlf, SIP_CRLF, strlen(SIP_CRLF)) == 0) {
165 		vlen -= strlen(SIP_CRLF);
166 		crlf -= strlen(SIP_CRLF);
167 	}
168 	rset->sip_dlg_route = calloc(1, vlen + 1);
169 	if (rset->sip_dlg_route == NULL) {
170 		free(rset);
171 		return (NULL);
172 	}
173 	/*
174 	 * loose routing
175 	 */
176 	rset->sip_dlg_route_lr = B_FALSE;
177 	(void) strncpy(rset->sip_dlg_route, value->sip_value_start, vlen);
178 	rset->sip_dlg_ruri.sip_str_ptr = rset->sip_dlg_route +
179 	    (value->cftr_uri.sip_str_ptr - value->sip_value_start);
180 	rset->sip_dlg_ruri.sip_str_len = value->cftr_uri.sip_str_len;
181 	rset->sip_dlg_route[vlen] = '\0';
182 
183 	assert(value->sip_value_parsed_uri != NULL);
184 	/*
185 	 * Check if the 'lr' param is present for this route.
186 	 */
187 	uri_param = sip_get_uri_params(value->sip_value_parsed_uri, &error);
188 	if (error != 0) {
189 		free(rset->sip_dlg_route);
190 		free(rset);
191 		return (NULL);
192 	}
193 	if (uri_param != NULL) {
194 		rset->sip_dlg_route_lr = sip_is_param_present(uri_param, "lr",
195 		    strlen("lr"));
196 	}
197 	return (rset);
198 }
199 
200 /*
201  * Depending on the route-set, determine the request URI.
202  */
203 char *
204 sip_dialog_req_uri(sip_dialog_t dialog)
205 {
206 	const sip_str_t		*req_uri;
207 	char			*uri;
208 	_sip_dialog_t		*_dialog;
209 
210 	_dialog = (_sip_dialog_t *)dialog;
211 	if (_dialog->sip_dlg_route_set == NULL ||
212 	    _dialog->sip_dlg_req_uri.sip_str_ptr == NULL) {
213 		const struct sip_value	*val;
214 
215 		val = sip_get_header_value(_dialog->sip_dlg_remote_target,
216 		    NULL);
217 		if (val == NULL)
218 			return (NULL);
219 		req_uri = &((sip_hdr_value_t *)val)->cftr_uri;
220 	} else {
221 		req_uri = &_dialog->sip_dlg_req_uri;
222 	}
223 	uri = (char *)malloc(req_uri->sip_str_len + 1);
224 	if (uri == NULL)
225 		return (NULL);
226 	(void) strncpy(uri, req_uri->sip_str_ptr, req_uri->sip_str_len);
227 	uri[req_uri->sip_str_len] = '\0';
228 
229 	return (uri);
230 }
231 
232 /*
233  * Free the route set.
234  */
235 void
236 sip_dialog_free_rset(sip_dlg_route_set_t *rset)
237 {
238 	sip_dlg_route_set_t	*next;
239 
240 	while (rset != NULL) {
241 		next = rset->sip_dlg_route_next;
242 		rset->sip_dlg_route_next = NULL;
243 		free(rset->sip_dlg_route);
244 		free(rset);
245 		rset = next;
246 	}
247 }
248 
249 /*
250  * Recompute route-set
251  */
252 static int
253 sip_dlg_recompute_rset(_sip_dialog_t *dialog, _sip_msg_t *sip_msg, int what)
254 {
255 	int ret;
256 
257 	if (dialog->sip_dlg_route_set != NULL) {
258 		sip_free_header(dialog->sip_dlg_route_set);
259 		dialog->sip_dlg_route_set = NULL;
260 	}
261 	if (dialog->sip_dlg_req_uri.sip_str_ptr != NULL) {
262 		free(dialog->sip_dlg_req_uri.sip_str_ptr);
263 		dialog->sip_dlg_req_uri.sip_str_ptr = NULL;
264 		dialog->sip_dlg_req_uri.sip_str_len = 0;
265 	}
266 	if (dialog->sip_dlg_rset.sip_str_ptr != NULL) {
267 		free(dialog->sip_dlg_rset.sip_str_ptr);
268 		dialog->sip_dlg_rset.sip_str_ptr = NULL;
269 		dialog->sip_dlg_rset.sip_str_len = 0;
270 	}
271 	ret = sip_dialog_get_route_set(dialog, sip_msg, what);
272 	return (ret);
273 }
274 
275 /*
276  * If the route set is empty, the UAC MUST place the remote target URI
277  * into the Request-URI.  The UAC MUST NOT add a Route header field to
278  * the request.
279  *
280  * If the route set is not empty, and the first URI in the route set
281  * contains the lr parameter (see Section 19.1.1), the UAC MUST place
282  * the remote target URI into the Request-URI and MUST include a Route
283  * header field containing the route set values in order, including all
284  * parameters.
285  *
286  * If the route set is not empty, and its first URI does not contain the
287  * lr parameter, the UAC MUST place the first URI from the route set
288  * into the Request-URI, stripping any parameters that are not allowed
289  * in a Request-URI.  The UAC MUST add a Route header field containing
290  * the remainder of the route set values in order, including all
291  * parameters.  The UAC MUST then place the remote target URI into the
292  * Route header field as the last value.
293  */
294 int
295 sip_dialog_set_route_hdr(_sip_dialog_t *dialog, sip_dlg_route_set_t *rset_head,
296     int rcnt, int rlen)
297 {
298 	size_t			rset_len;
299 	_sip_header_t		*rhdr;
300 	char			*rset;
301 	char			*rp;
302 	char			*rsp;
303 	int			count;
304 	sip_dlg_route_set_t	*route;
305 	boolean_t		first = B_TRUE;
306 	const sip_str_t		*to_uri;
307 	char			*uri = NULL;
308 	int			rspl;
309 	int			rpl;
310 
311 	assert(rcnt > 0);
312 
313 	dialog->sip_dlg_rset.sip_str_len = rlen + rcnt - 1;
314 	dialog->sip_dlg_rset.sip_str_ptr = malloc(rlen + rcnt);
315 	if (dialog->sip_dlg_rset.sip_str_ptr == NULL)
316 		return (ENOMEM);
317 	rsp = dialog->sip_dlg_rset.sip_str_ptr;
318 	rspl = rlen + rcnt;
319 	route = rset_head;
320 	rset_len = rlen;
321 	if (!route->sip_dlg_route_lr) {
322 		const struct sip_value	*val;
323 
324 		val = sip_get_header_value(dialog->sip_dlg_remote_target, NULL);
325 		to_uri = &((sip_hdr_value_t *)val)->cftr_uri;
326 		uri = (char *)malloc(to_uri->sip_str_len + 1);
327 		if (uri == NULL) {
328 			free(dialog->sip_dlg_rset.sip_str_ptr);
329 			dialog->sip_dlg_rset.sip_str_len = 0;
330 			dialog->sip_dlg_rset.sip_str_ptr = NULL;
331 			return (ENOMEM);
332 		}
333 		(void) strncpy(uri, to_uri->sip_str_ptr, to_uri->sip_str_len);
334 		uri[to_uri->sip_str_len] = '\0';
335 		rset_len = rlen - strlen(route->sip_dlg_route) + strlen(uri) +
336 		    SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN +
337 		    sizeof (char);
338 		count = snprintf(rsp, rspl, "%s", route->sip_dlg_route);
339 		dialog->sip_dlg_req_uri.sip_str_ptr = malloc(
340 		    route->sip_dlg_ruri.sip_str_len + 1);
341 		if (dialog->sip_dlg_req_uri.sip_str_ptr == NULL) {
342 			free(uri);
343 			free(dialog->sip_dlg_rset.sip_str_ptr);
344 			dialog->sip_dlg_rset.sip_str_len = 0;
345 			dialog->sip_dlg_rset.sip_str_ptr = NULL;
346 			return (ENOMEM);
347 		}
348 		(void) strncpy(dialog->sip_dlg_req_uri.sip_str_ptr, rsp +
349 		    (route->sip_dlg_ruri.sip_str_ptr - route->sip_dlg_route),
350 		    route->sip_dlg_ruri.sip_str_len);
351 		dialog->sip_dlg_req_uri.sip_str_ptr[
352 		    route->sip_dlg_ruri.sip_str_len] = '\0';
353 		dialog->sip_dlg_req_uri.sip_str_len =
354 		    route->sip_dlg_ruri.sip_str_len;
355 
356 		rsp += count;
357 		rspl -= count;
358 		route = route->sip_dlg_route_next;
359 	}
360 
361 	/*
362 	 * rcnt - 1 is for the number of COMMAs
363 	 */
364 	rset_len += strlen(SIP_ROUTE) + SIP_SPACE_LEN + sizeof (char) +
365 	    SIP_SPACE_LEN + rcnt - 1;
366 	rset = malloc(rset_len + 1);
367 	if (rset == 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;
371 		return (ENOMEM);
372 	}
373 	rhdr = sip_new_header(rset_len + strlen(SIP_CRLF));
374 	if (rhdr == NULL) {
375 		free(rset);
376 		free(dialog->sip_dlg_rset.sip_str_ptr);
377 		dialog->sip_dlg_rset.sip_str_len = 0;
378 		dialog->sip_dlg_rset.sip_str_ptr = NULL;
379 		return (ENOMEM);
380 	}
381 
382 	rp = rset;
383 	rpl = rset_len + 1;
384 	count = snprintf(rp, rpl, "%s %c ", SIP_ROUTE, SIP_HCOLON);
385 	rp += count;
386 	rpl -= count;
387 
388 	while (route != NULL) {
389 		if (first) {
390 			count = snprintf(rp, rpl, "%s", route->sip_dlg_route);
391 			rp += count;
392 			rpl -= count;
393 			first = B_FALSE;
394 			if (uri != NULL) {
395 				count = snprintf(rsp, rspl, "%c%s",
396 				    SIP_COMMA, route->sip_dlg_route);
397 			} else {
398 				count = snprintf(rsp, rspl, "%s",
399 				    route->sip_dlg_route);
400 			}
401 			rsp += count;
402 			rspl -= count;
403 		} else {
404 			count = snprintf(rp, rpl, "%c%s", SIP_COMMA,
405 			    route->sip_dlg_route);
406 			rp += count;
407 			rpl -= count;
408 			count = snprintf(rsp, rspl, "%c%s", SIP_COMMA,
409 			    route->sip_dlg_route);
410 			rsp += count;
411 			rspl -= count;
412 		}
413 		route = route->sip_dlg_route_next;
414 	}
415 	assert(rsp <= dialog->sip_dlg_rset.sip_str_ptr +
416 	    dialog->sip_dlg_rset.sip_str_len);
417 	dialog->sip_dlg_rset.sip_str_ptr[dialog->sip_dlg_rset.sip_str_len] =
418 	    '\0';
419 	if (uri != NULL) {
420 		if (first) {
421 			count = snprintf(rp, rpl, "%c %s %c", SIP_LAQUOT,
422 			    uri, SIP_RAQUOT);
423 		} else {
424 			count = snprintf(rp, rpl, "%c%c %s %c", SIP_COMMA,
425 			    SIP_LAQUOT, uri, SIP_RAQUOT);
426 		}
427 		rp += count;
428 		rpl -= count;
429 		free(uri);
430 	}
431 	assert(rp <= rset + rset_len);
432 	(void) snprintf(rhdr->sip_hdr_start, rset_len + strlen(SIP_CRLF) + 1,
433 	    "%s%s", rset, SIP_CRLF);
434 	free(rset);
435 	dialog->sip_dlg_route_set = (sip_header_t)rhdr;
436 	sip_dialog_free_rset(rset_head);
437 	return (0);
438 }
439 
440 /*
441  * UAC Behavior
442  * The route set MUST be set to the list of URIs in the Record-Route
443  * header field from the response, taken in reverse order and preserving
444  * all URI parameters.
445  *
446  * UAS behavior
447  * The route set MUST be set to the list of URIs in the Record-Route
448  * header field from the request, taken in order and preserving all URI
449  * parameters.
450  */
451 static int
452 sip_dialog_get_route_set(_sip_dialog_t *dialog, _sip_msg_t *sip_msg, int what)
453 {
454 	sip_header_t		rrhdr;
455 	sip_hdr_value_t		*value;
456 	int			error;
457 	sip_dlg_route_set_t	*rset_head = NULL;
458 	sip_dlg_route_set_t	*rset_tail = NULL;
459 	sip_dlg_route_set_t	*rset;
460 	int			rset_cnt = 0;
461 	int			rset_len = 0;
462 
463 	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
464 	rrhdr = sip_search_for_header(sip_msg, SIP_RECORD_ROUTE, NULL);
465 	while (rrhdr != NULL) {
466 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
467 		value = (sip_hdr_value_t *)sip_get_header_value(rrhdr, &error);
468 		while (value != NULL && error == 0) {
469 			char	*crlf;
470 
471 			if (value->sip_value_state == SIP_VALUE_BAD) {
472 				value = (sip_hdr_value_t *)sip_get_next_value(
473 				    (sip_header_value_t)value, &error);
474 				continue;
475 			}
476 			rset = sip_add_route_to_set(value);
477 			if (rset == NULL)
478 				goto r_error;
479 			/*
480 			 * Add one for COMMA
481 			 */
482 			rset_cnt++;
483 			rset_len += (value->sip_value_end -
484 			    value->sip_value_start);
485 			/*
486 			 * Check for CRLF
487 			 */
488 			crlf = value->sip_value_end - strlen(SIP_CRLF);
489 			while (crlf != NULL &&
490 			    strncmp(crlf, SIP_CRLF, strlen(SIP_CRLF)) == 0) {
491 				rset_len -= strlen(SIP_CRLF);
492 				crlf -= strlen(SIP_CRLF);
493 			}
494 			if (rset_head == NULL) {
495 				assert(rset_tail == NULL);
496 				rset_head = rset_tail = rset;
497 			} else if (what == SIP_UAS_DIALOG) {
498 				rset_tail->sip_dlg_route_next = rset;
499 				rset_tail = rset;
500 			} else if (what == SIP_UAC_DIALOG) {
501 				rset->sip_dlg_route_next = rset_head;
502 				rset_head = rset;
503 			} else {
504 				assert(0);
505 			}
506 			value = (sip_hdr_value_t *)sip_get_next_value(
507 			    (sip_header_value_t)value, &error);
508 		}
509 		(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
510 		rrhdr = sip_search_for_header(sip_msg, SIP_RECORD_ROUTE, rrhdr);
511 	}
512 	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
513 	if (rset_cnt == 0)
514 		return (0);
515 	if (sip_dialog_set_route_hdr(dialog, rset_head, rset_cnt,
516 	    rset_len) != 0) {
517 		goto r_error;
518 	}
519 	return (0);
520 r_error:
521 	sip_dialog_free_rset(rset_head);
522 	return (ENOMEM);
523 }
524 
525 /*
526  * UAS behavior:
527  * The remote sequence number MUST be set to the value of the sequence
528  * number in the CSeq header field of the request.  The local sequence
529  * number MUST be empty.  The call identifier component of the dialog ID
530  * MUST be set to the value of the Call-ID in the request.  The local
531  * tag component of the dialog ID MUST be set to the tag in the To field
532  * in the response to the request (which always includes a tag), and the
533  * remote tag component of the dialog ID MUST be set to the tag from the
534  * From field in the request.  A UAS MUST be prepared to receive a
535  * request without a tag in the From field, in which case the tag is
536  * considered to have a value of null.
537  * The remote URI MUST be set to the URI in the From field, and the
538  * local URI MUST be set to the URI in the To field.
539  * The remote target MUST be set to the URI from the Contact header field
540  * of the request.
541  *
542  * UAC behavior:
543  * The local sequence number MUST be set to the value of the sequence
544  * number in the CSeq header field of the request.  The remote sequence
545  * number MUST be empty (it is established when the remote UA sends a
546  * request within the dialog).  The call identifier component of the
547  * dialog ID MUST be set to the value of the Call-ID in the request.
548  * The local tag component of the dialog ID MUST be set to the tag in
549  * the From field in the request, and the remote tag component of the
550  * dialog ID MUST be set to the tag in the To field of the response.  A
551  * UAC MUST be prepared to receive a response without a tag in the To
552  * field, in which case the tag is considered to have a value of null.
553  * The remote URI MUST be set to the URI in the To field, and the local
554  * URI MUST be set to the URI in the From field.
555  * The remote target MUST be set to the URI from the Contact header field
556  * of the response.
557  */
558 
559 
560 /*
561  * This is the routine that seeds a dialog.
562  */
563 sip_dialog_t
564 sip_seed_dialog(sip_conn_object_t obj, _sip_msg_t *sip_msg,
565     boolean_t dlg_on_fork, int dlg_type)
566 {
567 	_sip_dialog_t		*dialog;
568 	int			cseq;
569 	sip_header_t		fhdr = NULL;
570 	sip_header_t		thdr = NULL;
571 	sip_header_t		chdr;
572 	sip_header_t		cihdr;
573 	sip_header_t		evhdr = NULL;
574 	const struct sip_value	*value;
575 	sip_dialog_timer_obj_t	*tim_obj = NULL;
576 	const sip_str_t		*callid;
577 	sip_method_t		method;
578 	int			timer1 = sip_timer_T1;
579 	int			error;
580 
581 	if (!sip_msg_is_request((sip_msg_t)sip_msg, &error))
582 		return (NULL);
583 
584 	method = sip_get_request_method((sip_msg_t)sip_msg, &error);
585 	/*
586 	 * Only INVITE and SUBSCRIBE supported
587 	 */
588 	if (error != 0 || (method != INVITE && method != SUBSCRIBE))
589 		return (NULL);
590 
591 	/*
592 	 * A request outside of a dialog MUST NOT contain a To tag
593 	 */
594 	if (sip_get_to_tag((sip_msg_t)sip_msg, NULL) != NULL)
595 		return (NULL);
596 
597 	if (dlg_type == SIP_UAS_DIALOG) {
598 		thdr = sip_dlg_xchg_from_to((sip_msg_t)sip_msg,
599 		    SIP_DLG_XCHG_FROM);
600 		(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
601 	} else {
602 		(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
603 		fhdr = sip_search_for_header(sip_msg, SIP_FROM, NULL);
604 	}
605 	cihdr = sip_search_for_header(sip_msg, SIP_CALL_ID, NULL);
606 	chdr = sip_search_for_header(sip_msg, SIP_CONTACT, NULL);
607 	if (method == SUBSCRIBE)
608 		evhdr = sip_search_for_header(sip_msg, SIP_EVENT, NULL);
609 	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
610 	if ((fhdr == NULL && thdr == NULL) || cihdr == NULL || chdr == NULL ||
611 	    (method == SUBSCRIBE && evhdr == NULL)) {
612 		if (thdr != NULL)
613 			sip_free_header(thdr);
614 		return (NULL);
615 	}
616 
617 	/*
618 	 * Sanity check since we just store the headers in the dialog
619 	 */
620 	if (sip_get_from_tag((sip_msg_t)sip_msg, NULL) == NULL ||
621 	    sip_get_from_uri_str((sip_msg_t)sip_msg, NULL) == NULL ||
622 	    ((cseq = sip_get_callseq_num((sip_msg_t)sip_msg, NULL)) == -1) ||
623 	    (callid = sip_get_callid((sip_msg_t)sip_msg, NULL)) == NULL ||
624 	    sip_get_to_uri_str((sip_msg_t)sip_msg, NULL) == NULL ||
625 	    ((value = sip_get_header_value(chdr, NULL)) == NULL) ||
626 	    sip_get_contact_uri_str((sip_header_value_t)value, NULL) == NULL) {
627 		if (thdr != NULL)
628 			sip_free_header(thdr);
629 		return (NULL);
630 	}
631 
632 	tim_obj = calloc(1, sizeof (sip_dialog_timer_obj_t));
633 	if (tim_obj == NULL) {
634 		if (thdr != NULL)
635 			sip_free_header(thdr);
636 		return (NULL);
637 	}
638 	dialog = calloc(1, sizeof (_sip_dialog_t));
639 	if (dialog == NULL) {
640 		if (thdr != NULL)
641 			sip_free_header(thdr);
642 		return (NULL);
643 	}
644 	/*
645 	 * We will take the TO header with the tag when we complete this
646 	 * dialog
647 	 */
648 	if (dlg_type == SIP_UAS_DIALOG) {
649 		dialog->sip_dlg_remote_uri_tag = thdr;
650 		/*
651 		 * We take the remote target from the incoming request on the
652 		 * UAS. For the UAC, we will take it from the response.
653 		 */
654 		if ((dialog->sip_dlg_remote_target = sip_dup_header(chdr)) ==
655 		    NULL) {
656 			goto dia_err;
657 		}
658 	} else {
659 		if ((dialog->sip_dlg_local_uri_tag = sip_dup_header(fhdr)) ==
660 		    NULL) {
661 			goto dia_err;
662 		}
663 	}
664 	if ((dialog->sip_dlg_call_id = sip_dup_header(cihdr)) == NULL)
665 		goto dia_err;
666 	if (method == SUBSCRIBE) {
667 		dialog->sip_dlg_event = sip_dup_header(evhdr);
668 		if (dialog->sip_dlg_event == NULL) {
669 			goto dia_err;
670 		}
671 	}
672 	dialog->sip_dlg_rset.sip_str_ptr = NULL;
673 	dialog->sip_dlg_rset.sip_str_len = 0;
674 	dialog->sip_dlg_req_uri.sip_str_ptr = NULL;
675 	dialog->sip_dlg_req_uri.sip_str_len = 0;
676 	/*
677 	 * Get the route set from the request, if present
678 	 */
679 	if (dlg_type == SIP_UAS_DIALOG &&
680 	    sip_dialog_get_route_set(dialog, sip_msg, dlg_type) != 0) {
681 		goto dia_err;
682 	}
683 	if (dlg_type == SIP_UAC_DIALOG)
684 		dialog->sip_dlg_local_cseq = cseq;
685 	else
686 		dialog->sip_dlg_remote_cseq = cseq;
687 	dialog->sip_dlg_type = dlg_type;
688 	dialog->sip_dlg_on_fork = dlg_on_fork;
689 	dialog->sip_dlg_method = method;
690 	/*
691 	 * Set the partial dialog timer with the INVITE timeout val
692 	 */
693 	if (sip_conn_timer1 != NULL)
694 		timer1 = sip_conn_timer1(obj);
695 	SIP_INIT_TIMER(dialog->sip_dlg_timer, 64 * timer1);
696 	tim_obj->dialog = dialog;
697 	/*
698 	 * Since at the client we never pass the partial dialog, we need not
699 	 * invoke the callback when the partial dialog self-destructs.
700 	 */
701 	if (dlg_type == SIP_UAS_DIALOG)
702 		tim_obj->func = sip_ulp_dlg_del_cb;
703 	SIP_SCHED_TIMER(dialog->sip_dlg_timer, (void *)tim_obj,
704 	    sip_dlg_self_destruct);
705 	if (!SIP_IS_TIMER_RUNNING(dialog->sip_dlg_timer))
706 		goto dia_err;
707 	(void) pthread_mutex_init(&dialog->sip_dlg_mutex, NULL);
708 
709 	if (dlg_type == SIP_UAC_DIALOG) {
710 		const sip_str_t	*local_tag;
711 
712 		local_tag = sip_get_from_tag((sip_msg_t)sip_msg, NULL);
713 		assert(local_tag != NULL);
714 		sip_md5_hash(local_tag->sip_str_ptr, local_tag->sip_str_len,
715 		    callid->sip_str_ptr, callid->sip_str_len,
716 		    NULL, 0, NULL, 0, NULL, 0, NULL, 0,
717 		    (uchar_t *)dialog->sip_dlg_id);
718 
719 
720 		/*
721 		 * Add it to the partial hash table
722 		 */
723 		if (sip_hash_add(sip_dialog_phash, (void *)dialog,
724 		    SIP_DIGEST_TO_HASH(dialog->sip_dlg_id)) != 0) {
725 			goto dia_err;
726 		}
727 	}
728 	SIP_DLG_REFCNT_INCR(dialog);
729 	return ((sip_dialog_t)dialog);
730 dia_err:
731 	sip_release_dialog_res(dialog);
732 	if (SIP_IS_TIMER_RUNNING(dialog->sip_dlg_timer))
733 		SIP_CANCEL_TIMER(dialog->sip_dlg_timer);
734 	if (tim_obj != NULL)
735 		free(tim_obj);
736 	return (NULL);
737 }
738 
739 /*
740  * When creating a dialog from a NOTIFY request, we need to get the FROM
741  * header for the dialog from the TO header of the NOTIFY.
742  */
743 _sip_header_t *
744 sip_dlg_xchg_from_to(sip_msg_t sip_msg, int what)
745 {
746 	int			len;
747 	_sip_header_t		*newhdr;
748 	int			cnt;
749 	const struct sip_header	*hdr;
750 	int			hdrsize;
751 	int			error;
752 
753 	hdr = sip_get_header(sip_msg, what == SIP_DLG_XCHG_FROM ? SIP_FROM :
754 	    SIP_TO, NULL, &error);
755 	if (error != 0 || hdr == NULL)
756 		return (NULL);
757 	if (sip_parse_goto_values((_sip_header_t *)hdr) != 0)
758 		return (NULL);
759 	len = hdr->sip_hdr_end - hdr->sip_hdr_current;
760 	if (what == SIP_DLG_XCHG_FROM) {
761 		hdrsize = len + strlen(SIP_TO) + SIP_SPACE_LEN + sizeof (char) +
762 		    SIP_SPACE_LEN;
763 	} else {
764 		hdrsize = len + strlen(SIP_FROM) + SIP_SPACE_LEN +
765 		    sizeof (char) + SIP_SPACE_LEN;
766 	}
767 	newhdr = sip_new_header(hdrsize);
768 	if (newhdr == NULL)
769 		return (NULL);
770 	if (what == SIP_DLG_XCHG_FROM) {
771 		cnt = snprintf(newhdr->sip_hdr_current, hdrsize + 1,
772 		    "%s %c ", SIP_TO, SIP_HCOLON);
773 	} else {
774 		cnt = snprintf(newhdr->sip_hdr_current, hdrsize + 1,
775 		    "%s %c ", SIP_FROM, SIP_HCOLON);
776 	}
777 	newhdr->sip_hdr_current += cnt;
778 	(void) strncpy(newhdr->sip_hdr_current, hdr->sip_hdr_current, len);
779 	newhdr->sip_hdr_current += len;
780 	assert(newhdr->sip_hdr_current == newhdr->sip_hdr_end);
781 	assert(hdr->sip_header_functions != NULL);
782 
783 	/*
784 	 * FROM and TO have common parsing functions
785 	 */
786 	newhdr->sip_header_functions = hdr->sip_header_functions;
787 	newhdr->sip_hdr_current = newhdr->sip_hdr_start;
788 
789 	return (newhdr);
790 }
791 
792 /*
793  * This is the response that completes the dialog that was created
794  * in sip_seed_dialog().
795  */
796 sip_dialog_t
797 sip_complete_dialog(_sip_msg_t *sip_msg, _sip_dialog_t *dialog)
798 {
799 	_sip_header_t		*thdr;
800 	_sip_header_t		*evhdr = NULL;
801 	_sip_header_t		*substate = NULL;
802 	sip_header_t		chdr = NULL;
803 	int			resp_code;
804 	const sip_str_t		*ttag;
805 	const sip_str_t		*remtag;
806 	const sip_str_t		*callid;
807 	const struct sip_value 	*val;
808 	sip_method_t		method;
809 	int			error = 0;
810 	int			prev_state;
811 	boolean_t		alloc_thdr = B_FALSE;
812 
813 	if (sip_msg_is_request((sip_msg_t)sip_msg, &error) && error == 0)
814 		method = sip_get_request_method((sip_msg_t)sip_msg, &error);
815 	else
816 		method = sip_get_callseq_method((sip_msg_t)sip_msg, &error);
817 	if (error != 0 || dialog == NULL ||
818 	    (sip_msg_is_request((sip_msg_t)sip_msg, &error) &&
819 	    (dialog->sip_dlg_method == INVITE || method != NOTIFY))) {
820 		return (NULL);
821 	}
822 	if ((dialog->sip_dlg_type == SIP_UAC_DIALOG && method != NOTIFY &&
823 	    sip_get_callseq_num((sip_msg_t)sip_msg, NULL) !=
824 	    dialog->sip_dlg_local_cseq) ||
825 	    (dialog->sip_dlg_type == SIP_UAS_DIALOG && method != NOTIFY &&
826 	    sip_get_callseq_num((sip_msg_t)sip_msg, NULL) !=
827 	    dialog->sip_dlg_remote_cseq)) {
828 		return (NULL);
829 	}
830 	if (method == NOTIFY) {
831 		const sip_str_t	*sstate;
832 
833 		thdr = sip_dlg_xchg_from_to((sip_msg_t)sip_msg,
834 		    SIP_DLG_XCHG_FROM);
835 		if (thdr == NULL)
836 			return (NULL);
837 		alloc_thdr = B_TRUE;
838 		(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
839 		chdr = sip_search_for_header(sip_msg, SIP_CONTACT, NULL);
840 		if (chdr == NULL) {
841 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
842 			sip_free_header(thdr);
843 			return (NULL);
844 		}
845 		evhdr = sip_search_for_header(sip_msg, SIP_EVENT, NULL);
846 		if (evhdr == NULL) {
847 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
848 			sip_free_header(thdr);
849 			return (NULL);
850 		}
851 		substate = sip_search_for_header(sip_msg,
852 		    SIP_SUBSCRIPTION_STATE, NULL);
853 		if (substate == NULL) {
854 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
855 			sip_free_header(thdr);
856 			return (NULL);
857 		}
858 		(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
859 		sstate = sip_get_substate((sip_msg_t)sip_msg, &error);
860 		if (sstate == NULL || error != 0) {
861 			sip_free_header(thdr);
862 			return (NULL);
863 		}
864 		if ((sstate->sip_str_len != strlen("pending") &&
865 		    sstate->sip_str_len != strlen("active")) ||
866 		    ((sstate->sip_str_len == strlen("pending") &&
867 		    strncasecmp(sstate->sip_str_ptr, "pending",
868 		    strlen("pending")) != 0) ||
869 		    (sstate->sip_str_len == strlen("active") &&
870 		    strncasecmp(sstate->sip_str_ptr, "active",
871 		    strlen("active")) != 0))) {
872 			sip_free_header(thdr);
873 			return (NULL);
874 		}
875 		ttag = sip_get_from_tag((sip_msg_t)sip_msg, NULL);
876 	} else {
877 		if (dialog->sip_dlg_type == SIP_UAS_DIALOG) {
878 			thdr = sip_dlg_xchg_from_to((sip_msg_t)sip_msg,
879 			    SIP_DLG_XCHG_TO);
880 			alloc_thdr = B_TRUE;
881 		} else {
882 			(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
883 			thdr = sip_search_for_header(sip_msg, SIP_TO, NULL);
884 			if (dialog->sip_dlg_remote_target == NULL) {
885 				chdr = sip_search_for_header(sip_msg,
886 				    SIP_CONTACT, NULL);
887 			}
888 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
889 		}
890 		if (thdr == NULL) {
891 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
892 			return (NULL);
893 		}
894 		ttag = sip_get_to_tag((sip_msg_t)sip_msg, NULL);
895 	}
896 	if (ttag == NULL) {
897 		if (alloc_thdr)
898 			sip_free_header(thdr);
899 		return (NULL);
900 	}
901 	prev_state = dialog->sip_dlg_state;
902 
903 	if (method == NOTIFY) {
904 		int			error;
905 		const sip_str_t		*dlg_id_val = NULL;
906 		const sip_str_t		*event;
907 		const sip_str_t		*id_val = NULL;
908 		sip_header_value_t	ev_val;
909 		sip_hdr_value_t		*dlg_ev_val = NULL;
910 
911 		event = sip_get_event((sip_msg_t)sip_msg, &error);
912 		if (event == NULL || error != 0) {
913 			sip_free_header(thdr);
914 			return (NULL);
915 		}
916 		ev_val = (sip_header_value_t)sip_get_header_value(evhdr,
917 		    &error);
918 		if (ev_val != NULL)
919 			id_val = sip_get_param_value(ev_val, "id", &error);
920 		if (error == 0) {
921 			dlg_ev_val = (sip_hdr_value_t *)sip_get_header_value(
922 			    dialog->sip_dlg_event, &error);
923 		}
924 		if (dlg_ev_val == NULL || error != 0) {
925 			sip_free_header(thdr);
926 			return (NULL);
927 		}
928 		dlg_id_val = sip_get_param_value((sip_header_value_t)dlg_ev_val,
929 		    "id", &error);
930 		if (error != 0 ||
931 		    dlg_ev_val->str_val_len != event->sip_str_len ||
932 		    strncmp(dlg_ev_val->str_val_ptr, event->sip_str_ptr,
933 		    event->sip_str_len != 0)) {
934 			sip_free_header(thdr);
935 			return (NULL);
936 		}
937 		if ((dlg_id_val == NULL && id_val != NULL) ||
938 		    (dlg_id_val != NULL && id_val == NULL)) {
939 			sip_free_header(thdr);
940 			return (NULL);
941 		} else if (dlg_id_val != NULL && id_val != NULL) {
942 			if (dlg_id_val->sip_str_len != id_val->sip_str_len ||
943 			    strncasecmp(dlg_id_val->sip_str_ptr,
944 			    id_val->sip_str_ptr, dlg_id_val->sip_str_len) !=
945 			    0) {
946 				sip_free_header(thdr);
947 				return (NULL);
948 			}
949 		}
950 		if (dialog->sip_dlg_type == SIP_UAC_DIALOG) {
951 			dialog->sip_dlg_remote_uri_tag = thdr;
952 			if ((dialog->sip_dlg_remote_target =
953 			    sip_dup_header(chdr)) == NULL) {
954 				sip_free_header(thdr);
955 				return (NULL);
956 			}
957 		} else {
958 			dialog->sip_dlg_local_uri_tag = thdr;
959 		}
960 		dialog->sip_dlg_state = SIP_DLG_CONFIRMED;
961 	} else {
962 		resp_code = sip_get_response_code((sip_msg_t)sip_msg, &error);
963 		(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
964 		assert(dialog->sip_dlg_state == SIP_DLG_NEW);
965 		if (dialog->sip_dlg_remote_target == NULL && chdr != NULL) {
966 			assert(dialog->sip_dlg_type == SIP_UAC_DIALOG);
967 			if ((dialog->sip_dlg_remote_target =
968 			    sip_dup_header(chdr)) == NULL) {
969 				(void) pthread_mutex_unlock(
970 				    &dialog->sip_dlg_mutex);
971 				if (alloc_thdr)
972 					sip_free_header(thdr);
973 				goto terminate_new_dlg;
974 			}
975 			if (sip_dialog_get_route_set(dialog, sip_msg,
976 			    dialog->sip_dlg_type) != 0) {
977 				(void) pthread_mutex_unlock(
978 				    &dialog->sip_dlg_mutex);
979 				if (alloc_thdr)
980 					sip_free_header(thdr);
981 				goto terminate_new_dlg;
982 			}
983 		}
984 		if (SIP_PROVISIONAL_RESP(resp_code)) {
985 			dialog->sip_dlg_state = SIP_DLG_EARLY;
986 		} else if (SIP_OK_RESP(resp_code)) {
987 			/*
988 			 * Per 12.1 the UAS must include the contact header
989 			 * for a dialog establishing response, so if we
990 			 * don't find one, we terminate it.
991 			 */
992 			if (dialog->sip_dlg_remote_target == NULL) {
993 				(void) pthread_mutex_unlock(
994 				    &dialog->sip_dlg_mutex);
995 				if (sip_ulp_dlg_del_cb != NULL) {
996 					sip_ulp_dlg_del_cb(dialog,
997 					    (sip_msg_t)sip_msg, NULL);
998 				}
999 				if (alloc_thdr)
1000 					sip_free_header(thdr);
1001 				goto terminate_new_dlg;
1002 			}
1003 			dialog->sip_dlg_state = SIP_DLG_CONFIRMED;
1004 		} else {
1005 			(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1006 			if (sip_ulp_dlg_del_cb != NULL) {
1007 				sip_ulp_dlg_del_cb(dialog, (sip_msg_t)sip_msg,
1008 				    NULL);
1009 			}
1010 			if (alloc_thdr)
1011 				sip_free_header(thdr);
1012 			goto terminate_new_dlg;
1013 		}
1014 		if (dialog->sip_dlg_type == SIP_UAS_DIALOG) {
1015 			dialog->sip_dlg_local_uri_tag = thdr;
1016 		} else {
1017 			if ((dialog->sip_dlg_remote_uri_tag =
1018 			    sip_dup_header(thdr)) == NULL) {
1019 				(void) pthread_mutex_unlock(
1020 				    &dialog->sip_dlg_mutex);
1021 				goto terminate_new_dlg;
1022 			}
1023 		}
1024 	}
1025 
1026 	/*
1027 	 * Cancel the partial dialog timer
1028 	 */
1029 	if (SIP_IS_TIMER_RUNNING(dialog->sip_dlg_timer))
1030 		SIP_CANCEL_TIMER(dialog->sip_dlg_timer);
1031 
1032 	if (dialog->sip_dlg_type == SIP_UAC_DIALOG) {
1033 		val =  sip_get_header_value(dialog->sip_dlg_local_uri_tag,
1034 		    &error);
1035 	} else {
1036 		val =  sip_get_header_value(dialog->sip_dlg_remote_uri_tag,
1037 		    &error);
1038 	}
1039 	assert(val != NULL && error == 0);
1040 	remtag = sip_get_param_value((sip_header_value_t)val, "tag", &error);
1041 
1042 	val = sip_get_header_value(dialog->sip_dlg_call_id, &error);
1043 	callid = &((sip_hdr_value_t *)val)->str_val;
1044 
1045 	/*
1046 	 * Get an ID for this dialog
1047 	 */
1048 	if (dialog->sip_dlg_type == SIP_UAC_DIALOG) {
1049 		sip_md5_hash(remtag->sip_str_ptr, remtag->sip_str_len,
1050 		    ttag->sip_str_ptr, ttag->sip_str_len,
1051 		    callid->sip_str_ptr, callid->sip_str_len,
1052 		    NULL, 0, NULL, 0, NULL, 0, (uchar_t *)dialog->sip_dlg_id);
1053 	} else {
1054 		sip_md5_hash(ttag->sip_str_ptr, ttag->sip_str_len,
1055 		    remtag->sip_str_ptr, remtag->sip_str_len,
1056 		    callid->sip_str_ptr, callid->sip_str_len,
1057 		    NULL, 0, NULL, 0, NULL, 0, (uchar_t *)dialog->sip_dlg_id);
1058 	}
1059 
1060 	SIP_DLG_REFCNT_INCR(dialog);
1061 	(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1062 
1063 	/*
1064 	 * Add it to the hash table
1065 	 */
1066 	if (sip_hash_add(sip_dialog_hash, (void *)dialog,
1067 	    SIP_DIGEST_TO_HASH(dialog->sip_dlg_id)) != 0) {
1068 	terminate_new_dlg:
1069 		/*
1070 		 * So that sip_dialog_delete() does not try to remove
1071 		 * this from the hash table.
1072 		 */
1073 		(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1074 		if (dialog->sip_dlg_type == SIP_UAS_DIALOG) {
1075 			if (dialog->sip_dlg_local_uri_tag != NULL) {
1076 				sip_free_header(dialog->sip_dlg_local_uri_tag);
1077 				dialog->sip_dlg_local_uri_tag = NULL;
1078 			}
1079 		} else {
1080 			if (dialog->sip_dlg_remote_uri_tag != NULL) {
1081 				sip_free_header(dialog->sip_dlg_remote_uri_tag);
1082 				dialog->sip_dlg_remote_uri_tag = NULL;
1083 			}
1084 		}
1085 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1086 		sip_dialog_terminate(dialog, (sip_msg_t)sip_msg);
1087 		return (NULL);
1088 	}
1089 	if (sip_dlg_ulp_state_cb != NULL) {
1090 		sip_dlg_ulp_state_cb((sip_dialog_t)dialog,
1091 		    (sip_msg_t)sip_msg, prev_state, dialog->sip_dlg_state);
1092 	}
1093 	return ((sip_dialog_t)dialog);
1094 }
1095 
1096 /*
1097  * Check if this dialog is a match.
1098  */
1099 boolean_t
1100 sip_dialog_match(void *obj, void *hindex)
1101 {
1102 	_sip_dialog_t	*dialog = (_sip_dialog_t *)obj;
1103 
1104 	(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1105 	if (dialog->sip_dlg_state == SIP_DLG_DESTROYED) {
1106 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1107 		return (B_FALSE);
1108 	}
1109 	if (bcmp(dialog->sip_dlg_id, hindex,
1110 	    sizeof (dialog->sip_dlg_id)) == 0) {
1111 		SIP_DLG_REFCNT_INCR(dialog);
1112 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1113 		return (B_TRUE);
1114 	}
1115 	(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1116 	return (B_FALSE);
1117 }
1118 
1119 /*
1120  * Don't delete, just take it out of the hash
1121  */
1122 boolean_t
1123 sip_dialog_dontfree(void *obj, void *hindex, int *found)
1124 {
1125 	_sip_dialog_t	*dialog = (_sip_dialog_t *)obj;
1126 
1127 	*found = 0;
1128 	(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1129 	if (bcmp(dialog->sip_dlg_id, hindex, sizeof (dialog->sip_dlg_id))
1130 	    == 0) {
1131 		*found = 1;
1132 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1133 		return (B_TRUE);
1134 	}
1135 	(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1136 	return (B_FALSE);
1137 }
1138 
1139 /*
1140  * Free resources associated with the dialog, the object will be removed
1141  * from the hash list by sip_hash_delete.
1142  */
1143 boolean_t
1144 sip_dialog_free(void *obj, void *hindex, int *found)
1145 {
1146 	_sip_dialog_t	*dialog = (_sip_dialog_t *)obj;
1147 
1148 	*found = 0;
1149 	(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1150 	if (bcmp(dialog->sip_dlg_id, hindex, sizeof (dialog->sip_dlg_id))
1151 	    == 0) {
1152 		*found = 1;
1153 		assert(dialog->sip_dlg_state == SIP_DLG_DESTROYED);
1154 		if (dialog->sip_dlg_ref_cnt != 0) {
1155 			(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1156 			return (B_FALSE);
1157 		}
1158 		sip_release_dialog_res(dialog);
1159 		return (B_TRUE);
1160 	}
1161 	(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1162 	return (B_FALSE);
1163 }
1164 
1165 /*
1166  * The UAS will receive the request from the transaction layer.  If the
1167  * request has a tag in the To header field, the UAS core computes the
1168  * dialog identifier corresponding to the request and compares it with
1169  * existing dialogs.  If there is a match, this is a mid-dialog request.
1170  */
1171 sip_dialog_t
1172 sip_dialog_find(_sip_msg_t *sip_msg)
1173 {
1174 	const sip_str_t	*localtag;
1175 	const sip_str_t	*remtag;
1176 	const sip_str_t	*callid;
1177 	uint16_t	digest[8];
1178 	_sip_dialog_t	*dialog;
1179 	boolean_t	is_request;
1180 	int		error;
1181 
1182 	is_request = sip_msg_is_request((sip_msg_t)sip_msg, &error);
1183 	if (error != 0)
1184 		return (NULL);
1185 	if (is_request) {
1186 		localtag = sip_get_to_tag((sip_msg_t)sip_msg, &error);
1187 		if (error == 0)
1188 			remtag = sip_get_from_tag((sip_msg_t)sip_msg, &error);
1189 	} else {
1190 		remtag = sip_get_to_tag((sip_msg_t)sip_msg, &error);
1191 		if (error == 0)
1192 			localtag = sip_get_from_tag((sip_msg_t)sip_msg, &error);
1193 	}
1194 	if (error != 0)
1195 		return (NULL);
1196 	callid = sip_get_callid((sip_msg_t)sip_msg, &error);
1197 	if (error != 0 || remtag == NULL || localtag == NULL ||
1198 	    callid == NULL) {
1199 		return (NULL);
1200 	}
1201 	sip_md5_hash(localtag->sip_str_ptr, localtag->sip_str_len,
1202 	    remtag->sip_str_ptr, remtag->sip_str_len,
1203 	    callid->sip_str_ptr, callid->sip_str_len,
1204 	    NULL, 0, NULL, 0, NULL, 0, (uchar_t *)digest);
1205 
1206 	dialog = (_sip_dialog_t *)sip_hash_find(sip_dialog_hash,
1207 	    (void *)digest, SIP_DIGEST_TO_HASH(digest), sip_dialog_match);
1208 	if (dialog == NULL) {
1209 		sip_md5_hash(localtag->sip_str_ptr, localtag->sip_str_len,
1210 		    NULL, 0, callid->sip_str_ptr, callid->sip_str_len,
1211 		    NULL, 0, NULL, 0, NULL, 0, (uchar_t *)digest);
1212 		dialog = (_sip_dialog_t *)sip_hash_find(sip_dialog_phash,
1213 		    (void *)digest, SIP_DIGEST_TO_HASH(digest),
1214 		    sip_dialog_match);
1215 	}
1216 	return ((sip_dialog_t)dialog);
1217 }
1218 
1219 /*
1220  * We keep this partial dialog for the duration of the INVITE
1221  * transaction timeout duration, i.e. Timer B.
1222  */
1223 void
1224 sip_dlg_self_destruct(void *args)
1225 {
1226 	sip_dialog_timer_obj_t	*tim_obj = (sip_dialog_timer_obj_t *)args;
1227 	_sip_dialog_t		*dialog = (_sip_dialog_t *)tim_obj->dialog;
1228 	int			index;
1229 
1230 	(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1231 	assert(dialog->sip_dlg_state == SIP_DLG_NEW);
1232 	dialog->sip_dlg_state = SIP_DLG_DESTROYED;
1233 	if (dialog->sip_dlg_type == SIP_UAC_DIALOG) {
1234 		index = SIP_DIGEST_TO_HASH(dialog->sip_dlg_id);
1235 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1236 		sip_hash_delete(sip_dialog_phash, (void *)dialog->sip_dlg_id,
1237 		    index, sip_dialog_dontfree);
1238 	} else {
1239 		(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1240 	}
1241 	if (tim_obj->func != NULL)
1242 		tim_obj->func(dialog, NULL, NULL);
1243 	free(tim_obj);
1244 	SIP_DLG_REFCNT_DECR(dialog);
1245 }
1246 
1247 /*
1248  * Terminate a dialog
1249  */
1250 void
1251 sip_dialog_terminate(_sip_dialog_t *dialog, sip_msg_t sip_msg)
1252 {
1253 	int	prev_state;
1254 
1255 	(void) pthread_mutex_lock(&dialog->sip_dlg_mutex);
1256 	prev_state = dialog->sip_dlg_state;
1257 	dialog->sip_dlg_state = SIP_DLG_DESTROYED;
1258 	(void) pthread_mutex_unlock(&dialog->sip_dlg_mutex);
1259 	if (sip_dlg_ulp_state_cb != NULL) {
1260 		sip_dlg_ulp_state_cb((sip_dialog_t)dialog, sip_msg, prev_state,
1261 		    dialog->sip_dlg_state);
1262 	}
1263 	SIP_DLG_REFCNT_DECR(dialog);
1264 }
1265 
1266 /*
1267  * Delete a dialog
1268  */
1269 void
1270 sip_dialog_delete(_sip_dialog_t *dialog)
1271 {
1272 	int	index;
1273 
1274 	/*
1275 	 * partial dialog, not in the hash table
1276 	 */
1277 	if (dialog->sip_dlg_local_uri_tag == NULL ||
1278 	    dialog->sip_dlg_remote_uri_tag == NULL) {
1279 		/*
1280 		 * Cancel the partial dialog timer
1281 		 */
1282 		if (SIP_IS_TIMER_RUNNING(dialog->sip_dlg_timer))
1283 			SIP_CANCEL_TIMER(dialog->sip_dlg_timer);
1284 		sip_release_dialog_res(dialog);
1285 		return;
1286 	}
1287 	index = SIP_DIGEST_TO_HASH(dialog->sip_dlg_id);
1288 	sip_hash_delete(sip_dialog_hash, (void *)dialog->sip_dlg_id, index,
1289 	    sip_dialog_free);
1290 }
1291 
1292 /*
1293  * Get the remote target from the CONTACT header from the 200 OK response
1294  */
1295 static boolean_t
1296 sip_get_rtarg(_sip_dialog_t *dialog, _sip_msg_t *sip_msg)
1297 {
1298 	sip_header_t	chdr;
1299 
1300 	if (dialog->sip_dlg_remote_target != NULL)
1301 		return (B_TRUE);
1302 
1303 	(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
1304 	chdr = sip_search_for_header(sip_msg, SIP_CONTACT, NULL);
1305 	(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
1306 	if (chdr == NULL)
1307 		return (B_FALSE);
1308 	if ((dialog->sip_dlg_remote_target = sip_dup_header(chdr)) == NULL)
1309 		return (B_FALSE);
1310 
1311 	return (B_TRUE);
1312 }
1313 
1314 /*
1315  * Process an incoming request/response
1316  */
1317 /* ARGSUSED */
1318 int
1319 sip_dialog_process(_sip_msg_t *sip_msg, sip_dialog_t *sip_dialog)
1320 {
1321 	boolean_t	request;
1322 	_sip_dialog_t	*_dialog;
1323 	int		error;
1324 
1325 	request = sip_msg_is_request((sip_msg_t)sip_msg, &error);
1326 	if (error != 0)
1327 		return (EINVAL);
1328 	_dialog = (_sip_dialog_t *)*sip_dialog;
1329 	if (request) {
1330 		uint32_t	cseq;
1331 		sip_method_t	method;
1332 
1333 		cseq = sip_get_callseq_num((sip_msg_t)sip_msg, &error);
1334 		if (error != 0)
1335 			return (EINVAL);
1336 		method = sip_get_callseq_method((sip_msg_t)sip_msg, &error);
1337 		if (error != 0)
1338 			return (EINVAL);
1339 		if (sip_get_request_method((sip_msg_t)sip_msg, &error) !=
1340 		    method) {
1341 			return (EINVAL);
1342 		}
1343 		(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
1344 		/*
1345 		 * Requests that do not change in any way the state
1346 		 * of a dialog may be received within a dialog.
1347 		 * They are processed as if they had been received
1348 		 * outside the dialog.
1349 		 * For dialogs that have been established with an
1350 		 * INVITE, the only target refresh request defined is
1351 		 * re-INVITE.
1352 		 */
1353 		if (_dialog->sip_dlg_method == INVITE &&
1354 		    method == INVITE && _dialog->sip_dlg_remote_cseq != 0 &&
1355 		    SIP_CSEQ_LT(cseq, _dialog->sip_dlg_remote_cseq)) {
1356 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1357 			return (EPROTO);
1358 		}
1359 		/*
1360 		 * Target-Refresh request
1361 		 */
1362 		if (_dialog->sip_dlg_method == INVITE && method == INVITE) {
1363 			sip_header_t	chdr;
1364 			sip_header_t	nchdr;
1365 
1366 			(void) pthread_mutex_lock(&sip_msg->sip_msg_mutex);
1367 			chdr = sip_search_for_header(sip_msg, SIP_CONTACT,
1368 			    NULL);
1369 			(void) pthread_mutex_unlock(&sip_msg->sip_msg_mutex);
1370 			if (chdr != NULL &&
1371 			    (nchdr = sip_dup_header(chdr)) != NULL) {
1372 				if (_dialog->sip_dlg_remote_target != NULL) {
1373 					sip_free_header(
1374 					    _dialog->sip_dlg_remote_target);
1375 				}
1376 				_dialog->sip_dlg_remote_target = nchdr;
1377 			}
1378 		}
1379 		_dialog->sip_dlg_remote_cseq = cseq;
1380 		(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1381 	} else {
1382 		int		resp_code;
1383 		sip_method_t	method;
1384 		int		error;
1385 
1386 		resp_code = sip_get_response_code((sip_msg_t)sip_msg, &error);
1387 		if (error == 0) {
1388 			method = sip_get_callseq_method((sip_msg_t)sip_msg,
1389 			    &error);
1390 		}
1391 		if (error != 0)
1392 			return (error);
1393 
1394 		(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
1395 		assert(_dialog->sip_dlg_state == SIP_DLG_EARLY ||
1396 		    _dialog->sip_dlg_state == SIP_DLG_CONFIRMED);
1397 		/*
1398 		 * Let the user delete the dialog if it is not a 1XX/2XX resp
1399 		 * for an early INVITE dialog.
1400 		 */
1401 		if (SIP_OK_RESP(resp_code)) {
1402 			if (method == INVITE) {
1403 				if (!sip_get_rtarg(_dialog, sip_msg)) {
1404 					(void) pthread_mutex_unlock(
1405 					    &_dialog->sip_dlg_mutex);
1406 					if (sip_ulp_dlg_del_cb != NULL) {
1407 						sip_ulp_dlg_del_cb(
1408 						    (sip_dialog_t)_dialog,
1409 						    (sip_msg_t)sip_msg, NULL);
1410 					}
1411 					sip_dialog_terminate(_dialog,
1412 					    (sip_msg_t)sip_msg);
1413 					return (0);
1414 				}
1415 				if (_dialog->sip_dlg_state == SIP_DLG_EARLY) {
1416 					_dialog->sip_dlg_state =
1417 					    SIP_DLG_CONFIRMED;
1418 					(void) pthread_mutex_unlock(
1419 					    &_dialog->sip_dlg_mutex);
1420 					(void) sip_dlg_recompute_rset(_dialog,
1421 					    sip_msg, SIP_UAC_DIALOG);
1422 					if (sip_dlg_ulp_state_cb != NULL) {
1423 						sip_dlg_ulp_state_cb(
1424 						    (sip_dialog_t)_dialog,
1425 						    sip_msg, SIP_DLG_EARLY,
1426 						    _dialog->sip_dlg_state);
1427 					}
1428 					return (0);
1429 				}
1430 			}
1431 		}
1432 		(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1433 	}
1434 	return (0);
1435 }
1436 
1437 /*
1438  * Copy partial dialog to create a complete dialog
1439  */
1440 _sip_dialog_t *
1441 sip_copy_partial_dialog(_sip_dialog_t *dialog)
1442 {
1443 	_sip_dialog_t	*new_dlg;
1444 
1445 	new_dlg =  calloc(1, sizeof (_sip_dialog_t));
1446 	if (new_dlg == NULL)
1447 		return (NULL);
1448 	if (dialog->sip_dlg_req_uri.sip_str_ptr != NULL) {
1449 		new_dlg->sip_dlg_req_uri.sip_str_ptr =
1450 		    malloc(dialog->sip_dlg_req_uri.sip_str_len + 1);
1451 		if (new_dlg->sip_dlg_req_uri.sip_str_ptr == NULL) {
1452 			free(new_dlg);
1453 			return (NULL);
1454 		}
1455 		(void) strncpy(new_dlg->sip_dlg_req_uri.sip_str_ptr,
1456 		    dialog->sip_dlg_req_uri.sip_str_ptr,
1457 		    dialog->sip_dlg_req_uri.sip_str_len);
1458 		new_dlg->sip_dlg_req_uri.sip_str_ptr[
1459 		    dialog->sip_dlg_req_uri.sip_str_len] = '\0';
1460 		new_dlg->sip_dlg_req_uri.sip_str_len =
1461 		    dialog->sip_dlg_req_uri.sip_str_len;
1462 	}
1463 	if (dialog->sip_dlg_route_set != NULL) {
1464 		assert(dialog->sip_dlg_rset.sip_str_ptr != NULL);
1465 		new_dlg->sip_dlg_rset.sip_str_ptr =
1466 		    malloc(dialog->sip_dlg_rset.sip_str_len + 1);
1467 		if (new_dlg->sip_dlg_rset.sip_str_ptr == NULL) {
1468 			if (new_dlg->sip_dlg_req_uri.sip_str_ptr != NULL)
1469 				free(new_dlg->sip_dlg_req_uri.sip_str_ptr);
1470 			free(new_dlg);
1471 			return (NULL);
1472 		}
1473 		(void) strncpy(new_dlg->sip_dlg_rset.sip_str_ptr,
1474 		    dialog->sip_dlg_rset.sip_str_ptr,
1475 		    dialog->sip_dlg_rset.sip_str_len);
1476 		new_dlg->sip_dlg_rset.sip_str_ptr[
1477 		    dialog->sip_dlg_rset.sip_str_len] = '\0';
1478 		new_dlg->sip_dlg_rset.sip_str_len =
1479 		    dialog->sip_dlg_rset.sip_str_len;
1480 
1481 		new_dlg->sip_dlg_route_set =
1482 		    sip_dup_header(dialog->sip_dlg_route_set);
1483 		if (new_dlg->sip_dlg_route_set == NULL) {
1484 			free(new_dlg->sip_dlg_rset.sip_str_ptr);
1485 			if (new_dlg->sip_dlg_req_uri.sip_str_ptr != NULL)
1486 				free(new_dlg->sip_dlg_req_uri.sip_str_ptr);
1487 			free(new_dlg);
1488 			return (NULL);
1489 		}
1490 	}
1491 	if ((new_dlg->sip_dlg_local_uri_tag =
1492 	    sip_dup_header(dialog->sip_dlg_local_uri_tag)) == NULL ||
1493 	    (new_dlg->sip_dlg_remote_target =
1494 	    sip_dup_header(dialog->sip_dlg_remote_target)) == NULL ||
1495 	    (new_dlg->sip_dlg_call_id =
1496 	    sip_dup_header(dialog->sip_dlg_call_id)) == NULL) {
1497 		sip_release_dialog_res(new_dlg);
1498 		return (NULL);
1499 	}
1500 	if (dialog->sip_dlg_event != NULL) {
1501 		new_dlg->sip_dlg_event = sip_dup_header(dialog->sip_dlg_event);
1502 		if (new_dlg->sip_dlg_event == NULL) {
1503 			sip_release_dialog_res(new_dlg);
1504 			return (NULL);
1505 		}
1506 	}
1507 	new_dlg->sip_dlg_local_cseq = dialog->sip_dlg_local_cseq;
1508 	new_dlg->sip_dlg_type = dialog->sip_dlg_type;
1509 	new_dlg->sip_dlg_on_fork = B_FALSE;
1510 	(void) pthread_mutex_init(&new_dlg->sip_dlg_mutex, NULL);
1511 
1512 	return (new_dlg);
1513 }
1514 
1515 /*
1516  * Update the dialog using the response
1517  */
1518 sip_dialog_t
1519 sip_update_dialog(sip_dialog_t dialog, _sip_msg_t *sip_msg)
1520 {
1521 	_sip_dialog_t	*_dialog;
1522 	boolean_t	isreq;
1523 	sip_method_t	method;
1524 	int		resp_code = 0;
1525 	int		prev_state;
1526 	boolean_t	decr_ref = B_FALSE;
1527 	int		error;
1528 
1529 	isreq = sip_msg_is_request((sip_msg_t)sip_msg, &error);
1530 	if (error != 0)
1531 		return (dialog);
1532 	_dialog = (_sip_dialog_t *)dialog;
1533 	(void) pthread_mutex_lock(&_dialog->sip_dlg_mutex);
1534 	if (isreq) {
1535 		method = sip_get_request_method((sip_msg_t)sip_msg, &error);
1536 		if (error != 0 || _dialog->sip_dlg_method != SUBSCRIBE ||
1537 		    method != NOTIFY) {
1538 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1539 			return (dialog);
1540 		}
1541 	} else {
1542 		resp_code = sip_get_response_code((sip_msg_t)sip_msg, &error);
1543 		if (error != 0) {
1544 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1545 			return (dialog);
1546 		}
1547 	}
1548 	prev_state = _dialog->sip_dlg_state;
1549 	if (_dialog->sip_dlg_state == SIP_DLG_CONFIRMED) {
1550 		(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1551 	} else if (_dialog->sip_dlg_state == SIP_DLG_EARLY) {
1552 		/*
1553 		 * Let the user delete the dialog if it is not a 1XX/2XX resp
1554 		 * for an early dialog.
1555 		 */
1556 		assert(!isreq);
1557 		if (SIP_OK_RESP(resp_code)) {
1558 			_dialog->sip_dlg_state = SIP_DLG_CONFIRMED;
1559 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1560 			(void) sip_dlg_recompute_rset(_dialog, sip_msg,
1561 			    SIP_UAS_DIALOG);
1562 			if (sip_dlg_ulp_state_cb != NULL) {
1563 				sip_dlg_ulp_state_cb(dialog, (sip_msg_t)sip_msg,
1564 				    prev_state, dialog->sip_dlg_state);
1565 			}
1566 		} else {
1567 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1568 		}
1569 	} else if (_dialog->sip_dlg_state == SIP_DLG_NEW) {
1570 		if (!isreq && _dialog->sip_dlg_method == SUBSCRIBE &&
1571 		    SIP_PROVISIONAL_RESP(resp_code)) {
1572 			(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1573 			return (dialog);
1574 		}
1575 		if (_dialog->sip_dlg_type == SIP_UAC_DIALOG) {
1576 			_sip_dialog_t	*new_dlg;
1577 
1578 			if (_dialog->sip_dlg_on_fork) {
1579 				new_dlg = sip_copy_partial_dialog(_dialog);
1580 				if (new_dlg == NULL) {
1581 					(void) pthread_mutex_unlock(
1582 					    &_dialog->sip_dlg_mutex);
1583 					return (dialog);
1584 				}
1585 				/*
1586 				 * This decr/incr dance is because the caller
1587 				 * has incremented the ref on the partial
1588 				 * dialog, we release it here and incr the
1589 				 * ref on the new dialog which will be
1590 				 * released by the caller.
1591 				 */
1592 				(void) pthread_mutex_unlock(
1593 				    &_dialog->sip_dlg_mutex);
1594 				SIP_DLG_REFCNT_DECR(_dialog);
1595 				_dialog = new_dlg;
1596 				(void) pthread_mutex_lock(
1597 				    &_dialog->sip_dlg_mutex);
1598 				SIP_DLG_REFCNT_INCR(_dialog);
1599 			} else {
1600 				int	index;
1601 
1602 				/*
1603 				 * take it out of the list so that further
1604 				 * responses will not result in a dialog.
1605 				 * We will have an extra refcount when we
1606 				 * come back from sip_complete_dialog(), i.e.
1607 				 * one when the partial dialog was created -
1608 				 * in sip_seed_dialog(), one held by the caller
1609 				 * and one that will be added by
1610 				 * sip_complete_dialog(). We need to release
1611 				 * the one added by the sip_seed_dialog(),
1612 				 * since the one in sip_complete_dialog()
1613 				 * is for the same purpose.
1614 				 */
1615 				if (SIP_IS_TIMER_RUNNING(
1616 				    _dialog->sip_dlg_timer)) {
1617 					SIP_CANCEL_TIMER(
1618 					    _dialog->sip_dlg_timer);
1619 				}
1620 				index = SIP_DIGEST_TO_HASH(dialog->sip_dlg_id);
1621 				(void) pthread_mutex_unlock(
1622 				    &_dialog->sip_dlg_mutex);
1623 				sip_hash_delete(sip_dialog_phash,
1624 				    (void *)_dialog->sip_dlg_id,
1625 				    index, sip_dialog_dontfree);
1626 				(void) pthread_mutex_lock(
1627 				    &_dialog->sip_dlg_mutex);
1628 				decr_ref = B_TRUE;
1629 			}
1630 		} else {
1631 			decr_ref = B_TRUE;
1632 		}
1633 		(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1634 		if ((dialog = sip_complete_dialog(sip_msg, _dialog)) ==
1635 		    NULL) {
1636 			if (_dialog->sip_dlg_type == SIP_UAC_DIALOG && decr_ref)
1637 				SIP_DLG_REFCNT_DECR(_dialog);
1638 			return (NULL);
1639 		}
1640 		if (decr_ref)
1641 			SIP_DLG_REFCNT_DECR(_dialog);
1642 	} else {
1643 		(void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex);
1644 	}
1645 	return (dialog);
1646 }
1647 
1648 /*
1649  * Initialize the hash table
1650  */
1651 void
1652 sip_dialog_init(void (*ulp_dlg_del) (sip_dialog_t, sip_msg_t, void *),
1653     void (*ulp_state_cb)(sip_dialog_t, sip_msg_t, int, int))
1654 {
1655 	int	cnt;
1656 
1657 	for (cnt = 0; cnt < SIP_HASH_SZ; cnt++) {
1658 		sip_dialog_hash[cnt].hash_count = 0;
1659 		sip_dialog_hash[cnt].hash_head = NULL;
1660 		sip_dialog_hash[cnt].hash_tail = NULL;
1661 		(void) pthread_mutex_init(
1662 		    &sip_dialog_hash[cnt].sip_hash_mutex, NULL);
1663 		sip_dialog_phash[cnt].hash_count = 0;
1664 		sip_dialog_phash[cnt].hash_head = NULL;
1665 		sip_dialog_phash[cnt].hash_tail = NULL;
1666 		(void) pthread_mutex_init(
1667 		    &sip_dialog_phash[cnt].sip_hash_mutex, NULL);
1668 	}
1669 	if (ulp_dlg_del != NULL)
1670 		sip_ulp_dlg_del_cb = ulp_dlg_del;
1671 
1672 	if (ulp_state_cb != NULL)
1673 		sip_dlg_ulp_state_cb = ulp_state_cb;
1674 }
1675