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_remote_target, 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 * Get the Dialog method 123 */ 124 int 125 sip_get_dialog_method(sip_dialog_t dialog, int *error) 126 { 127 _sip_dialog_t *_dialog; 128 129 if (error != NULL) 130 *error = 0; 131 if (!sip_manage_dialog) { 132 if (error != NULL) 133 *error = EINVAL; 134 return (0); 135 } 136 if (dialog == NULL) { 137 if (error != NULL) 138 *error = EINVAL; 139 return (0); 140 } 141 _dialog = (_sip_dialog_t *)dialog; 142 return (_dialog->sip_dlg_method); 143 } 144 145 /* 146 * Get the Dialog state 147 */ 148 int 149 sip_get_dialog_state(sip_dialog_t dialog, int *error) 150 { 151 _sip_dialog_t *_dialog; 152 153 if (error != NULL) 154 *error = 0; 155 if (!sip_manage_dialog) { 156 if (error != NULL) 157 *error = EINVAL; 158 return (0); 159 } 160 if (dialog == NULL) { 161 if (error != NULL) 162 *error = EINVAL; 163 return (0); 164 } 165 _dialog = (_sip_dialog_t *)dialog; 166 return (_dialog->sip_dlg_state); 167 } 168 169 /* 170 * Return the dialog callid 171 */ 172 const sip_str_t * 173 sip_get_dialog_callid(sip_dialog_t dialog, int *error) 174 { 175 _sip_dialog_t *_dialog; 176 const struct sip_value *val; 177 const sip_str_t *callid = NULL; 178 179 if (error != NULL) 180 *error = 0; 181 if (!sip_manage_dialog || dialog == NULL) { 182 if (error != NULL) 183 *error = EINVAL; 184 return (NULL); 185 } 186 _dialog = (_sip_dialog_t *)dialog; 187 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 188 if (dialog->sip_dlg_call_id != NULL) { 189 val = sip_get_header_value(_dialog->sip_dlg_call_id, error); 190 if (val == NULL) { 191 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 192 return (NULL); 193 } 194 callid = &((sip_hdr_value_t *)val)->str_val; 195 } 196 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 197 return (callid); 198 } 199 200 /* 201 * Return the dialog localtag. 202 */ 203 const sip_str_t * 204 sip_get_dialog_local_tag(sip_dialog_t dialog, int *error) 205 { 206 _sip_dialog_t *_dialog; 207 const sip_str_t *ltag = NULL; 208 const struct sip_value *val; 209 210 if (error != NULL) 211 *error = 0; 212 if (!sip_manage_dialog || dialog == NULL) { 213 if (error != NULL) 214 *error = EINVAL; 215 return (NULL); 216 } 217 _dialog = (_sip_dialog_t *)dialog; 218 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 219 if (dialog->sip_dlg_local_uri_tag != NULL) { 220 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 221 error); 222 if (val == NULL) { 223 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 224 return (NULL); 225 } 226 ltag = sip_get_param_value((sip_header_value_t)val, "tag", 227 error); 228 } 229 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 230 return (ltag); 231 } 232 233 /* 234 * Return the dialog remotetag 235 */ 236 const sip_str_t * 237 sip_get_dialog_remote_tag(sip_dialog_t dialog, int *error) 238 { 239 _sip_dialog_t *_dialog; 240 const sip_str_t *ttag = NULL; 241 const struct sip_value *val; 242 243 if (error != NULL) 244 *error = 0; 245 if (!sip_manage_dialog || dialog == NULL) { 246 if (error != NULL) 247 *error = EINVAL; 248 return (NULL); 249 } 250 _dialog = (_sip_dialog_t *)dialog; 251 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 252 if (dialog->sip_dlg_remote_uri_tag != NULL) { 253 val = sip_get_header_value(_dialog->sip_dlg_remote_uri_tag, 254 error); 255 if (val == NULL) { 256 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 257 return (NULL); 258 } 259 ttag = sip_get_param_value((sip_header_value_t)val, "tag", 260 error); 261 } 262 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 263 264 return (ttag); 265 } 266 267 /* 268 * Return the dialog localuri. 269 */ 270 const struct sip_uri * 271 sip_get_dialog_local_uri(sip_dialog_t dialog, int *error) 272 { 273 _sip_dialog_t *_dialog; 274 const _sip_uri_t *luri = NULL; 275 const struct sip_value *val; 276 277 if (error != NULL) 278 *error = 0; 279 if (!sip_manage_dialog || dialog == NULL) { 280 if (error != NULL) 281 *error = EINVAL; 282 return (NULL); 283 } 284 _dialog = (_sip_dialog_t *)dialog; 285 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 286 if (dialog->sip_dlg_local_uri_tag != NULL) { 287 val = sip_get_header_value(_dialog->sip_dlg_local_uri_tag, 288 error); 289 if (val == NULL) { 290 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 291 return (NULL); 292 } 293 luri = val->sip_value_parse_uri; 294 } 295 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 296 297 return ((sip_uri_t)luri); 298 } 299 300 /* 301 * Return the dialog remoteuri. 302 */ 303 const struct sip_uri * 304 sip_get_dialog_remote_uri(sip_dialog_t dialog, int *error) 305 { 306 _sip_dialog_t *_dialog; 307 const _sip_uri_t *ruri = NULL; 308 const struct sip_value *val; 309 310 if (error != NULL) 311 *error = 0; 312 if (!sip_manage_dialog || dialog == NULL) { 313 if (error != NULL) 314 *error = EINVAL; 315 return (NULL); 316 } 317 _dialog = (_sip_dialog_t *)dialog; 318 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 319 if (dialog->sip_dlg_remote_uri_tag != NULL) { 320 val = sip_get_header_value(dialog->sip_dlg_remote_uri_tag, 321 error); 322 if (val == NULL) { 323 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 324 return (NULL); 325 } 326 ruri = val->sip_value_parse_uri; 327 } 328 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 329 return ((sip_uri_t)ruri); 330 } 331 332 /* 333 * Return the dialog remotetarg. 334 */ 335 const struct sip_uri * 336 sip_get_dialog_remote_target_uri(sip_dialog_t dialog, int *error) 337 { 338 _sip_dialog_t *_dialog; 339 const struct sip_uri *rtarg = NULL; 340 const struct sip_value *val; 341 342 if (error != NULL) 343 *error = 0; 344 if (!sip_manage_dialog || dialog == NULL) { 345 if (error != NULL) 346 *error = EINVAL; 347 return (NULL); 348 } 349 _dialog = (_sip_dialog_t *)dialog; 350 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 351 if (dialog->sip_dlg_remote_target != NULL) { 352 val = sip_get_header_value(_dialog->sip_dlg_remote_target, 353 error); 354 if (val == NULL) { 355 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 356 return (NULL); 357 } 358 rtarg = val->sip_value_parse_uri; 359 } 360 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 361 362 return ((sip_uri_t)rtarg); 363 } 364 365 /* 366 * Return the dialog route set 367 */ 368 const sip_str_t * 369 sip_get_dialog_route_set(sip_dialog_t dialog, int *error) 370 { 371 _sip_dialog_t *_dialog; 372 373 if (error != NULL) 374 *error = 0; 375 if (!sip_manage_dialog || dialog == NULL) { 376 if (error != NULL) 377 *error = EINVAL; 378 return (NULL); 379 } 380 _dialog = (_sip_dialog_t *)dialog; 381 if (_dialog->sip_dlg_rset.sip_str_len > 0) 382 return (&_dialog->sip_dlg_rset); 383 return (NULL); 384 } 385 386 /* 387 * Return the dialog secure 388 */ 389 boolean_t 390 sip_is_dialog_secure(sip_dialog_t dialog, int *error) 391 { 392 _sip_dialog_t *_dialog; 393 boolean_t issecure; 394 395 if (error != NULL) 396 *error = 0; 397 if (!sip_manage_dialog || dialog == NULL) { 398 if (error != NULL) 399 *error = EINVAL; 400 return (B_FALSE); 401 } 402 _dialog = (_sip_dialog_t *)dialog; 403 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 404 issecure = _dialog->sip_dlg_secure; 405 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 406 return (issecure); 407 } 408 409 /* 410 * Return the dialog local cseq 411 */ 412 uint32_t 413 sip_get_dialog_local_cseq(sip_dialog_t dialog, int *error) 414 { 415 _sip_dialog_t *_dialog; 416 uint32_t cseq; 417 418 if (error != NULL) 419 *error = 0; 420 if (!sip_manage_dialog || dialog == NULL) { 421 if (error != NULL) 422 *error = EINVAL; 423 return (0); 424 } 425 _dialog = (_sip_dialog_t *)dialog; 426 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 427 cseq = _dialog->sip_dlg_local_cseq; 428 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 429 return (cseq); 430 } 431 432 /* 433 * Return the dialog remote cseq 434 */ 435 uint32_t 436 sip_get_dialog_remote_cseq(sip_dialog_t dialog, int *error) 437 { 438 _sip_dialog_t *_dialog; 439 uint32_t cseq; 440 441 if (error != NULL) 442 *error = 0; 443 if (!sip_manage_dialog || dialog == NULL) { 444 if (error != NULL) 445 *error = EINVAL; 446 return (0); 447 } 448 _dialog = (_sip_dialog_t *)dialog; 449 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 450 cseq = _dialog->sip_dlg_remote_cseq; 451 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 452 return (cseq); 453 } 454 455 /* 456 * Return the dialog type 457 */ 458 int 459 sip_get_dialog_type(sip_dialog_t dialog, int *error) 460 { 461 _sip_dialog_t *_dialog; 462 int type; 463 464 if (error != NULL) 465 *error = 0; 466 if (!sip_manage_dialog || dialog == NULL) { 467 if (error != NULL) 468 *error = EINVAL; 469 return (-1); 470 } 471 _dialog = (_sip_dialog_t *)dialog; 472 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 473 type = _dialog->sip_dlg_type; 474 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 475 return (type); 476 } 477 478 479 /* 480 * Partial dialog ? 481 */ 482 boolean_t 483 sip_incomplete_dialog(sip_dialog_t dialog) 484 { 485 _sip_dialog_t *_dialog; 486 boolean_t isnew; 487 488 if (!sip_manage_dialog || dialog == NULL) 489 return (B_FALSE); 490 _dialog = (_sip_dialog_t *)dialog; 491 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 492 isnew = _dialog->sip_dlg_state == SIP_DLG_NEW; 493 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 494 return (isnew); 495 } 496 497 /* 498 * Hold dialog 499 */ 500 void 501 sip_hold_dialog(sip_dialog_t dialog) 502 { 503 _sip_dialog_t *_dialog; 504 505 if (!sip_manage_dialog || dialog == NULL) 506 return; 507 _dialog = (_sip_dialog_t *)dialog; 508 (void) pthread_mutex_lock(&_dialog->sip_dlg_mutex); 509 SIP_DLG_REFCNT_INCR(_dialog); 510 (void) pthread_mutex_unlock(&_dialog->sip_dlg_mutex); 511 } 512 513 /* 514 * Release dialog 515 */ 516 void 517 sip_release_dialog(sip_dialog_t dialog) 518 { 519 _sip_dialog_t *_dialog; 520 521 if (!sip_manage_dialog || dialog == NULL) 522 return; 523 _dialog = (_sip_dialog_t *)dialog; 524 SIP_DLG_REFCNT_DECR(_dialog); 525 } 526 527 /* 528 * Delete a dialog 529 */ 530 void 531 sip_delete_dialog(sip_dialog_t dialog) 532 { 533 if (!sip_manage_dialog || dialog == NULL) 534 return; 535 sip_dialog_terminate(dialog, NULL); 536 } 537