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