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 /* 30 * SIP Client/Server Invite/Non-Invite Transaction State machine. 31 */ 32 33 #include "sip_parse_uri.h" 34 #include "sip_msg.h" 35 #include "sip_miscdefs.h" 36 #include "sip_xaction.h" 37 38 39 /* 40 * Some Timer related info from RFC 3261, page 265. 41 * 42 * ---------------------------------------------------------------------- 43 * Timer Value Section Meaning 44 * ---------------------------------------------------------------------- 45 * T1 500ms default Section 17.1.1.1 RTT Estimate 46 * T2 4s Section 17.1.2.2 The maximum retransmit 47 * interval for non-INVITE 48 * requests and INVITE 49 * responses 50 * T4 5s Section 17.1.2.2 Maximum duration a 51 * message will 52 * remain in the network 53 * ---------------------------------------------------------------------- 54 * Timer A initially T1 Section 17.1.1.2 INVITE request retransmit 55 * interval, for UDP only 56 * Timer B 64*T1 Section 17.1.1.2 INVITE transaction 57 * timeout timer 58 * Timer C > 3min Section 16.6 proxy INVITE transaction 59 * bullet 11 timeout 60 * Timer D > 32s for UDP Section 17.1.1.2 Wait time for response 61 * 0s for TCP/SCTP retransmits 62 * Timer E initially T1 Section 17.1.2.2 non-INVITE request 63 * retransmit interval, 64 * UDP only 65 * Timer F 64*T1 Section 17.1.2.2 non-INVITE transaction 66 * timeout timer 67 * Timer G initially T1 Section 17.2.1 INVITE response 68 * retransmit interval 69 * Timer H 64*T1 Section 17.2.1 Wait time for 70 * ACK receipt 71 * Timer I T4 for UDP Section 17.2.1 Wait time for 72 * 0s for TCP/SCTP ACK retransmits 73 * Timer J 64*T1 for UDP Section 17.2.2 Wait time for 74 * 0s for TCP/SCTP non-INVITE request 75 * retransmits 76 * Timer K T4 for UDP Section 17.1.2.2 Wait time for 77 * 0s for TCP/SCTP response retransmits 78 * ---------------------------------------------------------------------- 79 */ 80 81 #ifndef MIN 82 #define MIN(a, b) (((a) < (b)) ? (a):(b)) 83 #endif 84 85 /* 86 * Arg to the timer fire routine 87 */ 88 typedef struct sip_xaction_timer_obj_s { 89 sip_xaction_timer_type_t sip_xaction_timer_type; 90 sip_xaction_t *sip_trans; 91 int sip_xaction_timer_xport; 92 } sip_xaction_time_obj_t; 93 94 int sip_xaction_output(sip_conn_object_t, sip_xaction_t *, 95 _sip_msg_t *); 96 int sip_xaction_input(sip_conn_object_t, sip_xaction_t *, 97 _sip_msg_t **); 98 void sip_xaction_terminate(sip_xaction_t *, _sip_msg_t *, int); 99 100 static int sip_clnt_xaction_output(sip_conn_object_t, sip_xaction_t *, 101 _sip_msg_t *); 102 static int sip_clnt_xaction_input(sip_conn_object_t, sip_xaction_t *, 103 _sip_msg_t **); 104 static int sip_clnt_xaction_inv_res(sip_conn_object_t, sip_xaction_t *, 105 _sip_msg_t **); 106 static int sip_clnt_xaction_noninv_res(sip_conn_object_t, sip_xaction_t *, 107 _sip_msg_t **); 108 static int sip_srv_xaction_output(sip_conn_object_t, sip_xaction_t *, 109 _sip_msg_t *); 110 static int sip_srv_xaction_input(sip_conn_object_t, sip_xaction_t *, 111 _sip_msg_t **); 112 static int sip_srv_xaction_inv_res(sip_conn_object_t, sip_xaction_t *, 113 _sip_msg_t *); 114 static int sip_srv_xaction_noninv_res(sip_conn_object_t, sip_xaction_t *, 115 _sip_msg_t *); 116 static int sip_create_send_nonOKack(sip_conn_object_t, sip_xaction_t *, 117 _sip_msg_t *, boolean_t); 118 void sip_xaction_state_timer_fire(void *); 119 120 static sip_xaction_time_obj_t *sip_setup_timer(sip_conn_object_t, 121 sip_xaction_t *, _sip_msg_t *, 122 sip_timer_t, int); 123 124 /* 125 * Return a timer object 126 */ 127 static sip_xaction_time_obj_t * 128 sip_setup_timer(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 129 _sip_msg_t *sip_msg, sip_timer_t timer, int type) 130 { 131 sip_xaction_time_obj_t *sip_timer_obj = NULL; 132 133 sip_timer_obj = (sip_xaction_time_obj_t *) 134 malloc(sizeof (sip_xaction_time_obj_t)); 135 if (sip_timer_obj == NULL) 136 return (NULL); 137 if (SIP_IS_TIMER_RUNNING(timer)) 138 SIP_CANCEL_TIMER(timer); 139 sip_timer_obj->sip_xaction_timer_type = type; 140 sip_timer_obj->sip_xaction_timer_xport = sip_conn_transport(conn_obj); 141 sip_timer_obj->sip_trans = sip_trans; 142 /* 143 * Save the message 144 */ 145 if (sip_msg != NULL) { 146 (void) sip_add_conn_obj_cache(conn_obj, (void *)sip_trans); 147 if (sip_trans->sip_xaction_last_msg != NULL) { 148 SIP_MSG_REFCNT_DECR(sip_trans->sip_xaction_last_msg); 149 sip_trans->sip_xaction_last_msg = NULL; 150 } 151 SIP_MSG_REFCNT_INCR(sip_msg); 152 sip_trans->sip_xaction_last_msg = sip_msg; 153 } 154 return (sip_timer_obj); 155 } 156 157 /* 158 * --------------------------- Output Routines --------------------------- 159 */ 160 161 /* 162 * Send a SIP message, request or response, out 163 */ 164 int 165 sip_xaction_output(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 166 _sip_msg_t *msg) 167 { 168 sip_message_type_t *sip_msg_info; 169 int ret; 170 171 assert(conn_obj != NULL); 172 sip_msg_info = msg->sip_msg_req_res; 173 174 if (sip_msg_info->is_request) 175 return (sip_clnt_xaction_output(conn_obj, sip_trans, msg)); 176 177 ret = sip_srv_xaction_output(conn_obj, sip_trans, msg); 178 179 return (ret); 180 } 181 182 /* 183 * Send a Request out 184 */ 185 static int 186 sip_clnt_xaction_output(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 187 _sip_msg_t *msg) 188 { 189 sip_xaction_time_obj_t *timer_obj_A = NULL; 190 sip_xaction_time_obj_t *timer_obj_B = NULL; 191 sip_xaction_time_obj_t *timer_obj_E = NULL; 192 sip_xaction_time_obj_t *timer_obj_F = NULL; 193 sip_message_type_t *sip_msg_info; 194 int prev_state; 195 int error = 0; 196 boolean_t isreliable; 197 198 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 199 prev_state = sip_trans->sip_xaction_state; 200 assert(msg->sip_msg_req_res != NULL); 201 sip_msg_info = msg->sip_msg_req_res; 202 isreliable = sip_is_conn_reliable(conn_obj); 203 204 if (sip_msg_info->sip_req_method == INVITE) { 205 /* 206 * if transport is not reliable, start TIMER A. 207 */ 208 if (!isreliable) { 209 timer_obj_A = sip_setup_timer(conn_obj, sip_trans, 210 msg, sip_trans->sip_xaction_TA, 211 SIP_XACTION_TIMER_A); 212 if (timer_obj_A == NULL) { 213 error = ENOMEM; 214 goto error_ret; 215 } 216 } 217 218 timer_obj_B = sip_setup_timer(conn_obj, sip_trans, NULL, 219 sip_trans->sip_xaction_TB, SIP_XACTION_TIMER_B); 220 if (timer_obj_B == NULL) { 221 error = ENOMEM; 222 goto error_ret; 223 } 224 if (timer_obj_A != NULL) { 225 SIP_SCHED_TIMER(sip_trans->sip_xaction_TA, timer_obj_A, 226 sip_xaction_state_timer_fire); 227 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TA)) { 228 error = ENOMEM; 229 goto error_ret; 230 } 231 } 232 SIP_SCHED_TIMER(sip_trans->sip_xaction_TB, timer_obj_B, 233 sip_xaction_state_timer_fire); 234 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TB)) { 235 if (timer_obj_A != NULL) 236 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TA) 237 error = ENOMEM; 238 goto error_ret; 239 } 240 sip_trans->sip_xaction_state = SIP_CLNT_CALLING; 241 } else { 242 /* 243 * if transport is not reliable, start rexmit Timer E. 244 */ 245 if (!isreliable) { 246 timer_obj_E = sip_setup_timer(conn_obj, sip_trans, msg, 247 sip_trans->sip_xaction_TE, SIP_XACTION_TIMER_E); 248 if (timer_obj_E == NULL) { 249 error = ENOMEM; 250 goto error_ret; 251 } 252 } 253 /* 254 * Start transaction Timer F 255 */ 256 timer_obj_F = sip_setup_timer(conn_obj, sip_trans, NULL, 257 sip_trans->sip_xaction_TF, SIP_XACTION_TIMER_F); 258 if (timer_obj_F == NULL) { 259 error = ENOMEM; 260 goto error_ret; 261 } 262 if (timer_obj_E != NULL) { 263 SIP_SCHED_TIMER(sip_trans->sip_xaction_TE, timer_obj_E, 264 sip_xaction_state_timer_fire); 265 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TE)) { 266 error = ENOMEM; 267 goto error_ret; 268 } 269 } 270 SIP_SCHED_TIMER(sip_trans->sip_xaction_TF, timer_obj_F, 271 sip_xaction_state_timer_fire); 272 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TF)) { 273 if (timer_obj_E != NULL) 274 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TE) 275 error = ENOMEM; 276 goto error_ret; 277 } 278 sip_trans->sip_xaction_state = SIP_CLNT_TRYING; 279 } 280 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 281 if (sip_xaction_ulp_state_cb != NULL) { 282 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 283 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 284 } 285 return (0); 286 287 error_ret: 288 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 289 if (timer_obj_A != NULL) 290 free(timer_obj_A); 291 if (timer_obj_B != NULL) 292 free(timer_obj_B); 293 if (timer_obj_E != NULL) 294 free(timer_obj_E); 295 if (timer_obj_F != NULL) 296 free(timer_obj_F); 297 return (error); 298 } 299 300 /* 301 * Send a response out 302 */ 303 static int 304 sip_srv_xaction_output(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 305 _sip_msg_t *msg) 306 { 307 int ret; 308 309 if (sip_trans->sip_xaction_method == INVITE) 310 ret = sip_srv_xaction_inv_res(conn_obj, sip_trans, msg); 311 else 312 ret = sip_srv_xaction_noninv_res(conn_obj, sip_trans, msg); 313 return (ret); 314 } 315 316 /* 317 * Send a INVITE response out 318 */ 319 static int 320 sip_srv_xaction_inv_res(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 321 _sip_msg_t *msg) 322 { 323 int resp_code; 324 sip_xaction_time_obj_t *timer_obj_G = NULL; 325 sip_xaction_time_obj_t *timer_obj_H = NULL; 326 sip_message_type_t *sip_msg_info = msg->sip_msg_req_res; 327 int prev_state; 328 boolean_t isreliable; 329 330 isreliable = sip_is_conn_reliable(conn_obj); 331 332 resp_code = sip_msg_info->sip_resp_code; 333 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 334 prev_state = sip_trans->sip_xaction_state; 335 switch (sip_trans->sip_xaction_state) { 336 case SIP_SRV_INV_PROCEEDING: 337 if (SIP_PROVISIONAL_RESP(resp_code)) { 338 if (sip_trans->sip_xaction_last_msg != NULL) { 339 SIP_MSG_REFCNT_DECR( 340 sip_trans->sip_xaction_last_msg); 341 sip_trans->sip_xaction_last_msg = NULL; 342 } 343 SIP_MSG_REFCNT_INCR(msg); 344 sip_trans->sip_xaction_last_msg = msg; 345 (void) sip_add_conn_obj_cache(conn_obj, 346 (void *)sip_trans); 347 } else if (SIP_OK_RESP(resp_code)) { 348 sip_trans->sip_xaction_state = 349 SIP_SRV_INV_TERMINATED; 350 } else if (SIP_NONOK_FINAL_RESP(resp_code)) { 351 if (sip_trans->sip_xaction_last_msg != NULL) { 352 SIP_MSG_REFCNT_DECR( 353 sip_trans->sip_xaction_last_msg); 354 sip_trans->sip_xaction_last_msg = NULL; 355 } 356 SIP_MSG_REFCNT_INCR(msg); 357 sip_trans->sip_xaction_last_msg = msg; 358 (void) sip_add_conn_obj_cache(conn_obj, 359 (void *)sip_trans); 360 /* 361 * For unreliable transport start timer G 362 */ 363 if (!isreliable) { 364 timer_obj_G = sip_setup_timer( 365 conn_obj, sip_trans, 366 NULL, sip_trans->sip_xaction_TG, 367 SIP_XACTION_TIMER_G); 368 if (timer_obj_G == NULL) { 369 (void) pthread_mutex_unlock( 370 &sip_trans-> 371 sip_xaction_mutex); 372 return (ENOMEM); 373 } 374 } 375 /* 376 * Start Timer H 377 */ 378 timer_obj_H = sip_setup_timer( 379 conn_obj, sip_trans, 380 NULL, sip_trans->sip_xaction_TH, 381 SIP_XACTION_TIMER_H); 382 if (timer_obj_H == NULL) { 383 if (timer_obj_G != NULL) 384 free(timer_obj_G); 385 (void) pthread_mutex_unlock( 386 &sip_trans->sip_xaction_mutex); 387 return (ENOMEM); 388 } 389 if (timer_obj_G != NULL) { 390 SIP_SCHED_TIMER( 391 sip_trans->sip_xaction_TG, 392 timer_obj_G, 393 sip_xaction_state_timer_fire); 394 if (!SIP_IS_TIMER_RUNNING( 395 sip_trans->sip_xaction_TG)) { 396 (void) pthread_mutex_unlock( 397 &sip_trans-> 398 sip_xaction_mutex); 399 free(timer_obj_G); 400 return (ENOMEM); 401 } 402 } 403 if (timer_obj_H != NULL) { 404 SIP_SCHED_TIMER( 405 sip_trans->sip_xaction_TH, 406 timer_obj_H, 407 sip_xaction_state_timer_fire); 408 if (!SIP_IS_TIMER_RUNNING( 409 sip_trans->sip_xaction_TH)) { 410 if (timer_obj_G != NULL) { 411 SIP_CANCEL_TIMER( 412 sip_trans-> 413 sip_xaction_TG); 414 free(timer_obj_G); 415 } 416 (void) pthread_mutex_unlock( 417 &sip_trans-> 418 sip_xaction_mutex); 419 free(timer_obj_H); 420 return (ENOMEM); 421 } 422 } 423 sip_trans->sip_xaction_state = 424 SIP_SRV_INV_COMPLETED; 425 } 426 break; 427 default: 428 (void) pthread_mutex_unlock( 429 &sip_trans->sip_xaction_mutex); 430 return (EPROTO); 431 } 432 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 433 if (prev_state != sip_trans->sip_xaction_state && 434 sip_xaction_ulp_state_cb != NULL) { 435 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 436 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 437 } 438 return (0); 439 } 440 441 /* 442 * Send a NON-INVITE response out 443 */ 444 static int 445 sip_srv_xaction_noninv_res(sip_conn_object_t conn_obj, 446 sip_xaction_t *sip_trans, _sip_msg_t *msg) 447 { 448 int resp_code; 449 sip_xaction_time_obj_t *timer_obj_J = NULL; 450 sip_message_type_t *sip_msg_info = msg->sip_msg_req_res; 451 int prev_state; 452 boolean_t isreliable; 453 454 resp_code = sip_msg_info->sip_resp_code; 455 isreliable = sip_is_conn_reliable(conn_obj); 456 457 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 458 prev_state = sip_trans->sip_xaction_state; 459 switch (sip_trans->sip_xaction_state) { 460 case SIP_SRV_TRYING: 461 if (sip_trans->sip_xaction_last_msg != NULL) { 462 SIP_MSG_REFCNT_DECR( 463 sip_trans->sip_xaction_last_msg); 464 sip_trans->sip_xaction_last_msg = NULL; 465 } 466 SIP_MSG_REFCNT_INCR(msg); 467 sip_trans->sip_xaction_last_msg = msg; 468 (void) sip_add_conn_obj_cache(conn_obj, 469 (void *)sip_trans); 470 if (SIP_PROVISIONAL_RESP(resp_code)) { 471 sip_trans->sip_xaction_state = 472 SIP_SRV_NONINV_PROCEEDING; 473 } else if (SIP_FINAL_RESP(resp_code)) { 474 /* 475 * For unreliable transports, start Timer J 476 */ 477 if (!isreliable) { 478 timer_obj_J = sip_setup_timer( 479 conn_obj, sip_trans, 480 NULL, sip_trans->sip_xaction_TJ, 481 SIP_XACTION_TIMER_J); 482 if (timer_obj_J == NULL) { 483 (void) pthread_mutex_unlock(& 484 sip_trans-> 485 sip_xaction_mutex); 486 return (ENOMEM); 487 } 488 SIP_SCHED_TIMER( 489 sip_trans->sip_xaction_TJ, 490 timer_obj_J, 491 sip_xaction_state_timer_fire); 492 if (!SIP_IS_TIMER_RUNNING( 493 sip_trans->sip_xaction_TJ)) { 494 (void) pthread_mutex_unlock(& 495 sip_trans-> 496 sip_xaction_mutex); 497 free(timer_obj_J); 498 return (ENOMEM); 499 } 500 sip_trans->sip_xaction_state = 501 SIP_SRV_NONINV_COMPLETED; 502 } else { 503 sip_trans->sip_xaction_state = 504 SIP_SRV_NONINV_TERMINATED; 505 } 506 } 507 break; 508 case SIP_SRV_NONINV_PROCEEDING: 509 if (sip_trans->sip_xaction_last_msg != NULL) { 510 SIP_MSG_REFCNT_DECR( 511 sip_trans->sip_xaction_last_msg); 512 sip_trans->sip_xaction_last_msg = NULL; 513 } 514 SIP_MSG_REFCNT_INCR(msg); 515 sip_trans->sip_xaction_last_msg = msg; 516 (void) sip_add_conn_obj_cache(conn_obj, 517 (void *)sip_trans); 518 if (SIP_PROVISIONAL_RESP(resp_code)) { 519 break; 520 } else if (SIP_FINAL_RESP(resp_code)) { 521 /* 522 * For unreliable transports, start Timer J 523 */ 524 if (!isreliable) { 525 timer_obj_J = sip_setup_timer( 526 conn_obj, sip_trans, 527 NULL, sip_trans->sip_xaction_TJ, 528 SIP_XACTION_TIMER_J); 529 if (timer_obj_J == NULL) { 530 (void) pthread_mutex_unlock(& 531 sip_trans-> 532 sip_xaction_mutex); 533 return (ENOMEM); 534 } 535 SIP_SCHED_TIMER( 536 sip_trans->sip_xaction_TJ, 537 timer_obj_J, 538 sip_xaction_state_timer_fire); 539 if (!SIP_IS_TIMER_RUNNING( 540 sip_trans->sip_xaction_TJ)) { 541 (void) pthread_mutex_unlock(& 542 sip_trans-> 543 sip_xaction_mutex); 544 free(timer_obj_J); 545 return (ENOMEM); 546 } 547 sip_trans->sip_xaction_state = 548 SIP_SRV_NONINV_COMPLETED; 549 } else { 550 sip_trans->sip_xaction_state = 551 SIP_SRV_NONINV_TERMINATED; 552 } 553 } 554 break; 555 default: 556 (void) pthread_mutex_unlock( 557 &sip_trans->sip_xaction_mutex); 558 return (EPROTO); 559 } 560 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 561 if (prev_state != sip_trans->sip_xaction_state && 562 sip_xaction_ulp_state_cb != NULL) { 563 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 564 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 565 } 566 return (0); 567 } 568 569 570 /* 571 * -------------------------- Input Routines --------------------------- 572 */ 573 574 /* 575 * Process an incoming SIP message Request or Response 576 */ 577 int 578 sip_xaction_input(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 579 _sip_msg_t **sip_msg) 580 { 581 sip_message_type_t *sip_msg_info; 582 int ret; 583 584 sip_msg_info = (*sip_msg)->sip_msg_req_res; 585 if (sip_msg_info->is_request) 586 ret = sip_srv_xaction_input(conn_obj, sip_trans, sip_msg); 587 else 588 ret = sip_clnt_xaction_input(conn_obj, sip_trans, sip_msg); 589 return (ret); 590 } 591 592 /* 593 * Process a Request from the transport 594 */ 595 static int 596 sip_srv_xaction_input(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 597 _sip_msg_t **sip_msg) 598 { 599 sip_message_type_t *sip_msg_info; 600 _sip_msg_t *msg = *sip_msg; 601 int prev_state; 602 boolean_t isreliable; 603 604 sip_msg_info = msg->sip_msg_req_res; 605 isreliable = sip_is_conn_reliable(conn_obj); 606 607 /* 608 * Cancel if the original transaction has not yet got a final 609 * response and send a 487 response. 610 */ 611 if (sip_msg_info->sip_req_method == ACK) { 612 _sip_msg_t *sip_last_resp; 613 const sip_str_t *resp_to_tag; 614 const sip_str_t *req_to_tag; 615 int error; 616 sip_message_type_t *last_msg_info; 617 618 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 619 620 if (sip_trans->sip_xaction_last_msg != NULL) 621 sip_last_resp = sip_trans->sip_xaction_last_msg; 622 else 623 sip_last_resp = sip_trans->sip_xaction_orig_msg; 624 last_msg_info = sip_last_resp->sip_msg_req_res; 625 if (last_msg_info->is_request) { 626 (void) pthread_mutex_unlock( 627 &sip_trans->sip_xaction_mutex); 628 return (0); 629 } 630 req_to_tag = sip_get_to_tag((sip_msg_t)msg, &error); 631 if (req_to_tag == NULL || error != 0) { 632 (void) pthread_mutex_unlock( 633 &sip_trans->sip_xaction_mutex); 634 return (0); 635 } 636 resp_to_tag = sip_get_to_tag((sip_msg_t)sip_last_resp, 637 &error); 638 if (req_to_tag == NULL || error != 0) { 639 (void) pthread_mutex_unlock( 640 &sip_trans->sip_xaction_mutex); 641 return (0); 642 } 643 if (resp_to_tag->sip_str_len != req_to_tag->sip_str_len || 644 strncmp(resp_to_tag->sip_str_ptr, req_to_tag->sip_str_ptr, 645 req_to_tag->sip_str_len) != 0) { 646 (void) pthread_mutex_unlock( 647 &sip_trans->sip_xaction_mutex); 648 return (0); 649 } 650 prev_state = sip_trans->sip_xaction_state; 651 if (sip_trans->sip_xaction_state == SIP_SRV_INV_COMPLETED) { 652 sip_xaction_time_obj_t *timer_obj_I = NULL; 653 654 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TG); 655 /* 656 * Cancel Timer H and goto TERMINATED state for 657 * reliable transports. 658 */ 659 if (isreliable) { 660 SIP_CANCEL_TIMER( 661 sip_trans->sip_xaction_TH); 662 sip_trans->sip_xaction_state = 663 SIP_SRV_INV_TERMINATED; 664 (void) pthread_mutex_unlock( 665 &sip_trans->sip_xaction_mutex); 666 if (sip_xaction_ulp_state_cb != NULL) { 667 sip_xaction_ulp_state_cb( 668 (sip_transaction_t)sip_trans, 669 (sip_msg_t)msg, prev_state, 670 sip_trans->sip_xaction_state); 671 } 672 return (0); 673 } 674 /* 675 * For unreliable transports, start TIMER I and 676 * transition to CONFIRMED state. 677 */ 678 timer_obj_I = sip_setup_timer(conn_obj, sip_trans, 679 NULL, 680 sip_trans->sip_xaction_TI, SIP_XACTION_TIMER_I); 681 if (timer_obj_I == NULL) { 682 (void) pthread_mutex_unlock( 683 &sip_trans->sip_xaction_mutex); 684 return (ENOMEM); 685 } 686 SIP_SCHED_TIMER(sip_trans->sip_xaction_TI, 687 timer_obj_I, sip_xaction_state_timer_fire); 688 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TI)) { 689 (void) pthread_mutex_unlock( 690 &sip_trans->sip_xaction_mutex); 691 free(timer_obj_I); 692 return (ENOMEM); 693 } 694 sip_trans->sip_xaction_state = SIP_SRV_CONFIRMED; 695 } 696 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 697 if (prev_state != sip_trans->sip_xaction_state && 698 sip_xaction_ulp_state_cb != NULL) { 699 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 700 (sip_msg_t)msg, prev_state, 701 sip_trans->sip_xaction_state); 702 } 703 return (0); 704 } else if (sip_msg_info->sip_req_method == CANCEL) { 705 if (sip_trans->sip_xaction_method == INVITE) { 706 (void) pthread_mutex_unlock( 707 &sip_trans->sip_xaction_mutex); 708 return (0); 709 } 710 } 711 if (sip_msg_info->sip_req_method == INVITE) { 712 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 713 assert(sip_trans->sip_xaction_method == INVITE); 714 /* 715 * Retransmitted invite 716 */ 717 switch (sip_trans->sip_xaction_state) { 718 case SIP_SRV_INV_PROCEEDING: 719 case SIP_SRV_INV_COMPLETED: 720 if (sip_trans->sip_xaction_last_msg != NULL) { 721 _sip_msg_t *new_msg; 722 723 new_msg = 724 sip_trans->sip_xaction_last_msg; 725 (void) sip_stack_send(conn_obj, 726 new_msg->sip_msg_buf, 727 new_msg->sip_msg_len); 728 } 729 break; 730 default: 731 (void) pthread_mutex_unlock( 732 &sip_trans->sip_xaction_mutex); 733 return (EPROTO); 734 } 735 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 736 sip_free_msg((sip_msg_t)msg); 737 *sip_msg = NULL; 738 return (0); 739 } 740 /* 741 * Retransmitted request 742 */ 743 assert(sip_trans->sip_xaction_method != INVITE); 744 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 745 switch (sip_trans->sip_xaction_state) { 746 case SIP_SRV_NONINV_PROCEEDING: 747 case SIP_SRV_NONINV_COMPLETED: 748 if (sip_trans->sip_xaction_last_msg != NULL) { 749 _sip_msg_t *new_msg; 750 751 new_msg = sip_trans->sip_xaction_last_msg; 752 (void) sip_stack_send(conn_obj, 753 new_msg->sip_msg_buf, new_msg->sip_msg_len); 754 } 755 break; 756 default: 757 (void) pthread_mutex_unlock( 758 &sip_trans->sip_xaction_mutex); 759 return (EPROTO); 760 } 761 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 762 sip_free_msg((sip_msg_t)msg); 763 *sip_msg = NULL; 764 return (0); 765 } 766 767 /* 768 * Process a Response 769 */ 770 static int 771 sip_clnt_xaction_input(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 772 _sip_msg_t **msg) 773 { 774 int ret; 775 776 if (sip_trans->sip_xaction_method == INVITE) 777 ret = sip_clnt_xaction_inv_res(conn_obj, sip_trans, msg); 778 else 779 ret = sip_clnt_xaction_noninv_res(conn_obj, sip_trans, msg); 780 781 return (ret); 782 } 783 784 static int 785 sip_create_send_nonOKack(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 786 _sip_msg_t *msg, boolean_t copy) 787 { 788 _sip_msg_t *ack_msg; 789 int ret = 0; 790 791 ack_msg = (_sip_msg_t *)sip_new_msg(); 792 if (ack_msg == NULL) 793 return (ENOMEM); 794 if ((ret = sip_create_nonOKack( 795 (sip_msg_t)sip_trans->sip_xaction_orig_msg, (sip_msg_t)msg, 796 (sip_msg_t)ack_msg)) != 0) { 797 sip_free_msg((sip_msg_t)ack_msg); 798 return (ret); 799 } 800 if ((ret = sip_stack_send(conn_obj, ack_msg->sip_msg_buf, 801 ack_msg->sip_msg_len)) != 0) { 802 sip_free_msg((sip_msg_t)ack_msg); 803 return (ret); 804 } 805 if (copy) { 806 SIP_MSG_REFCNT_INCR(ack_msg); 807 if (sip_trans->sip_xaction_last_msg != NULL) { 808 SIP_MSG_REFCNT_DECR(sip_trans->sip_xaction_last_msg); 809 sip_trans->sip_xaction_last_msg = NULL; 810 } 811 sip_trans->sip_xaction_last_msg = ack_msg; 812 } 813 sip_free_msg((sip_msg_t)ack_msg); 814 return (0); 815 } 816 817 /* 818 * Process a INVITE Response 819 */ 820 static int 821 sip_clnt_xaction_inv_res(sip_conn_object_t conn_obj, sip_xaction_t *sip_trans, 822 _sip_msg_t **sip_msg) 823 { 824 int resp_code; 825 _sip_msg_t *msg = *sip_msg; 826 sip_xaction_time_obj_t *timer_obj_D = NULL; 827 sip_message_type_t *sip_msg_info; 828 int prev_state; 829 boolean_t isreliable; 830 831 assert(msg->sip_msg_req_res != NULL); 832 833 sip_msg_info = msg->sip_msg_req_res; 834 resp_code = sip_msg_info->sip_resp_code; 835 isreliable = sip_is_conn_reliable(conn_obj); 836 837 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 838 prev_state = sip_trans->sip_xaction_state; 839 switch (sip_trans->sip_xaction_state) { 840 case SIP_CLNT_CALLING: 841 if (SIP_PROVISIONAL_RESP(resp_code)) { 842 /* 843 * sip_trans->sip_xaction_last_msg ? 844 */ 845 SIP_CANCEL_TIMER( 846 sip_trans->sip_xaction_TA); 847 sip_trans->sip_xaction_state = 848 SIP_CLNT_INV_PROCEEDING; 849 } else if (SIP_OK_RESP(resp_code)) { 850 /* 851 * sip_trans->sip_xaction_last_msg ? 852 */ 853 SIP_CANCEL_TIMER( 854 sip_trans->sip_xaction_TA); 855 SIP_CANCEL_TIMER( 856 sip_trans->sip_xaction_TB); 857 sip_trans->sip_xaction_state = 858 SIP_CLNT_INV_TERMINATED; 859 } else if (SIP_NONOK_FINAL_RESP(resp_code)) { 860 int ret; 861 862 /* 863 * sip_trans->sip_xaction_last_msg ? 864 */ 865 SIP_CANCEL_TIMER( 866 sip_trans->sip_xaction_TA); 867 SIP_CANCEL_TIMER( 868 sip_trans->sip_xaction_TB); 869 if ((ret = sip_create_send_nonOKack(conn_obj, 870 sip_trans, msg, B_FALSE)) != 0) { 871 (void) pthread_mutex_unlock( 872 &sip_trans->sip_xaction_mutex); 873 return (ret); 874 } 875 /* 876 * start timer D for unreliable transports 877 */ 878 if (!isreliable) { 879 timer_obj_D = sip_setup_timer( 880 conn_obj, sip_trans, 881 NULL, sip_trans->sip_xaction_TD, 882 SIP_XACTION_TIMER_D); 883 if (timer_obj_D == NULL) { 884 (void) pthread_mutex_unlock( 885 &sip_trans-> 886 sip_xaction_mutex); 887 return (ENOMEM); 888 } 889 SIP_SCHED_TIMER( 890 sip_trans->sip_xaction_TD, 891 timer_obj_D, 892 sip_xaction_state_timer_fire); 893 if (!SIP_IS_TIMER_RUNNING( 894 sip_trans->sip_xaction_TD)) { 895 (void) pthread_mutex_unlock( 896 &sip_trans-> 897 sip_xaction_mutex); 898 free(timer_obj_D); 899 return (ENOMEM); 900 } 901 sip_trans->sip_xaction_state = 902 SIP_CLNT_INV_COMPLETED; 903 } else { 904 sip_trans->sip_xaction_state = 905 SIP_CLNT_INV_TERMINATED; 906 } 907 } else { 908 /* 909 * Invalid resp_code 910 */ 911 (void) pthread_mutex_unlock( 912 &sip_trans->sip_xaction_mutex); 913 return (EPROTO); 914 } 915 break; 916 case SIP_CLNT_INV_PROCEEDING: 917 if (SIP_PROVISIONAL_RESP(resp_code)) { 918 break; 919 } else if (SIP_OK_RESP(resp_code)) { 920 SIP_CANCEL_TIMER( 921 sip_trans->sip_xaction_TB); 922 sip_trans->sip_xaction_state = 923 SIP_CLNT_INV_TERMINATED; 924 } else if (SIP_NONOK_FINAL_RESP(resp_code)) { 925 int ret; 926 927 SIP_CANCEL_TIMER( 928 sip_trans->sip_xaction_TB); 929 if ((ret = sip_create_send_nonOKack(conn_obj, 930 sip_trans, msg, B_FALSE)) != 0) { 931 (void) pthread_mutex_unlock( 932 &sip_trans->sip_xaction_mutex); 933 return (ret); 934 } 935 /* 936 * start timer D for unreliable transports 937 */ 938 if (!isreliable) { 939 timer_obj_D = sip_setup_timer( 940 conn_obj, sip_trans, 941 NULL, sip_trans->sip_xaction_TD, 942 SIP_XACTION_TIMER_D); 943 if (timer_obj_D == NULL) { 944 (void) pthread_mutex_unlock( 945 &sip_trans-> 946 sip_xaction_mutex); 947 return (ENOMEM); 948 } 949 SIP_SCHED_TIMER( 950 sip_trans->sip_xaction_TD, 951 timer_obj_D, 952 sip_xaction_state_timer_fire); 953 if (!SIP_IS_TIMER_RUNNING( 954 sip_trans->sip_xaction_TD)) { 955 (void) pthread_mutex_unlock( 956 &sip_trans-> 957 sip_xaction_mutex); 958 free(timer_obj_D); 959 return (ENOMEM); 960 } 961 sip_trans->sip_xaction_state = 962 SIP_CLNT_INV_COMPLETED; 963 } else { 964 sip_trans->sip_xaction_state = 965 SIP_CLNT_INV_TERMINATED; 966 } 967 } else { 968 (void) pthread_mutex_unlock( 969 &sip_trans->sip_xaction_mutex); 970 return (EPROTO); 971 } 972 break; 973 case SIP_CLNT_INV_COMPLETED: 974 /* 975 * Transport error takes it to 976 * SIP_CLNT_INV_TERMINATED 977 */ 978 if (SIP_NONOK_FINAL_RESP(resp_code)) { 979 int ret; 980 981 if ((ret = sip_create_send_nonOKack(conn_obj, 982 sip_trans, msg, B_FALSE)) != 0) { 983 (void) pthread_mutex_unlock( 984 &sip_trans->sip_xaction_mutex); 985 return (ret); 986 } 987 } else { 988 /* 989 * Invalid resp_code 990 */ 991 (void) pthread_mutex_unlock( 992 &sip_trans->sip_xaction_mutex); 993 return (EPROTO); 994 } 995 break; 996 default: 997 (void) pthread_mutex_unlock( 998 &sip_trans->sip_xaction_mutex); 999 return (EPROTO); 1000 } 1001 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 1002 if (prev_state != sip_trans->sip_xaction_state && 1003 sip_xaction_ulp_state_cb != NULL) { 1004 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 1005 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 1006 } 1007 return (0); 1008 } 1009 1010 /* 1011 * Process a NON-INVITE Response 1012 */ 1013 static int 1014 sip_clnt_xaction_noninv_res(sip_conn_object_t conn_obj, 1015 sip_xaction_t *sip_trans, _sip_msg_t **sip_msg) 1016 { 1017 int resp_code; 1018 sip_xaction_time_obj_t *timer_obj_K = NULL; 1019 sip_message_type_t *sip_msg_info; 1020 int prev_state; 1021 _sip_msg_t *msg = *sip_msg; 1022 boolean_t isreliable; 1023 1024 assert(msg->sip_msg_req_res != NULL); 1025 assert(sip_trans != NULL); 1026 1027 sip_msg_info = msg->sip_msg_req_res; 1028 isreliable = sip_is_conn_reliable(conn_obj); 1029 resp_code = sip_msg_info->sip_resp_code; 1030 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 1031 prev_state = sip_trans->sip_xaction_state; 1032 switch (sip_trans->sip_xaction_state) { 1033 case SIP_CLNT_TRYING: 1034 if (SIP_PROVISIONAL_RESP(resp_code)) { 1035 sip_trans->sip_xaction_state = 1036 SIP_CLNT_NONINV_PROCEEDING; 1037 } else if (SIP_FINAL_RESP(resp_code)) { 1038 SIP_CANCEL_TIMER( 1039 sip_trans->sip_xaction_TE); 1040 SIP_CANCEL_TIMER( 1041 sip_trans->sip_xaction_TF); 1042 /* 1043 * Start timer K for unreliable transports 1044 */ 1045 if (!isreliable) { 1046 timer_obj_K = sip_setup_timer( 1047 conn_obj, sip_trans, 1048 NULL, sip_trans->sip_xaction_TK, 1049 SIP_XACTION_TIMER_K); 1050 if (timer_obj_K == NULL) { 1051 (void) pthread_mutex_unlock(& 1052 sip_trans-> 1053 sip_xaction_mutex); 1054 return (ENOMEM); 1055 } 1056 SIP_SCHED_TIMER( 1057 sip_trans->sip_xaction_TK, 1058 timer_obj_K, 1059 sip_xaction_state_timer_fire); 1060 if (!SIP_IS_TIMER_RUNNING( 1061 sip_trans->sip_xaction_TK)) { 1062 (void) pthread_mutex_unlock( 1063 &sip_trans-> 1064 sip_xaction_mutex); 1065 free(timer_obj_K); 1066 return (ENOMEM); 1067 } 1068 sip_trans->sip_xaction_state = 1069 SIP_CLNT_NONINV_COMPLETED; 1070 } else { 1071 sip_trans->sip_xaction_state = 1072 SIP_CLNT_NONINV_TERMINATED; 1073 } 1074 } 1075 break; 1076 case SIP_CLNT_NONINV_PROCEEDING: 1077 if (SIP_PROVISIONAL_RESP(resp_code)) { 1078 break; 1079 } else if (SIP_FINAL_RESP(resp_code)) { 1080 SIP_CANCEL_TIMER( 1081 sip_trans->sip_xaction_TE); 1082 SIP_CANCEL_TIMER( 1083 sip_trans->sip_xaction_TF); 1084 /* 1085 * Start timer K for unreliable transports 1086 */ 1087 if (!isreliable) { 1088 timer_obj_K = sip_setup_timer( 1089 conn_obj, sip_trans, 1090 NULL, sip_trans->sip_xaction_TK, 1091 SIP_XACTION_TIMER_K); 1092 if (timer_obj_K == NULL) { 1093 (void) pthread_mutex_unlock(& 1094 sip_trans-> 1095 sip_xaction_mutex); 1096 return (ENOMEM); 1097 } 1098 SIP_SCHED_TIMER( 1099 sip_trans->sip_xaction_TK, 1100 timer_obj_K, 1101 sip_xaction_state_timer_fire); 1102 if (!SIP_IS_TIMER_RUNNING( 1103 sip_trans->sip_xaction_TK)) { 1104 (void) pthread_mutex_unlock( 1105 &sip_trans-> 1106 sip_xaction_mutex); 1107 free(timer_obj_K); 1108 return (ENOMEM); 1109 } 1110 sip_trans->sip_xaction_state = 1111 SIP_CLNT_NONINV_COMPLETED; 1112 } else { 1113 sip_trans->sip_xaction_state = 1114 SIP_CLNT_NONINV_TERMINATED; 1115 } 1116 } 1117 break; 1118 default: 1119 (void) pthread_mutex_unlock( 1120 &sip_trans->sip_xaction_mutex); 1121 return (EPROTO); 1122 } 1123 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 1124 if (prev_state != sip_trans->sip_xaction_state && 1125 sip_xaction_ulp_state_cb != NULL) { 1126 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 1127 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 1128 } 1129 return (0); 1130 } 1131 1132 /* 1133 * If there is a transport error, sending the message out, terminate the 1134 * transaction. 1135 */ 1136 /* ARGSUSED */ 1137 void 1138 sip_xaction_terminate(sip_xaction_t *sip_trans, _sip_msg_t *msg, int transport) 1139 { 1140 sip_message_type_t *sip_msg_info; 1141 int state; 1142 int prev_state; 1143 1144 sip_msg_info = msg->sip_msg_req_res; 1145 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 1146 if (sip_msg_info->is_request) { 1147 if (sip_trans->sip_xaction_method == INVITE) 1148 state = SIP_CLNT_INV_TERMINATED; 1149 else 1150 state = SIP_CLNT_NONINV_TERMINATED; 1151 } else { 1152 if (sip_trans->sip_xaction_method == INVITE) 1153 state = SIP_SRV_INV_TERMINATED; 1154 else 1155 state = SIP_SRV_NONINV_TERMINATED; 1156 } 1157 prev_state = sip_trans->sip_xaction_state; 1158 sip_trans->sip_xaction_state = state; 1159 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 1160 if (sip_xaction_ulp_state_cb != NULL) { 1161 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 1162 (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); 1163 } 1164 sip_xaction_delete(sip_trans); 1165 } 1166 1167 /* 1168 * --------------------------- Timer Routine --------------------------- 1169 */ 1170 1171 void 1172 sip_xaction_state_timer_fire(void *args) 1173 { 1174 sip_xaction_time_obj_t *time_obj = (sip_xaction_time_obj_t *)args; 1175 sip_xaction_t *sip_trans = time_obj->sip_trans; 1176 _sip_msg_t *new_msg; 1177 boolean_t destroy_trans = B_FALSE; 1178 sip_conn_object_t conn_obj; 1179 int prev_state; 1180 1181 assert(time_obj != NULL); 1182 1183 (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); 1184 prev_state = sip_trans->sip_xaction_state; 1185 switch (time_obj->sip_xaction_timer_type) { 1186 case SIP_XACTION_TIMER_A: 1187 if (sip_trans->sip_xaction_state != SIP_CLNT_CALLING) 1188 break; 1189 /* 1190 * Assert candidate 1191 */ 1192 if (sip_trans->sip_xaction_last_msg == NULL) 1193 break; 1194 if (sip_trans->sip_xaction_conn_obj == NULL) 1195 break; 1196 new_msg = sip_trans->sip_xaction_last_msg; 1197 conn_obj = sip_trans->sip_xaction_conn_obj; 1198 if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, 1199 new_msg->sip_msg_len) != 0) { 1200 sip_del_conn_obj_cache( 1201 sip_trans->sip_xaction_conn_obj, 1202 (void *)sip_trans); 1203 sip_trans->sip_xaction_state = 1204 SIP_CLNT_INV_TERMINATED; 1205 (void) pthread_mutex_unlock( 1206 &sip_trans->sip_xaction_mutex); 1207 if (sip_xaction_ulp_state_cb != NULL) { 1208 sip_xaction_ulp_state_cb( 1209 (sip_transaction_t)sip_trans, NULL, 1210 prev_state, sip_trans->sip_xaction_state); 1211 } 1212 if (sip_xaction_ulp_trans_err != NULL) { 1213 sip_xaction_ulp_trans_err(sip_trans, 0, 1214 NULL); 1215 } 1216 sip_xaction_delete(sip_trans); 1217 free(time_obj); 1218 return; 1219 } 1220 SIP_SET_TIMEOUT(sip_trans->sip_xaction_TA, 1221 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TA)); 1222 /* 1223 * Reschedule the timer 1224 */ 1225 SIP_SCHED_TIMER(sip_trans->sip_xaction_TA, 1226 time_obj, sip_xaction_state_timer_fire); 1227 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TA)) { 1228 sip_del_conn_obj_cache( 1229 sip_trans->sip_xaction_conn_obj, 1230 (void *)sip_trans); 1231 sip_trans->sip_xaction_state = 1232 SIP_CLNT_INV_TERMINATED; 1233 (void) pthread_mutex_unlock( 1234 &sip_trans->sip_xaction_mutex); 1235 if (sip_xaction_ulp_state_cb != NULL) { 1236 sip_xaction_ulp_state_cb( 1237 (sip_transaction_t)sip_trans, NULL, 1238 prev_state, sip_trans->sip_xaction_state); 1239 } 1240 if (sip_xaction_ulp_trans_err != NULL) { 1241 sip_xaction_ulp_trans_err(sip_trans, 0, 1242 NULL); 1243 } 1244 sip_xaction_delete(sip_trans); 1245 free(time_obj); 1246 return; 1247 } 1248 (void) pthread_mutex_unlock( 1249 &sip_trans->sip_xaction_mutex); 1250 return; 1251 case SIP_XACTION_TIMER_B: 1252 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TA); 1253 if (sip_trans->sip_xaction_state == SIP_CLNT_CALLING) { 1254 sip_trans->sip_xaction_state = 1255 SIP_CLNT_INV_TERMINATED; 1256 (void) pthread_mutex_unlock( 1257 &sip_trans->sip_xaction_mutex); 1258 if (sip_xaction_ulp_state_cb != NULL) { 1259 sip_xaction_ulp_state_cb( 1260 (sip_transaction_t)sip_trans, NULL, 1261 prev_state, sip_trans->sip_xaction_state); 1262 } 1263 if (sip_xaction_ulp_trans_err != NULL) { 1264 sip_xaction_ulp_trans_err(sip_trans, 0, 1265 NULL); 1266 } 1267 sip_xaction_delete(sip_trans); 1268 free(time_obj); 1269 return; 1270 } 1271 break; 1272 case SIP_XACTION_TIMER_D: 1273 if (sip_trans->sip_xaction_state == 1274 SIP_CLNT_INV_COMPLETED) { 1275 SIP_CANCEL_TIMER( 1276 sip_trans->sip_xaction_TB); 1277 sip_trans->sip_xaction_state = 1278 SIP_CLNT_INV_TERMINATED; 1279 destroy_trans = B_TRUE; 1280 } 1281 break; 1282 case SIP_XACTION_TIMER_E: 1283 /* 1284 * Assert candidate 1285 */ 1286 if (sip_trans->sip_xaction_state != SIP_CLNT_TRYING && 1287 sip_trans->sip_xaction_state != 1288 SIP_CLNT_NONINV_PROCEEDING) { 1289 break; 1290 } 1291 /* 1292 * Assert candidate 1293 */ 1294 if (sip_trans->sip_xaction_last_msg == NULL) 1295 break; 1296 if (sip_trans->sip_xaction_conn_obj == NULL) 1297 break; 1298 conn_obj = sip_trans->sip_xaction_conn_obj; 1299 new_msg = sip_trans->sip_xaction_last_msg; 1300 if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, 1301 new_msg->sip_msg_len) != 0) { 1302 sip_del_conn_obj_cache( 1303 sip_trans->sip_xaction_conn_obj, 1304 (void *)sip_trans); 1305 sip_trans->sip_xaction_state = 1306 SIP_CLNT_NONINV_TERMINATED; 1307 (void) pthread_mutex_unlock( 1308 &sip_trans->sip_xaction_mutex); 1309 if (sip_xaction_ulp_state_cb != NULL) { 1310 sip_xaction_ulp_state_cb( 1311 (sip_transaction_t)sip_trans, NULL, 1312 prev_state, sip_trans->sip_xaction_state); 1313 } 1314 if (sip_xaction_ulp_trans_err != NULL) { 1315 sip_xaction_ulp_trans_err(sip_trans, 0, 1316 NULL); 1317 } 1318 sip_xaction_delete(sip_trans); 1319 free(time_obj); 1320 return; 1321 } 1322 SIP_SET_TIMEOUT(sip_trans->sip_xaction_TE, 1323 MIN(SIP_TIMER_T2, 1324 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TE))); 1325 /* 1326 * Reschedule the timer 1327 */ 1328 SIP_SCHED_TIMER(sip_trans->sip_xaction_TE, 1329 time_obj, sip_xaction_state_timer_fire); 1330 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TE)) { 1331 sip_del_conn_obj_cache( 1332 sip_trans->sip_xaction_conn_obj, 1333 (void *)sip_trans); 1334 sip_trans->sip_xaction_state = 1335 SIP_CLNT_NONINV_TERMINATED; 1336 (void) pthread_mutex_unlock( 1337 &sip_trans->sip_xaction_mutex); 1338 if (sip_xaction_ulp_state_cb != NULL) { 1339 sip_xaction_ulp_state_cb( 1340 (sip_transaction_t)sip_trans, NULL, 1341 prev_state, sip_trans->sip_xaction_state); 1342 } 1343 if (sip_xaction_ulp_trans_err != NULL) { 1344 sip_xaction_ulp_trans_err(sip_trans, 0, 1345 NULL); 1346 } 1347 sip_xaction_delete(sip_trans); 1348 free(time_obj); 1349 return; 1350 } 1351 (void) pthread_mutex_unlock( 1352 &sip_trans->sip_xaction_mutex); 1353 return; 1354 case SIP_XACTION_TIMER_F: 1355 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TE); 1356 if (sip_trans->sip_xaction_state == SIP_CLNT_TRYING || 1357 sip_trans->sip_xaction_state == 1358 SIP_CLNT_NONINV_PROCEEDING) { 1359 sip_trans->sip_xaction_state = 1360 SIP_CLNT_NONINV_TERMINATED; 1361 (void) pthread_mutex_unlock( 1362 &sip_trans->sip_xaction_mutex); 1363 if (sip_xaction_ulp_state_cb != NULL) { 1364 sip_xaction_ulp_state_cb( 1365 (sip_transaction_t)sip_trans, NULL, 1366 prev_state, sip_trans->sip_xaction_state); 1367 } 1368 if (sip_xaction_ulp_trans_err != NULL) { 1369 sip_xaction_ulp_trans_err(sip_trans, 0, 1370 NULL); 1371 } 1372 sip_xaction_delete(sip_trans); 1373 free(time_obj); 1374 return; 1375 } 1376 break; 1377 case SIP_XACTION_TIMER_G: 1378 /* 1379 * Assert candidate 1380 */ 1381 if (sip_trans->sip_xaction_last_msg == NULL) 1382 break; 1383 if (sip_trans->sip_xaction_conn_obj == NULL) 1384 break; 1385 if (sip_trans->sip_xaction_state != 1386 SIP_SRV_INV_COMPLETED) { 1387 break; 1388 } 1389 new_msg = sip_trans->sip_xaction_last_msg; 1390 conn_obj = sip_trans->sip_xaction_conn_obj; 1391 if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, 1392 new_msg->sip_msg_len) != 0) { 1393 sip_del_conn_obj_cache( 1394 sip_trans->sip_xaction_conn_obj, 1395 (void *)sip_trans); 1396 sip_trans->sip_xaction_state = 1397 SIP_SRV_INV_TERMINATED; 1398 (void) pthread_mutex_unlock( 1399 &sip_trans->sip_xaction_mutex); 1400 if (sip_xaction_ulp_state_cb != NULL) { 1401 sip_xaction_ulp_state_cb( 1402 (sip_transaction_t)sip_trans, NULL, 1403 prev_state, sip_trans->sip_xaction_state); 1404 } 1405 if (sip_xaction_ulp_trans_err != NULL) { 1406 sip_xaction_ulp_trans_err(sip_trans, 0, 1407 NULL); 1408 } 1409 sip_xaction_delete(sip_trans); 1410 free(time_obj); 1411 return; 1412 } 1413 SIP_SET_TIMEOUT(sip_trans->sip_xaction_TG, 1414 MIN(SIP_TIMER_T2, 1415 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TG))); 1416 SIP_SCHED_TIMER(sip_trans->sip_xaction_TG, 1417 time_obj, sip_xaction_state_timer_fire); 1418 if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TG)) { 1419 sip_del_conn_obj_cache( 1420 sip_trans->sip_xaction_conn_obj, 1421 (void *)sip_trans); 1422 sip_trans->sip_xaction_state = 1423 SIP_SRV_INV_TERMINATED; 1424 (void) pthread_mutex_unlock( 1425 &sip_trans->sip_xaction_mutex); 1426 if (sip_xaction_ulp_state_cb != NULL) { 1427 sip_xaction_ulp_state_cb( 1428 (sip_transaction_t)sip_trans, NULL, 1429 prev_state, sip_trans->sip_xaction_state); 1430 } 1431 if (sip_xaction_ulp_trans_err != NULL) { 1432 sip_xaction_ulp_trans_err(sip_trans, 0, 1433 NULL); 1434 } 1435 sip_xaction_delete(sip_trans); 1436 free(time_obj); 1437 return; 1438 } 1439 (void) pthread_mutex_unlock( 1440 &sip_trans->sip_xaction_mutex); 1441 return; 1442 case SIP_XACTION_TIMER_H: 1443 SIP_CANCEL_TIMER(sip_trans->sip_xaction_TG); 1444 if (sip_trans->sip_xaction_state == 1445 SIP_SRV_INV_COMPLETED) { 1446 sip_trans->sip_xaction_state = 1447 SIP_SRV_INV_TERMINATED; 1448 (void) pthread_mutex_unlock( 1449 &sip_trans->sip_xaction_mutex); 1450 if (sip_xaction_ulp_state_cb != NULL) { 1451 sip_xaction_ulp_state_cb( 1452 (sip_transaction_t)sip_trans, NULL, 1453 prev_state, sip_trans->sip_xaction_state); 1454 } 1455 if (sip_xaction_ulp_trans_err != NULL) { 1456 sip_xaction_ulp_trans_err(sip_trans, 0, 1457 NULL); 1458 } 1459 sip_xaction_delete(sip_trans); 1460 free(time_obj); 1461 return; 1462 } 1463 break; 1464 case SIP_XACTION_TIMER_I: 1465 if (sip_trans->sip_xaction_state == 1466 SIP_SRV_CONFIRMED) { 1467 SIP_CANCEL_TIMER( 1468 sip_trans->sip_xaction_TH); 1469 sip_trans->sip_xaction_state = 1470 SIP_SRV_INV_TERMINATED; 1471 destroy_trans = B_TRUE; 1472 } 1473 break; 1474 case SIP_XACTION_TIMER_J: 1475 if (sip_trans->sip_xaction_state == 1476 SIP_SRV_NONINV_COMPLETED) { 1477 sip_trans->sip_xaction_state = 1478 SIP_SRV_NONINV_TERMINATED; 1479 destroy_trans = B_TRUE; 1480 1481 } 1482 break; 1483 case SIP_XACTION_TIMER_K: 1484 if (sip_trans->sip_xaction_state == 1485 SIP_CLNT_NONINV_COMPLETED) { 1486 SIP_CANCEL_TIMER( 1487 sip_trans->sip_xaction_TF); 1488 sip_trans->sip_xaction_state = 1489 SIP_CLNT_NONINV_TERMINATED; 1490 destroy_trans = B_TRUE; 1491 } 1492 break; 1493 default: 1494 break; 1495 } 1496 if (destroy_trans) { 1497 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 1498 if (sip_xaction_ulp_state_cb != NULL && 1499 prev_state != sip_trans->sip_xaction_state) { 1500 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, 1501 NULL, prev_state, sip_trans->sip_xaction_state); 1502 } 1503 sip_xaction_delete(sip_trans); 1504 free(time_obj); 1505 return; 1506 } 1507 (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); 1508 if (sip_xaction_ulp_state_cb != NULL && 1509 prev_state != sip_trans->sip_xaction_state) { 1510 sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, NULL, 1511 prev_state, sip_trans->sip_xaction_state); 1512 } 1513 free(time_obj); 1514 } 1515