140cb5e5dSvi117747 /*
240cb5e5dSvi117747 * CDDL HEADER START
340cb5e5dSvi117747 *
440cb5e5dSvi117747 * The contents of this file are subject to the terms of the
540cb5e5dSvi117747 * Common Development and Distribution License (the "License").
640cb5e5dSvi117747 * You may not use this file except in compliance with the License.
740cb5e5dSvi117747 *
840cb5e5dSvi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
940cb5e5dSvi117747 * or http://www.opensolaris.org/os/licensing.
1040cb5e5dSvi117747 * See the License for the specific language governing permissions
1140cb5e5dSvi117747 * and limitations under the License.
1240cb5e5dSvi117747 *
1340cb5e5dSvi117747 * When distributing Covered Code, include this CDDL HEADER in each
1440cb5e5dSvi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1540cb5e5dSvi117747 * If applicable, add the following below this CDDL HEADER, with the
1640cb5e5dSvi117747 * fields enclosed by brackets "[]" replaced with your own identifying
1740cb5e5dSvi117747 * information: Portions Copyright [yyyy] [name of copyright owner]
1840cb5e5dSvi117747 *
1940cb5e5dSvi117747 * CDDL HEADER END
2040cb5e5dSvi117747 */
2140cb5e5dSvi117747
2240cb5e5dSvi117747 /*
23*2c2c4183Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2440cb5e5dSvi117747 * Use is subject to license terms.
2540cb5e5dSvi117747 */
2640cb5e5dSvi117747
2740cb5e5dSvi117747 #pragma ident "%Z%%M% %I% %E% SMI"
2840cb5e5dSvi117747
29*2c2c4183Svi117747 #include <stdlib.h>
30*2c2c4183Svi117747 #include <assert.h>
31*2c2c4183Svi117747 #include <errno.h>
32*2c2c4183Svi117747 #include <strings.h>
33*2c2c4183Svi117747 #include <pthread.h>
34*2c2c4183Svi117747 #include <sip.h>
35*2c2c4183Svi117747
3640cb5e5dSvi117747 #include "sip_msg.h"
3740cb5e5dSvi117747 #include "sip_miscdefs.h"
3840cb5e5dSvi117747 #include "sip_xaction.h"
3940cb5e5dSvi117747
4040cb5e5dSvi117747 /*
4140cb5e5dSvi117747 * Hold transaction
4240cb5e5dSvi117747 */
4340cb5e5dSvi117747 void
sip_hold_trans(sip_transaction_t sip_trans)4440cb5e5dSvi117747 sip_hold_trans(sip_transaction_t sip_trans)
4540cb5e5dSvi117747 {
4640cb5e5dSvi117747 sip_xaction_t *_trans;
4740cb5e5dSvi117747
4840cb5e5dSvi117747 if (sip_trans == NULL)
4940cb5e5dSvi117747 return;
5040cb5e5dSvi117747 _trans = (sip_xaction_t *)sip_trans;
5140cb5e5dSvi117747 (void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex));
5240cb5e5dSvi117747 SIP_XACTION_REFCNT_INCR(_trans);
5340cb5e5dSvi117747 (void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex));
5440cb5e5dSvi117747 }
5540cb5e5dSvi117747
5640cb5e5dSvi117747 /*
5740cb5e5dSvi117747 * Release transaction
5840cb5e5dSvi117747 */
5940cb5e5dSvi117747 void
sip_release_trans(sip_transaction_t sip_trans)6040cb5e5dSvi117747 sip_release_trans(sip_transaction_t sip_trans)
6140cb5e5dSvi117747 {
6240cb5e5dSvi117747 sip_xaction_t *_trans;
6340cb5e5dSvi117747
6440cb5e5dSvi117747 if (sip_trans == NULL)
6540cb5e5dSvi117747 return;
6640cb5e5dSvi117747 _trans = (sip_xaction_t *)sip_trans;
6740cb5e5dSvi117747 SIP_XACTION_REFCNT_DECR(_trans);
6840cb5e5dSvi117747 }
6940cb5e5dSvi117747
7040cb5e5dSvi117747 /*
7140cb5e5dSvi117747 * Given a message get the client/server transaction. The caller is
7240cb5e5dSvi117747 * responsible for doing a sip_release_trans().
7340cb5e5dSvi117747 */
7440cb5e5dSvi117747 const struct sip_xaction *
sip_get_trans(sip_msg_t sip_msg,int which,int * error)7540cb5e5dSvi117747 sip_get_trans(sip_msg_t sip_msg, int which, int *error)
7640cb5e5dSvi117747 {
7740cb5e5dSvi117747 if (error != NULL)
7840cb5e5dSvi117747 *error = 0;
7940cb5e5dSvi117747 if (sip_msg == NULL) {
8040cb5e5dSvi117747 if (error != NULL)
8140cb5e5dSvi117747 *error = EINVAL;
8240cb5e5dSvi117747 return (NULL);
8340cb5e5dSvi117747 }
8440cb5e5dSvi117747 return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE,
8540cb5e5dSvi117747 which, NULL));
8640cb5e5dSvi117747 }
8740cb5e5dSvi117747
8840cb5e5dSvi117747 /*
8940cb5e5dSvi117747 * Get the last response sent for this transaction
9040cb5e5dSvi117747 */
9140cb5e5dSvi117747 const struct sip_message *
sip_get_trans_resp_msg(sip_transaction_t sip_trans,int * error)9240cb5e5dSvi117747 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error)
9340cb5e5dSvi117747 {
9440cb5e5dSvi117747 sip_xaction_t *_trans;
9540cb5e5dSvi117747
9640cb5e5dSvi117747 if (error != NULL)
9740cb5e5dSvi117747 *error = 0;
9840cb5e5dSvi117747 if (sip_trans == NULL) {
9940cb5e5dSvi117747 if (error != NULL)
10040cb5e5dSvi117747 *error = EINVAL;
10140cb5e5dSvi117747 return (NULL);
10240cb5e5dSvi117747 }
10340cb5e5dSvi117747 _trans = (sip_xaction_t *)sip_trans;
10440cb5e5dSvi117747 if ((_trans->sip_xaction_last_msg != NULL) &&
10540cb5e5dSvi117747 !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg,
10640cb5e5dSvi117747 error)) {
10740cb5e5dSvi117747 return (_trans->sip_xaction_last_msg);
10840cb5e5dSvi117747 } else if (!sip_msg_is_request((sip_msg_t)
10940cb5e5dSvi117747 _trans->sip_xaction_orig_msg, error)) {
11040cb5e5dSvi117747 return (_trans->sip_xaction_orig_msg);
11140cb5e5dSvi117747 }
11240cb5e5dSvi117747 return (NULL);
11340cb5e5dSvi117747 }
11440cb5e5dSvi117747
11540cb5e5dSvi117747 /*
11640cb5e5dSvi117747 * Get the SIP message that created this transaction
11740cb5e5dSvi117747 */
11840cb5e5dSvi117747 const struct sip_message *
sip_get_trans_orig_msg(sip_transaction_t sip_trans,int * error)11940cb5e5dSvi117747 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error)
12040cb5e5dSvi117747 {
12140cb5e5dSvi117747 if (error != NULL)
12240cb5e5dSvi117747 *error = 0;
12340cb5e5dSvi117747 if (sip_trans == NULL) {
12440cb5e5dSvi117747 if (error != NULL)
12540cb5e5dSvi117747 *error = EINVAL;
12640cb5e5dSvi117747 return (NULL);
12740cb5e5dSvi117747 }
12840cb5e5dSvi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg);
12940cb5e5dSvi117747 }
13040cb5e5dSvi117747
13140cb5e5dSvi117747 /*
13240cb5e5dSvi117747 * Get the connection object that was used to send the last message for this
13340cb5e5dSvi117747 * transaction.
13440cb5e5dSvi117747 */
13540cb5e5dSvi117747 const struct sip_conn_object *
sip_get_trans_conn_obj(sip_transaction_t sip_trans,int * error)13640cb5e5dSvi117747 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error)
13740cb5e5dSvi117747 {
13840cb5e5dSvi117747 if (error != NULL)
13940cb5e5dSvi117747 *error = 0;
14040cb5e5dSvi117747 if (sip_trans == NULL) {
14140cb5e5dSvi117747 if (error != NULL)
14240cb5e5dSvi117747 *error = EINVAL;
14340cb5e5dSvi117747 return (NULL);
14440cb5e5dSvi117747 }
14540cb5e5dSvi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj);
14640cb5e5dSvi117747 }
14740cb5e5dSvi117747
14840cb5e5dSvi117747 /*
14940cb5e5dSvi117747 * Get the transaction method
15040cb5e5dSvi117747 */
15140cb5e5dSvi117747 sip_method_t
sip_get_trans_method(sip_transaction_t sip_trans,int * error)15240cb5e5dSvi117747 sip_get_trans_method(sip_transaction_t sip_trans, int *error)
15340cb5e5dSvi117747 {
15440cb5e5dSvi117747 if (error != NULL)
15540cb5e5dSvi117747 *error = 0;
15640cb5e5dSvi117747
15740cb5e5dSvi117747 if (sip_trans == NULL) {
15840cb5e5dSvi117747 if (error != NULL)
15940cb5e5dSvi117747 *error = EINVAL;
16040cb5e5dSvi117747 return (-1);
16140cb5e5dSvi117747 }
16240cb5e5dSvi117747 return (((sip_xaction_t *)sip_trans)->sip_xaction_method);
16340cb5e5dSvi117747 }
16440cb5e5dSvi117747
16540cb5e5dSvi117747 /*
16640cb5e5dSvi117747 * Get the transaction id. Caller frees string
16740cb5e5dSvi117747 */
16840cb5e5dSvi117747 char *
sip_get_trans_branchid(sip_transaction_t trans,int * error)16940cb5e5dSvi117747 sip_get_trans_branchid(sip_transaction_t trans, int *error)
17040cb5e5dSvi117747 {
17140cb5e5dSvi117747 sip_xaction_t *xaction = (sip_xaction_t *)trans;
17240cb5e5dSvi117747 char *bid;
17340cb5e5dSvi117747
17440cb5e5dSvi117747 if (error != NULL)
17540cb5e5dSvi117747 *error = 0;
17640cb5e5dSvi117747 if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) {
17740cb5e5dSvi117747 if (error != NULL)
17840cb5e5dSvi117747 *error = EINVAL;
17940cb5e5dSvi117747 return (NULL);
18040cb5e5dSvi117747 }
18140cb5e5dSvi117747 bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1);
18240cb5e5dSvi117747 if (bid == NULL) {
18340cb5e5dSvi117747 if (error != NULL)
18440cb5e5dSvi117747 *error = ENOMEM;
18540cb5e5dSvi117747 return (NULL);
18640cb5e5dSvi117747 }
18740cb5e5dSvi117747 (void) strncpy(bid, xaction->sip_xaction_branch_id,
18840cb5e5dSvi117747 strlen(xaction->sip_xaction_branch_id));
18940cb5e5dSvi117747 bid[strlen(xaction->sip_xaction_branch_id)] = '\0';
19040cb5e5dSvi117747 return (bid);
19140cb5e5dSvi117747 }
19240cb5e5dSvi117747
19340cb5e5dSvi117747 /*
19440cb5e5dSvi117747 * Get the transaction state
19540cb5e5dSvi117747 */
19640cb5e5dSvi117747 int
sip_get_trans_state(sip_transaction_t trans,int * error)19740cb5e5dSvi117747 sip_get_trans_state(sip_transaction_t trans, int *error)
19840cb5e5dSvi117747 {
19940cb5e5dSvi117747 sip_xaction_t *xaction = (sip_xaction_t *)trans;
20040cb5e5dSvi117747
20140cb5e5dSvi117747 if (error != NULL)
20240cb5e5dSvi117747 *error = 0;
20340cb5e5dSvi117747 if (xaction == NULL) {
20440cb5e5dSvi117747 if (error != NULL)
20540cb5e5dSvi117747 *error = EINVAL;
20640cb5e5dSvi117747 return (NULL);
20740cb5e5dSvi117747 }
20840cb5e5dSvi117747 return (xaction->sip_xaction_state);
20940cb5e5dSvi117747 }
210