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