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