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