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