1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <assert.h> 31 #include <errno.h> 32 #include <pthread.h> 33 #include <sip.h> 34 35 #include "sip_msg.h" 36 #include "sip_miscdefs.h" 37 #include "sip_parse_uri.h" 38 #include "sip_dialog.h" 39 40 /* 41 * Create a request using the state maintained in the dialog. 42 */ 43 sip_msg_t 44 sip_create_dialog_req(sip_method_t method, sip_dialog_t dialog, 45 char *transport, char *sent_by, int sent_by_port, char *via_param, 46 uint32_t maxforward, int cseq) 47 { 48 _sip_dialog_t *_dialog; 49 sip_msg_t sip_msg; 50 char *uri; 51 int oldseq = 0; 52 53 if (!sip_manage_dialog || dialog == NULL || transport == NULL || 54 sent_by == NULL) { 55 return (NULL); 56 } 57 if ((sip_msg = sip_new_msg()) == NULL) 58 return (NULL); 59 _dialog = (_sip_dialog_t *)dialog; 60 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 61 /* 62 * Depending on the route set, if any, the request URI could either 63 * be the contact URI or the 1st URI from the route set. 64 */ 65 uri = (char *)sip_dialog_req_uri(_dialog); 66 if (uri == NULL) 67 goto err_ret; 68 if (sip_add_request_line(sip_msg, method, uri) != 0) { 69 free(uri); 70 goto err_ret; 71 } 72 free(uri); 73 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_uri_tag, NULL) != 0) 74 goto err_ret; 75 if (sip_copy_header(sip_msg, _dialog->sip_dlg_remote_uri_tag, NULL) != 76 0) { 77 goto err_ret; 78 } 79 if (sip_copy_header(sip_msg, _dialog->sip_dlg_local_contact, NULL) != 0) 80 goto err_ret; 81 if (sip_add_via(sip_msg, transport, sent_by, sent_by_port, via_param) != 82 0) { 83 goto err_ret; 84 } 85 if (sip_add_maxforward(sip_msg, maxforward) != 0) 86 goto err_ret; 87 if (sip_copy_header(sip_msg, _dialog->sip_dlg_call_id, NULL) != 0) 88 goto err_ret; 89 if (cseq < 0) { 90 if (_dialog->sip_dlg_local_cseq == 0) 91 _dialog->sip_dlg_local_cseq = 1; 92 oldseq = _dialog->sip_dlg_local_cseq; 93 cseq = ++_dialog->sip_dlg_local_cseq; 94 } 95 if (sip_add_cseq(sip_msg, method, cseq) != 0) { 96 _dialog->sip_dlg_local_cseq = oldseq; 97 goto err_ret; 98 } 99 /* 100 * The route set, even if empty, overrides any pre-existing route set. 101 * If the route set is empty, the UAC MUST NOT add a Route header 102 * field to the request. 103 */ 104 (void) sip_delete_header_by_name(sip_msg, SIP_ROUTE); 105 106 if (_dialog->sip_dlg_route_set != NULL) { 107 if (sip_copy_header(sip_msg, _dialog->sip_dlg_route_set, 108 NULL) != 0) { 109 _dialog->sip_dlg_local_cseq = oldseq; 110 goto err_ret; 111 } 112 } 113 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 114 return (sip_msg); 115 err_ret: 116 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 117 sip_free_msg(sip_msg); 118 return (NULL); 119 } 120 121 /* 122 * Create a request using the state maintained in the dialog. The request will 123 * not have Contact header. 124 */ 125 sip_msg_t 126 sip_create_dialog_req_nocontact(sip_method_t method, sip_dialog_t dialog, 127 char *transport, char *sent_by, int sent_by_port, char *via_param, 128 uint32_t maxforward, int cseq) 129 { 130 sip_msg_t sip_msg; 131 132 sip_msg = sip_create_dialog_req(method, dialog, transport, sent_by, 133 sent_by_port, via_param, maxforward, cseq); 134 if (sip_msg != NULL) { 135 if (sip_delete_header_by_name(sip_msg, SIP_CONTACT) != 0) { 136 sip_free_msg(sip_msg); 137 return (NULL); 138 } 139 } 140 141 return (sip_msg); 142 } 143 144 /* 145 * Get the Dialog method 146 */ 147 int 148 sip_get_dialog_method(sip_dialog_t dialog, int *error) 149 { 150 _sip_dialog_t *_dialog; 151 152 if (error != NULL) 153 *error = 0; 154 if (!sip_manage_dialog) { 155 if (error != NULL) 156 *error = EINVAL; 157 return (0); 158 } 159 if (dialog == NULL) { 160 if (error != NULL) 161 *error = EINVAL; 162 return (0); 163 } 164 _dialog = (_sip_dialog_t *)dialog; 165 return (_dialog->sip_dlg_method); 166 } 167 168 /* 169 * Get the Dialog state 170 */ 171 int 172 sip_get_dialog_state(sip_dialog_t dialog, int *error) 173 { 174 _sip_dialog_t *_dialog; 175 176 if (error != NULL) 177 *error = 0; 178 if (!sip_manage_dialog) { 179 if (error != NULL) 180 *error = EINVAL; 181 return (0); 182 } 183 if (dialog == NULL) { 184 if (error != NULL) 185 *error = EINVAL; 186 return (0); 187 } 188 _dialog = (_sip_dialog_t *)dialog; 189 return (_dialog->sip_dlg_state); 190 } 191 192 /* 193 * Return the dialog callid 194 */ 195 const sip_str_t * 196 sip_get_dialog_callid(sip_dialog_t dialog, int *error) 197 { 198 _sip_dialog_t *_dialog; 199 const struct sip_value *val; 200 const sip_str_t *callid = NULL; 201 202 if (error != NULL) 203 *error = 0; 204 if (!sip_manage_dialog || dialog == NULL) { 205 if (error != NULL) 206 *error = EINVAL; 207 return (NULL); 208 } 209 _dialog = (_sip_dialog_t *)dialog; 210 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 211 if (dialog->sip_dlg_call_id != NULL) { 212 val = sip_get_header_value(_dialog->sip_dlg_call_id, error); 213 if (val == NULL) { 214 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 215 return (NULL); 216 } 217 callid = &((sip_hdr_value_t *)val)->str_val; 218 } 219 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 220 return (callid); 221 } 222 223 /* 224 * Return the dialog localtag. 225 */ 226 const sip_str_t * 227 sip_get_dialog_local_tag(sip_dialog_t dialog, int *error) 228 { 229 _sip_dialog_t *_dialog; 230 const sip_str_t *ltag = NULL; 231 const struct sip_value *val; 232 233 if (error != NULL) 234 *error = 0; 235 if (!sip_manage_dialog || dialog == NULL) { 236 if (error != NULL) 237 *error = EINVAL; 238 return (NULL); 239 } 240 _dialog = (_sip_dialog_t *)dialog; 241 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 242 if (dialog->sip_dlg_local_uri_tag != NULL) { 243 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 244 error); 245 if (val == NULL) { 246 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 247 return (NULL); 248 } 249 ltag = sip_get_param_value((sip_header_value_t)val, "tag", 250 error); 251 } 252 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 253 return (ltag); 254 } 255 256 /* 257 * Return the dialog remotetag 258 */ 259 const sip_str_t * 260 sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error) 261 { 262 _sip_dialog_t *_dialog; 263 const sip_str_t *ttag = NULL; 264 const struct sip_value *val; 265 266 if (error != NULL) 267 *error = 0; 268 if (!sip_manage_dialog || dialog == NULL) { 269 if (error != NULL) 270 *error = EINVAL; 271 return (NULL); 272 } 273 _dialog = (_sip_dialog_t *)dialog; 274 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 275 if (dialog->sip_dlg_remote_uri_tag != NULL) { 276 val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag, 277 error); 278 if (val == NULL) { 279 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 280 return (NULL); 281 } 282 ttag = sip_get_param_value((sip_header_value_t)val, "tag", 283 error); 284 } 285 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 286 287 return (ttag); 288 } 289 290 /* 291 * Return the dialog localuri. 292 */ 293 const struct sip_uri * 294 sip_get_dialog_local_uri(sip_dialog_t dialog, int *error) 295 { 296 _sip_dialog_t *_dialog; 297 const _sip_uri_t *luri = NULL; 298 const struct sip_value *val; 299 300 if (error != NULL) 301 *error = 0; 302 if (!sip_manage_dialog || dialog == NULL) { 303 if (error != NULL) 304 *error = EINVAL; 305 return (NULL); 306 } 307 _dialog = (_sip_dialog_t *)dialog; 308 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 309 if (dialog->sip_dlg_local_uri_tag != NULL) { 310 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 311 error); 312 if (val == NULL) { 313 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 314 return (NULL); 315 } 316 luri = val->sip_value_parse_uri; 317 } 318 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 319 320 return ((sip_uri_t)luri); 321 } 322 323 /* 324 * Return the dialog remoteuri. 325 */ 326 const struct sip_uri * 327 sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error) 328 { 329 _sip_dialog_t *_dialog; 330 const _sip_uri_t *ruri = NULL; 331 const struct sip_value *val; 332 333 if (error != NULL) 334 *error = 0; 335 if (!sip_manage_dialog || dialog == NULL) { 336 if (error != NULL) 337 *error = EINVAL; 338 return (NULL); 339 } 340 _dialog = (_sip_dialog_t *)dialog; 341 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 342 if (dialog->sip_dlg_remote_uri_tag != NULL) { 343 val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag, 344 error); 345 if (val == NULL) { 346 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 347 return (NULL); 348 } 349 ruri = val->sip_value_parse_uri; 350 } 351 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 352 return ((sip_uri_t)ruri); 353 } 354 355 /* 356 * Return the dialog remotetarg. 357 */ 358 const struct sip_uri * 359 sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error) 360 { 361 _sip_dialog_t *_dialog; 362 const struct sip_uri *rtarg = NULL; 363 const struct sip_value *val; 364 365 if (error != NULL) 366 *error = 0; 367 if (!sip_manage_dialog || dialog == NULL) { 368 if (error != NULL) 369 *error = EINVAL; 370 return (NULL); 371 } 372 _dialog = (_sip_dialog_t *)dialog; 373 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 374 if (dialog->sip_dlg_remote_target != NULL) { 375 val = sip_get_header_value(_dialog->sip_dlg_remote_target, 376 error); 377 if (val == NULL) { 378 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 379 return (NULL); 380 } 381 rtarg = val->sip_value_parse_uri; 382 } 383 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 384 385 return ((sip_uri_t)rtarg); 386 } 387 388 /* 389 * Return the dialog local contact uri. 390 */ 391 const struct sip_uri * 392 sip_get_dialog_local_contact_uri(sip_dialog_t dialog, int *error) 393 { 394 _sip_dialog_t *_dialog; 395 const struct sip_uri *lcuri = NULL; 396 const struct sip_value *val; 397 398 if (error != NULL) 399 *error = 0; 400 if (!sip_manage_dialog || dialog == NULL) { 401 if (error != NULL) 402 *error = EINVAL; 403 return (NULL); 404 } 405 _dialog = (_sip_dialog_t *)dialog; 406 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 407 if (dialog->sip_dlg_local_contact != NULL) { 408 val = sip_get_header_value(_dialog->sip_dlg_local_contact, 409 error); 410 if (val == NULL) { 411 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 412 return (NULL); 413 } 414 lcuri = val->sip_value_parse_uri; 415 } 416 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 417 418 return ((sip_uri_t)lcuri); 419 } 420 421 /* 422 * Return the dialog route set 423 */ 424 const sip_str_t * 425 sip_get_dialog_route_set(sip_dialog_t dialog, int *error) 426 { 427 _sip_dialog_t *_dialog; 428 429 if (error != NULL) 430 *error = 0; 431 if (!sip_manage_dialog || dialog == NULL) { 432 if (error != NULL) 433 *error = EINVAL; 434 return (NULL); 435 } 436 _dialog = (_sip_dialog_t *)dialog; 437 if (_dialog->sip_dlg_rset.sip_str_len > 0) 438 return (&_dialog->sip_dlg_rset); 439 return (NULL); 440 } 441 442 /* 443 * Return the dialog secure 444 */ 445 boolean_t 446 sip_is_dialog_secure(sip_dialog_t dialog, int *error) 447 { 448 _sip_dialog_t *_dialog; 449 boolean_t issecure; 450 451 if (error != NULL) 452 *error = 0; 453 if (!sip_manage_dialog || dialog == NULL) { 454 if (error != NULL) 455 *error = EINVAL; 456 return (B_FALSE); 457 } 458 _dialog = (_sip_dialog_t *)dialog; 459 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 460 issecure = _dialog->sip_dlg_secure; 461 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 462 return (issecure); 463 } 464 465 /* 466 * Return the dialog local cseq 467 */ 468 uint32_t 469 sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error) 470 { 471 _sip_dialog_t *_dialog; 472 uint32_t cseq; 473 474 if (error != NULL) 475 *error = 0; 476 if (!sip_manage_dialog || dialog == NULL) { 477 if (error != NULL) 478 *error = EINVAL; 479 return (0); 480 } 481 _dialog = (_sip_dialog_t *)dialog; 482 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 483 cseq = _dialog->sip_dlg_local_cseq; 484 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 485 return (cseq); 486 } 487 488 /* 489 * Return the dialog remote cseq 490 */ 491 uint32_t 492 sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error) 493 { 494 _sip_dialog_t *_dialog; 495 uint32_t cseq; 496 497 if (error != NULL) 498 *error = 0; 499 if (!sip_manage_dialog || dialog == NULL) { 500 if (error != NULL) 501 *error = EINVAL; 502 return (0); 503 } 504 _dialog = (_sip_dialog_t *)dialog; 505 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 506 cseq = _dialog->sip_dlg_remote_cseq; 507 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 508 return (cseq); 509 } 510 511 /* 512 * Return the dialog type 513 */ 514 int 515 sip_get_dialog_type(sip_dialog_t dialog, int *error) 516 { 517 _sip_dialog_t *_dialog; 518 int type; 519 520 if (error != NULL) 521 *error = 0; 522 if (!sip_manage_dialog || dialog == NULL) { 523 if (error != NULL) 524 *error = EINVAL; 525 return (-1); 526 } 527 _dialog = (_sip_dialog_t *)dialog; 528 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 529 type = _dialog->sip_dlg_type; 530 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 531 return (type); 532 } 533 534 535 /* 536 * Partial dialog ? 537 */ 538 boolean_t 539 sip_incomplete_dialog(sip_dialog_t dialog) 540 { 541 _sip_dialog_t *_dialog; 542 boolean_t isnew; 543 544 if (!sip_manage_dialog || dialog == NULL) 545 return (B_FALSE); 546 _dialog = (_sip_dialog_t *)dialog; 547 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 548 isnew = _dialog->sip_dlg_state == SIP_DLG_NEW; 549 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 550 return (isnew); 551 } 552 553 /* 554 * Hold dialog 555 */ 556 void 557 sip_hold_dialog(sip_dialog_t dialog) 558 { 559 _sip_dialog_t *_dialog; 560 561 if (!sip_manage_dialog || dialog == NULL) 562 return; 563 _dialog = (_sip_dialog_t *)dialog; 564 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 565 SIP_DLG_REFCNT_INCR(_dialog); 566 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 567 } 568 569 /* 570 * Release dialog 571 */ 572 void 573 sip_release_dialog(sip_dialog_t dialog) 574 { 575 _sip_dialog_t *_dialog; 576 577 if (!sip_manage_dialog || dialog == NULL) 578 return; 579 _dialog = (_sip_dialog_t *)dialog; 580 SIP_DLG_REFCNT_DECR(_dialog); 581 } 582 583 /* 584 * Delete a dialog 585 */ 586 void 587 sip_delete_dialog(sip_dialog_t dialog) 588 { 589 if (!sip_manage_dialog || dialog == NULL) 590 return; 591 sip_dialog_terminate(dialog, NULL); 592 } 593