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 *
sip_setup_timer(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * sip_msg,sip_timer_t timer,int type)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
sip_xaction_output(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg)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
sip_clnt_xaction_output(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg)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
sip_srv_xaction_output(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg)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
sip_srv_xaction_inv_res(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg)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
sip_srv_xaction_noninv_res(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg)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
sip_xaction_input(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t ** sip_msg)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
sip_srv_xaction_input(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t ** sip_msg)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
sip_clnt_xaction_input(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t ** msg)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
sip_create_send_nonOKack(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t * msg,boolean_t copy)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
sip_clnt_xaction_inv_res(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t ** sip_msg)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
sip_clnt_xaction_noninv_res(sip_conn_object_t conn_obj,sip_xaction_t * sip_trans,_sip_msg_t ** sip_msg)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
sip_xaction_terminate(sip_xaction_t * sip_trans,_sip_msg_t * msg,int transport)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
sip_xaction_state_timer_fire(void * args)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