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