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