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