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