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