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