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 #include "sip_hash.h" 30 #include "sip_parse_uri.h" 31 #include "sip_msg.h" 32 #include "sip_miscdefs.h" 33 #include "sip_xaction.h" 34 35 /* 36 * Hold transaction 37 */ 38 void 39 sip_hold_trans(sip_transaction_t sip_trans) 40 { 41 sip_xaction_t *_trans; 42 43 if (sip_trans == NULL) 44 return; 45 _trans = (sip_xaction_t *)sip_trans; 46 (void) pthread_mutex_lock(&((_trans)->sip_xaction_mutex)); 47 SIP_XACTION_REFCNT_INCR(_trans); 48 (void) pthread_mutex_unlock(&((_trans)->sip_xaction_mutex)); 49 } 50 51 /* 52 * Release transaction 53 */ 54 void 55 sip_release_trans(sip_transaction_t sip_trans) 56 { 57 sip_xaction_t *_trans; 58 59 if (sip_trans == NULL) 60 return; 61 _trans = (sip_xaction_t *)sip_trans; 62 SIP_XACTION_REFCNT_DECR(_trans); 63 } 64 65 /* 66 * Given a message get the client/server transaction. The caller is 67 * responsible for doing a sip_release_trans(). 68 */ 69 const struct sip_xaction * 70 sip_get_trans(sip_msg_t sip_msg, int which, int *error) 71 { 72 if (error != NULL) 73 *error = 0; 74 if (sip_msg == NULL) { 75 if (error != NULL) 76 *error = EINVAL; 77 return (NULL); 78 } 79 return ((sip_transaction_t)sip_xaction_get(NULL, sip_msg, B_FALSE, 80 which, NULL)); 81 } 82 83 /* 84 * Get the last response sent for this transaction 85 */ 86 const struct sip_message * 87 sip_get_trans_resp_msg(sip_transaction_t sip_trans, int *error) 88 { 89 sip_xaction_t *_trans; 90 91 if (error != NULL) 92 *error = 0; 93 if (sip_trans == NULL) { 94 if (error != NULL) 95 *error = EINVAL; 96 return (NULL); 97 } 98 _trans = (sip_xaction_t *)sip_trans; 99 if ((_trans->sip_xaction_last_msg != NULL) && 100 !sip_msg_is_request((sip_msg_t)_trans->sip_xaction_last_msg, 101 error)) { 102 return (_trans->sip_xaction_last_msg); 103 } else if (!sip_msg_is_request((sip_msg_t) 104 _trans->sip_xaction_orig_msg, error)) { 105 return (_trans->sip_xaction_orig_msg); 106 } 107 return (NULL); 108 } 109 110 /* 111 * Get the SIP message that created this transaction 112 */ 113 const struct sip_message * 114 sip_get_trans_orig_msg(sip_transaction_t sip_trans, int *error) 115 { 116 if (error != NULL) 117 *error = 0; 118 if (sip_trans == NULL) { 119 if (error != NULL) 120 *error = EINVAL; 121 return (NULL); 122 } 123 return (((sip_xaction_t *)sip_trans)->sip_xaction_orig_msg); 124 } 125 126 /* 127 * Get the connection object that was used to send the last message for this 128 * transaction. 129 */ 130 const struct sip_conn_object * 131 sip_get_trans_conn_obj(sip_transaction_t sip_trans, int *error) 132 { 133 if (error != NULL) 134 *error = 0; 135 if (sip_trans == NULL) { 136 if (error != NULL) 137 *error = EINVAL; 138 return (NULL); 139 } 140 return (((sip_xaction_t *)sip_trans)->sip_xaction_conn_obj); 141 } 142 143 /* 144 * Get the transaction method 145 */ 146 sip_method_t 147 sip_get_trans_method(sip_transaction_t sip_trans, int *error) 148 { 149 if (error != NULL) 150 *error = 0; 151 152 if (sip_trans == NULL) { 153 if (error != NULL) 154 *error = EINVAL; 155 return (-1); 156 } 157 return (((sip_xaction_t *)sip_trans)->sip_xaction_method); 158 } 159 160 /* 161 * Get the transaction id. Caller frees string 162 */ 163 char * 164 sip_get_trans_branchid(sip_transaction_t trans, int *error) 165 { 166 sip_xaction_t *xaction = (sip_xaction_t *)trans; 167 char *bid; 168 169 if (error != NULL) 170 *error = 0; 171 if (xaction == NULL || xaction->sip_xaction_branch_id == NULL) { 172 if (error != NULL) 173 *error = EINVAL; 174 return (NULL); 175 } 176 bid = malloc(strlen(xaction->sip_xaction_branch_id) + 1); 177 if (bid == NULL) { 178 if (error != NULL) 179 *error = ENOMEM; 180 return (NULL); 181 } 182 (void) strncpy(bid, xaction->sip_xaction_branch_id, 183 strlen(xaction->sip_xaction_branch_id)); 184 bid[strlen(xaction->sip_xaction_branch_id)] = '\0'; 185 return (bid); 186 } 187 188 /* 189 * Get the transaction state 190 */ 191 int 192 sip_get_trans_state(sip_transaction_t trans, int *error) 193 { 194 sip_xaction_t *xaction = (sip_xaction_t *)trans; 195 196 if (error != NULL) 197 *error = 0; 198 if (xaction == NULL) { 199 if (error != NULL) 200 *error = EINVAL; 201 return (NULL); 202 } 203 return (xaction->sip_xaction_state); 204 } 205