1*2882Svi117747 /* 2*2882Svi117747 * CDDL HEADER START 3*2882Svi117747 * 4*2882Svi117747 * The contents of this file are subject to the terms of the 5*2882Svi117747 * Common Development and Distribution License (the "License"). 6*2882Svi117747 * You may not use this file except in compliance with the License. 7*2882Svi117747 * 8*2882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2882Svi117747 * or http://www.opensolaris.org/os/licensing. 10*2882Svi117747 * See the License for the specific language governing permissions 11*2882Svi117747 * and limitations under the License. 12*2882Svi117747 * 13*2882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each 14*2882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2882Svi117747 * If applicable, add the following below this CDDL HEADER, with the 16*2882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying 17*2882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 18*2882Svi117747 * 19*2882Svi117747 * CDDL HEADER END 20*2882Svi117747 */ 21*2882Svi117747 22*2882Svi117747 /* 23*2882Svi117747 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2882Svi117747 * Use is subject to license terms. 25*2882Svi117747 */ 26*2882Svi117747 27*2882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI" 28*2882Svi117747 29*2882Svi117747 #include "sip_parse_uri.h" 30*2882Svi117747 #include "sip_msg.h" 31*2882Svi117747 #include "sip_miscdefs.h" 32*2882Svi117747 #include "sip_xaction.h" 33*2882Svi117747 34*2882Svi117747 #define SIP_BUF_SIZE 128 35*2882Svi117747 36*2882Svi117747 /* 37*2882Svi117747 * Find the header named header, consecutive calls with old_header 38*2882Svi117747 * passed in will return next header of the same type. 39*2882Svi117747 * If no name is passed the first header is returned. consectutive calls 40*2882Svi117747 * with no name but an old header will return the next header. 41*2882Svi117747 */ 42*2882Svi117747 const struct sip_header * 43*2882Svi117747 sip_get_header(sip_msg_t sip_msg, char *header_name, sip_header_t old_header, 44*2882Svi117747 int *error) 45*2882Svi117747 { 46*2882Svi117747 _sip_msg_t *_sip_msg; 47*2882Svi117747 const struct sip_header *sip_hdr; 48*2882Svi117747 49*2882Svi117747 if (error != NULL) 50*2882Svi117747 *error = 0; 51*2882Svi117747 if (sip_msg == NULL) { 52*2882Svi117747 if (error != NULL) 53*2882Svi117747 *error = EINVAL; 54*2882Svi117747 return (NULL); 55*2882Svi117747 } 56*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 57*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 58*2882Svi117747 sip_hdr = (sip_header_t)sip_search_for_header((_sip_msg_t *)sip_msg, 59*2882Svi117747 header_name, (_sip_header_t *)old_header); 60*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 61*2882Svi117747 if (sip_hdr == NULL && error != NULL) 62*2882Svi117747 *error = EINVAL; 63*2882Svi117747 return (sip_hdr); 64*2882Svi117747 } 65*2882Svi117747 66*2882Svi117747 /* 67*2882Svi117747 * Return the request line as a string. Caller releases the returned string. 68*2882Svi117747 */ 69*2882Svi117747 char * 70*2882Svi117747 sip_reqline_to_str(sip_msg_t sip_msg, int *error) 71*2882Svi117747 { 72*2882Svi117747 char *reqstr; 73*2882Svi117747 74*2882Svi117747 if (error != NULL) 75*2882Svi117747 *error = 0; 76*2882Svi117747 if (sip_msg == NULL || !sip_msg_is_request(sip_msg, error)) { 77*2882Svi117747 if (error != NULL) 78*2882Svi117747 *error = EINVAL; 79*2882Svi117747 return (NULL); 80*2882Svi117747 } 81*2882Svi117747 reqstr = _sip_startline_to_str((_sip_msg_t *)sip_msg, error); 82*2882Svi117747 return (reqstr); 83*2882Svi117747 } 84*2882Svi117747 85*2882Svi117747 /* 86*2882Svi117747 * Return the response line as a string. Caller releases the returned string. 87*2882Svi117747 */ 88*2882Svi117747 char * 89*2882Svi117747 sip_respline_to_str(sip_msg_t sip_msg, int *error) 90*2882Svi117747 { 91*2882Svi117747 char *respstr; 92*2882Svi117747 93*2882Svi117747 if (error != NULL) 94*2882Svi117747 *error = 0; 95*2882Svi117747 if (sip_msg == NULL || sip_msg_is_request(sip_msg, error)) { 96*2882Svi117747 if (error != NULL) 97*2882Svi117747 *error = EINVAL; 98*2882Svi117747 return (NULL); 99*2882Svi117747 } 100*2882Svi117747 respstr = _sip_startline_to_str((_sip_msg_t *)sip_msg, error); 101*2882Svi117747 return (respstr); 102*2882Svi117747 } 103*2882Svi117747 104*2882Svi117747 /* 105*2882Svi117747 * return the first value of the header 106*2882Svi117747 */ 107*2882Svi117747 const struct sip_value * 108*2882Svi117747 sip_get_header_value(const struct sip_header *sip_header, int *error) 109*2882Svi117747 { 110*2882Svi117747 _sip_header_t *_sip_header; 111*2882Svi117747 sip_parsed_header_t *sip_parsed_header; 112*2882Svi117747 int ret = 0; 113*2882Svi117747 const struct sip_value *value; 114*2882Svi117747 115*2882Svi117747 if (error != NULL) 116*2882Svi117747 *error = 0; 117*2882Svi117747 if (sip_header == NULL) { 118*2882Svi117747 if (error != NULL) 119*2882Svi117747 *error = EINVAL; 120*2882Svi117747 return (NULL); 121*2882Svi117747 } 122*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 123*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 124*2882Svi117747 (void) pthread_mutex_lock( 125*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 126*2882Svi117747 } 127*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 128*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 129*2882Svi117747 (void) pthread_mutex_unlock( 130*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 131*2882Svi117747 } 132*2882Svi117747 if (error != NULL) 133*2882Svi117747 *error = EINVAL; 134*2882Svi117747 return (NULL); 135*2882Svi117747 } 136*2882Svi117747 ret = _sip_header->sip_header_functions->header_parse_func( 137*2882Svi117747 _sip_header, &sip_parsed_header); 138*2882Svi117747 if (_sip_header->sip_hdr_sipmsg != NULL) { 139*2882Svi117747 (void) pthread_mutex_unlock 140*2882Svi117747 (&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 141*2882Svi117747 } 142*2882Svi117747 if (error != NULL) 143*2882Svi117747 *error = ret; 144*2882Svi117747 145*2882Svi117747 if (ret != 0) 146*2882Svi117747 return (NULL); 147*2882Svi117747 value = (sip_header_value_t)sip_parsed_header->value; 148*2882Svi117747 while (value != NULL && value->value_state == SIP_VALUE_DELETED) 149*2882Svi117747 value = value->next; 150*2882Svi117747 if (value != NULL && value->value_state == SIP_VALUE_BAD && 151*2882Svi117747 error != NULL) { 152*2882Svi117747 *error = EPROTO; 153*2882Svi117747 } 154*2882Svi117747 return ((sip_header_value_t)value); 155*2882Svi117747 } 156*2882Svi117747 157*2882Svi117747 /* 158*2882Svi117747 * Return the next value of the header. 159*2882Svi117747 */ 160*2882Svi117747 const struct sip_value * 161*2882Svi117747 sip_get_next_value(sip_header_value_t old_value, int *error) 162*2882Svi117747 { 163*2882Svi117747 const struct sip_value *value; 164*2882Svi117747 165*2882Svi117747 if (error != NULL) 166*2882Svi117747 *error = 0; 167*2882Svi117747 if (old_value == NULL || old_value->next == NULL) { 168*2882Svi117747 if (error != NULL) 169*2882Svi117747 *error = EINVAL; 170*2882Svi117747 return (NULL); 171*2882Svi117747 } 172*2882Svi117747 /* 173*2882Svi117747 * We never free the deleted values so no need to hold a lock. 174*2882Svi117747 */ 175*2882Svi117747 value = (sip_header_value_t)old_value->next; 176*2882Svi117747 while (value != NULL && value->value_state == SIP_VALUE_DELETED) 177*2882Svi117747 value = value->next; 178*2882Svi117747 if (value != NULL && value->value_state == SIP_VALUE_BAD && 179*2882Svi117747 error != NULL) { 180*2882Svi117747 *error = EPROTO; 181*2882Svi117747 } 182*2882Svi117747 return ((sip_header_value_t)value); 183*2882Svi117747 } 184*2882Svi117747 185*2882Svi117747 /* 186*2882Svi117747 * Given a SIP message, delete the header "header_name". 187*2882Svi117747 */ 188*2882Svi117747 int 189*2882Svi117747 sip_delete_header_by_name(sip_msg_t msg, char *header_name) 190*2882Svi117747 { 191*2882Svi117747 _sip_msg_t *_msg = (_sip_msg_t *)msg; 192*2882Svi117747 sip_header_t sip_hdr; 193*2882Svi117747 _sip_header_t *_sip_hdr; 194*2882Svi117747 195*2882Svi117747 if (_msg == NULL || header_name == NULL) 196*2882Svi117747 return (EINVAL); 197*2882Svi117747 (void) pthread_mutex_lock(&_msg->sip_msg_mutex); 198*2882Svi117747 if (_msg->sip_msg_cannot_be_modified) { 199*2882Svi117747 (void) pthread_mutex_unlock(&_msg->sip_msg_mutex); 200*2882Svi117747 return (EPERM); 201*2882Svi117747 } 202*2882Svi117747 sip_hdr = (sip_header_t)sip_search_for_header(_msg, header_name, NULL); 203*2882Svi117747 if (sip_hdr == NULL) { 204*2882Svi117747 (void) pthread_mutex_unlock(&_msg->sip_msg_mutex); 205*2882Svi117747 return (EINVAL); 206*2882Svi117747 } 207*2882Svi117747 _sip_hdr = (_sip_header_t *)sip_hdr; 208*2882Svi117747 _sip_hdr->sip_header_state = SIP_HEADER_DELETED; 209*2882Svi117747 _sip_hdr->sip_hdr_sipmsg->sip_msg_len -= _sip_hdr->sip_hdr_end - 210*2882Svi117747 _sip_hdr->sip_hdr_start; 211*2882Svi117747 assert(_sip_hdr->sip_hdr_sipmsg->sip_msg_len >= 0); 212*2882Svi117747 if (_msg->sip_msg_buf != NULL) 213*2882Svi117747 _msg->sip_msg_modified = B_TRUE; 214*2882Svi117747 (void) pthread_mutex_unlock(&_msg->sip_msg_mutex); 215*2882Svi117747 216*2882Svi117747 return (0); 217*2882Svi117747 } 218*2882Svi117747 219*2882Svi117747 /* 220*2882Svi117747 * Mark the header as deleted. 221*2882Svi117747 */ 222*2882Svi117747 int 223*2882Svi117747 sip_delete_header(sip_header_t sip_header) 224*2882Svi117747 { 225*2882Svi117747 _sip_header_t *_sip_header; 226*2882Svi117747 227*2882Svi117747 if (sip_header == NULL) 228*2882Svi117747 return (EINVAL); 229*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 230*2882Svi117747 (void) pthread_mutex_lock(&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 231*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_cannot_be_modified) { 232*2882Svi117747 (void) pthread_mutex_unlock 233*2882Svi117747 (&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 234*2882Svi117747 return (EPERM); 235*2882Svi117747 } 236*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 237*2882Svi117747 (void) pthread_mutex_unlock( 238*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 239*2882Svi117747 return (EINVAL); 240*2882Svi117747 } 241*2882Svi117747 _sip_header->sip_header_state = SIP_HEADER_DELETED; 242*2882Svi117747 _sip_header->sip_hdr_sipmsg->sip_msg_len -= _sip_header->sip_hdr_end - 243*2882Svi117747 _sip_header->sip_hdr_start; 244*2882Svi117747 assert(_sip_header->sip_hdr_sipmsg->sip_msg_len >= 0); 245*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_buf != NULL) 246*2882Svi117747 _sip_header->sip_hdr_sipmsg->sip_msg_modified = B_TRUE; 247*2882Svi117747 (void) pthread_mutex_unlock 248*2882Svi117747 (&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 249*2882Svi117747 return (0); 250*2882Svi117747 } 251*2882Svi117747 252*2882Svi117747 /* 253*2882Svi117747 * Mark the value as deleted. 254*2882Svi117747 */ 255*2882Svi117747 int 256*2882Svi117747 sip_delete_value(sip_header_t sip_header, sip_header_value_t sip_header_value) 257*2882Svi117747 { 258*2882Svi117747 _sip_header_t *_sip_header; 259*2882Svi117747 sip_value_t *_sip_header_value; 260*2882Svi117747 int vlen; 261*2882Svi117747 char *c; 262*2882Svi117747 263*2882Svi117747 if (sip_header == NULL || sip_header_value == NULL) 264*2882Svi117747 return (EINVAL); 265*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 266*2882Svi117747 (void) pthread_mutex_lock(&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 267*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_cannot_be_modified) { 268*2882Svi117747 (void) pthread_mutex_unlock(&_sip_header-> 269*2882Svi117747 sip_hdr_sipmsg->sip_msg_mutex); 270*2882Svi117747 return (EPERM); 271*2882Svi117747 } 272*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 273*2882Svi117747 (void) pthread_mutex_unlock( 274*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 275*2882Svi117747 return (EINVAL); 276*2882Svi117747 } 277*2882Svi117747 _sip_header_value = (sip_value_t *)sip_header_value; 278*2882Svi117747 if (_sip_header_value->value_state == SIP_VALUE_DELETED) { 279*2882Svi117747 (void) pthread_mutex_unlock( 280*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 281*2882Svi117747 return (EINVAL); 282*2882Svi117747 } 283*2882Svi117747 _sip_header->sip_header_state = SIP_HEADER_DELETED_VAL; 284*2882Svi117747 _sip_header_value->value_state = SIP_VALUE_DELETED; 285*2882Svi117747 vlen = _sip_header_value->value_end - _sip_header_value->value_start; 286*2882Svi117747 if (_sip_header->sip_hdr_parsed->value == _sip_header_value) { 287*2882Svi117747 c = _sip_header_value->value_start; 288*2882Svi117747 while (*c-- != SIP_HCOLON) 289*2882Svi117747 vlen++; 290*2882Svi117747 } else { 291*2882Svi117747 c = _sip_header_value->value_start; 292*2882Svi117747 while (*c-- != SIP_COMMA) 293*2882Svi117747 vlen++; 294*2882Svi117747 } 295*2882Svi117747 if (_sip_header_value->next == NULL) { 296*2882Svi117747 sip_value_t *value = _sip_header->sip_hdr_parsed->value; 297*2882Svi117747 boolean_t crlf_present = B_FALSE; 298*2882Svi117747 char *s; 299*2882Svi117747 300*2882Svi117747 while (value != NULL && value != _sip_header_value) { 301*2882Svi117747 crlf_present = B_FALSE; 302*2882Svi117747 303*2882Svi117747 if (value->value_state == SIP_VALUE_DELETED) { 304*2882Svi117747 value = value->next; 305*2882Svi117747 continue; 306*2882Svi117747 } 307*2882Svi117747 s = value->value_end; 308*2882Svi117747 while (s != value->value_start) { 309*2882Svi117747 if (*s == '\r' && strncmp(s, SIP_CRLF, 310*2882Svi117747 strlen(SIP_CRLF)) == 0) { 311*2882Svi117747 crlf_present = B_TRUE; 312*2882Svi117747 break; 313*2882Svi117747 } 314*2882Svi117747 s--; 315*2882Svi117747 } 316*2882Svi117747 value = value->next; 317*2882Svi117747 } 318*2882Svi117747 if (!crlf_present) { 319*2882Svi117747 c = _sip_header_value->value_end; 320*2882Svi117747 while (*c-- != '\r') 321*2882Svi117747 vlen--; 322*2882Svi117747 assert(vlen > 0); 323*2882Svi117747 } 324*2882Svi117747 } 325*2882Svi117747 _sip_header->sip_hdr_sipmsg->sip_msg_len -= vlen; 326*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_buf != NULL) 327*2882Svi117747 _sip_header->sip_hdr_sipmsg->sip_msg_modified = B_TRUE; 328*2882Svi117747 (void) pthread_mutex_unlock 329*2882Svi117747 (&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 330*2882Svi117747 return (0); 331*2882Svi117747 } 332*2882Svi117747 333*2882Svi117747 /* 334*2882Svi117747 * Given a param list, check if a param name exists. 335*2882Svi117747 */ 336*2882Svi117747 boolean_t 337*2882Svi117747 sip_is_param_present(const sip_param_t *param_list, char *param_name, 338*2882Svi117747 int param_len) 339*2882Svi117747 { 340*2882Svi117747 const sip_param_t *param = param_list; 341*2882Svi117747 342*2882Svi117747 while (param != NULL) { 343*2882Svi117747 if (param->param_name.sip_str_len == param_len && 344*2882Svi117747 strncasecmp(param->param_name.sip_str_ptr, param_name, 345*2882Svi117747 param_len) == 0) { 346*2882Svi117747 return (B_TRUE); 347*2882Svi117747 } 348*2882Svi117747 param = param->param_next; 349*2882Svi117747 } 350*2882Svi117747 return (B_FALSE); 351*2882Svi117747 } 352*2882Svi117747 353*2882Svi117747 354*2882Svi117747 /* 355*2882Svi117747 * Given a value header return the value of the named param. 356*2882Svi117747 */ 357*2882Svi117747 const sip_str_t * 358*2882Svi117747 sip_get_param_value(sip_header_value_t header_value, char *param_name, 359*2882Svi117747 int *error) 360*2882Svi117747 { 361*2882Svi117747 sip_value_t *_sip_header_value; 362*2882Svi117747 sip_param_t *sip_param; 363*2882Svi117747 364*2882Svi117747 if (error != NULL) 365*2882Svi117747 *error = 0; 366*2882Svi117747 if (header_value == NULL || param_name == NULL) { 367*2882Svi117747 if (error != NULL) 368*2882Svi117747 *error = EINVAL; 369*2882Svi117747 return (NULL); 370*2882Svi117747 } 371*2882Svi117747 _sip_header_value = (sip_value_t *)header_value; 372*2882Svi117747 if (_sip_header_value->value_state == SIP_VALUE_DELETED) { 373*2882Svi117747 if (error != NULL) 374*2882Svi117747 *error = EINVAL; 375*2882Svi117747 return (NULL); 376*2882Svi117747 } 377*2882Svi117747 if (_sip_header_value->param_list == NULL) { 378*2882Svi117747 if (error != NULL) 379*2882Svi117747 *error = EINVAL; 380*2882Svi117747 return (NULL); 381*2882Svi117747 } 382*2882Svi117747 sip_param = sip_get_param_from_list(_sip_header_value->param_list, 383*2882Svi117747 param_name); 384*2882Svi117747 if (sip_param != NULL) 385*2882Svi117747 return (&sip_param->param_value); 386*2882Svi117747 return (NULL); 387*2882Svi117747 } 388*2882Svi117747 389*2882Svi117747 /* 390*2882Svi117747 * Return the list of params in the header 391*2882Svi117747 */ 392*2882Svi117747 const sip_param_t * 393*2882Svi117747 sip_get_params(sip_header_value_t header_value, int *error) 394*2882Svi117747 { 395*2882Svi117747 sip_value_t *sip_header_value; 396*2882Svi117747 397*2882Svi117747 if (error != NULL) 398*2882Svi117747 *error = 0; 399*2882Svi117747 if (header_value == NULL) { 400*2882Svi117747 if (error != NULL) 401*2882Svi117747 *error = EINVAL; 402*2882Svi117747 return (NULL); 403*2882Svi117747 } 404*2882Svi117747 sip_header_value = (sip_value_t *)header_value; 405*2882Svi117747 if (sip_header_value->value_state == SIP_VALUE_DELETED) { 406*2882Svi117747 if (error != NULL) 407*2882Svi117747 *error = EINVAL; 408*2882Svi117747 return (NULL); 409*2882Svi117747 } 410*2882Svi117747 return (sip_header_value->param_list); 411*2882Svi117747 } 412*2882Svi117747 413*2882Svi117747 /* 414*2882Svi117747 * Return true if this is a SIP request 415*2882Svi117747 */ 416*2882Svi117747 boolean_t 417*2882Svi117747 sip_msg_is_request(sip_msg_t sip_msg, int *error) 418*2882Svi117747 { 419*2882Svi117747 _sip_msg_t *_sip_msg; 420*2882Svi117747 sip_message_type_t *sip_msg_info; 421*2882Svi117747 boolean_t ret; 422*2882Svi117747 423*2882Svi117747 if (error != NULL) 424*2882Svi117747 *error = 0; 425*2882Svi117747 if (sip_msg == NULL) { 426*2882Svi117747 if (error != NULL) 427*2882Svi117747 *error = EINVAL; 428*2882Svi117747 return (B_FALSE); 429*2882Svi117747 } 430*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 431*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 432*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 433*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 434*2882Svi117747 if (error != NULL) 435*2882Svi117747 *error = EINVAL; 436*2882Svi117747 return (B_FALSE); 437*2882Svi117747 } 438*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 439*2882Svi117747 ret = sip_msg_info->is_request; 440*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 441*2882Svi117747 return (ret); 442*2882Svi117747 } 443*2882Svi117747 444*2882Svi117747 /* 445*2882Svi117747 * Return true if this is a SIP response 446*2882Svi117747 */ 447*2882Svi117747 boolean_t 448*2882Svi117747 sip_msg_is_response(sip_msg_t sip_msg, int *error) 449*2882Svi117747 { 450*2882Svi117747 boolean_t is_resp; 451*2882Svi117747 _sip_msg_t *_sip_msg; 452*2882Svi117747 sip_message_type_t *sip_msg_info; 453*2882Svi117747 454*2882Svi117747 if (error != NULL) 455*2882Svi117747 *error = 0; 456*2882Svi117747 if (sip_msg == NULL) { 457*2882Svi117747 if (error != NULL) 458*2882Svi117747 *error = EINVAL; 459*2882Svi117747 return (B_FALSE); 460*2882Svi117747 } 461*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 462*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 463*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 464*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 465*2882Svi117747 if (error != NULL) 466*2882Svi117747 *error = EINVAL; 467*2882Svi117747 return (B_FALSE); 468*2882Svi117747 } 469*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 470*2882Svi117747 is_resp = !sip_msg_info->is_request; 471*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 472*2882Svi117747 return (is_resp); 473*2882Svi117747 } 474*2882Svi117747 475*2882Svi117747 /* 476*2882Svi117747 * Return the method in the request line 477*2882Svi117747 */ 478*2882Svi117747 sip_method_t 479*2882Svi117747 sip_get_request_method(sip_msg_t sip_msg, int *error) 480*2882Svi117747 { 481*2882Svi117747 _sip_msg_t *_sip_msg; 482*2882Svi117747 sip_message_type_t *sip_msg_info; 483*2882Svi117747 sip_method_t ret = -1; 484*2882Svi117747 485*2882Svi117747 if (error != NULL) 486*2882Svi117747 *error = 0; 487*2882Svi117747 if (sip_msg == NULL) { 488*2882Svi117747 if (error != NULL) 489*2882Svi117747 *error = EINVAL; 490*2882Svi117747 return (ret); 491*2882Svi117747 } 492*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 493*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 494*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 495*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 496*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 497*2882Svi117747 if (error != NULL) 498*2882Svi117747 *error = EINVAL; 499*2882Svi117747 return (ret); 500*2882Svi117747 } 501*2882Svi117747 if (sip_msg_info->is_request) 502*2882Svi117747 ret = sip_msg_info->sip_req_method; 503*2882Svi117747 else if (error != NULL) 504*2882Svi117747 *error = EINVAL; 505*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 506*2882Svi117747 return (ret); 507*2882Svi117747 } 508*2882Svi117747 509*2882Svi117747 /* 510*2882Svi117747 * Return the URI from the request line 511*2882Svi117747 */ 512*2882Svi117747 const sip_str_t * 513*2882Svi117747 sip_get_request_uri_str(sip_msg_t sip_msg, int *error) 514*2882Svi117747 { 515*2882Svi117747 _sip_msg_t *_sip_msg; 516*2882Svi117747 sip_message_type_t *sip_msg_info; 517*2882Svi117747 sip_str_t *ret = NULL; 518*2882Svi117747 struct sip_uri *parsed_uri; 519*2882Svi117747 520*2882Svi117747 if (error != NULL) 521*2882Svi117747 *error = 0; 522*2882Svi117747 if (sip_msg == NULL) { 523*2882Svi117747 if (error != NULL) 524*2882Svi117747 *error = EINVAL; 525*2882Svi117747 return (NULL); 526*2882Svi117747 } 527*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 528*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 529*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 530*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 531*2882Svi117747 if (error != NULL) 532*2882Svi117747 *error = EINVAL; 533*2882Svi117747 return (NULL); 534*2882Svi117747 } 535*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 536*2882Svi117747 if (sip_msg_info->is_request) 537*2882Svi117747 ret = &sip_msg_info->sip_req_uri; 538*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 539*2882Svi117747 540*2882Svi117747 /* 541*2882Svi117747 * If the error is required, check the validity of the URI via 542*2882Svi117747 * sip_uri_parse(). 543*2882Svi117747 */ 544*2882Svi117747 if (error != NULL) { 545*2882Svi117747 parsed_uri = sip_parse_uri(ret, error); 546*2882Svi117747 if (parsed_uri != NULL) 547*2882Svi117747 sip_free_parsed_uri((sip_uri_t)parsed_uri); 548*2882Svi117747 } 549*2882Svi117747 return (ret); 550*2882Svi117747 } 551*2882Svi117747 552*2882Svi117747 /* 553*2882Svi117747 * Return the response code 554*2882Svi117747 */ 555*2882Svi117747 int 556*2882Svi117747 sip_get_response_code(sip_msg_t sip_msg, int *error) 557*2882Svi117747 { 558*2882Svi117747 _sip_msg_t *_sip_msg; 559*2882Svi117747 sip_message_type_t *sip_msg_info; 560*2882Svi117747 int ret = -1; 561*2882Svi117747 562*2882Svi117747 if (error != NULL) 563*2882Svi117747 *error = 0; 564*2882Svi117747 if (sip_msg == NULL) { 565*2882Svi117747 if (error != NULL) 566*2882Svi117747 *error = EINVAL; 567*2882Svi117747 return (ret); 568*2882Svi117747 } 569*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 570*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 571*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 572*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 573*2882Svi117747 if (error != NULL) 574*2882Svi117747 *error = EINVAL; 575*2882Svi117747 return (ret); 576*2882Svi117747 } 577*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 578*2882Svi117747 if (!sip_msg_info->is_request) 579*2882Svi117747 ret = sip_msg_info->sip_resp_code; 580*2882Svi117747 else if (error != NULL) 581*2882Svi117747 *error = EINVAL; 582*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 583*2882Svi117747 return (ret); 584*2882Svi117747 } 585*2882Svi117747 586*2882Svi117747 /* 587*2882Svi117747 * Get the response phrase 588*2882Svi117747 */ 589*2882Svi117747 const sip_str_t * 590*2882Svi117747 sip_get_response_phrase(sip_msg_t sip_msg, int *error) 591*2882Svi117747 { 592*2882Svi117747 _sip_msg_t *_sip_msg; 593*2882Svi117747 sip_message_type_t *sip_msg_info; 594*2882Svi117747 sip_str_t *ret = NULL; 595*2882Svi117747 596*2882Svi117747 if (error != NULL) 597*2882Svi117747 *error = 0; 598*2882Svi117747 if (sip_msg == NULL) { 599*2882Svi117747 if (error != NULL) 600*2882Svi117747 *error = EINVAL; 601*2882Svi117747 return (ret); 602*2882Svi117747 } 603*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 604*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 605*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 606*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 607*2882Svi117747 if (error != NULL) 608*2882Svi117747 *error = EINVAL; 609*2882Svi117747 return (ret); 610*2882Svi117747 } 611*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 612*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 613*2882Svi117747 if (!sip_msg_info->is_request) { 614*2882Svi117747 if (sip_msg_info->sip_resp_phrase_len == 0) 615*2882Svi117747 ret = NULL; 616*2882Svi117747 else 617*2882Svi117747 ret = &sip_msg_info->sip_resp_phrase; 618*2882Svi117747 } else if (error != NULL) { 619*2882Svi117747 *error = EINVAL; 620*2882Svi117747 } 621*2882Svi117747 return (ret); 622*2882Svi117747 } 623*2882Svi117747 624*2882Svi117747 /* 625*2882Svi117747 * Get the SIP version string 626*2882Svi117747 */ 627*2882Svi117747 const sip_str_t * 628*2882Svi117747 sip_get_sip_version(sip_msg_t sip_msg, int *error) 629*2882Svi117747 { 630*2882Svi117747 _sip_msg_t *_sip_msg; 631*2882Svi117747 sip_message_type_t *sip_msg_info; 632*2882Svi117747 sip_str_t *ret = NULL; 633*2882Svi117747 634*2882Svi117747 if (error != NULL) 635*2882Svi117747 *error = 0; 636*2882Svi117747 if (sip_msg == NULL) { 637*2882Svi117747 if (error != NULL) 638*2882Svi117747 *error = EINVAL; 639*2882Svi117747 return (ret); 640*2882Svi117747 } 641*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 642*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 643*2882Svi117747 if (_sip_msg->sip_msg_req_res == NULL) { 644*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 645*2882Svi117747 if (error != NULL) 646*2882Svi117747 *error = EINVAL; 647*2882Svi117747 return (ret); 648*2882Svi117747 } 649*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 650*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 651*2882Svi117747 ret = &sip_msg_info->sip_proto_version.version; 652*2882Svi117747 return (ret); 653*2882Svi117747 } 654*2882Svi117747 655*2882Svi117747 /* 656*2882Svi117747 * Return the length of the SIP message 657*2882Svi117747 */ 658*2882Svi117747 int 659*2882Svi117747 sip_get_msg_len(sip_msg_t sip_msg, int *error) 660*2882Svi117747 { 661*2882Svi117747 _sip_msg_t *_sip_msg; 662*2882Svi117747 663*2882Svi117747 if (error != NULL) 664*2882Svi117747 *error = 0; 665*2882Svi117747 if (sip_msg == NULL) { 666*2882Svi117747 if (error != NULL) 667*2882Svi117747 *error = EINVAL; 668*2882Svi117747 return (-1); 669*2882Svi117747 } 670*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 671*2882Svi117747 672*2882Svi117747 return (_sip_msg->sip_msg_len); 673*2882Svi117747 } 674*2882Svi117747 675*2882Svi117747 /* 676*2882Svi117747 * Get content as a string. Caller frees the string 677*2882Svi117747 */ 678*2882Svi117747 char * 679*2882Svi117747 sip_get_content(sip_msg_t sip_msg, int *error) 680*2882Svi117747 { 681*2882Svi117747 _sip_msg_t *_sip_msg; 682*2882Svi117747 sip_content_t *sip_content; 683*2882Svi117747 char *content; 684*2882Svi117747 int len; 685*2882Svi117747 char *p; 686*2882Svi117747 687*2882Svi117747 if (error != NULL) 688*2882Svi117747 *error = 0; 689*2882Svi117747 690*2882Svi117747 if (sip_msg == NULL) { 691*2882Svi117747 if (error != NULL) 692*2882Svi117747 *error = EINVAL; 693*2882Svi117747 return (NULL); 694*2882Svi117747 } 695*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 696*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 697*2882Svi117747 if (_sip_msg->sip_msg_content == NULL) { 698*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 699*2882Svi117747 if (error != NULL) 700*2882Svi117747 *error = EINVAL; 701*2882Svi117747 return (NULL); 702*2882Svi117747 } 703*2882Svi117747 content = malloc(_sip_msg->sip_msg_content_len + 1); 704*2882Svi117747 if (content == NULL) { 705*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 706*2882Svi117747 if (error != NULL) 707*2882Svi117747 *error = ENOMEM; 708*2882Svi117747 return (NULL); 709*2882Svi117747 } 710*2882Svi117747 p = content; 711*2882Svi117747 sip_content = _sip_msg->sip_msg_content; 712*2882Svi117747 while (sip_content != NULL) { 713*2882Svi117747 len = sip_content->sip_content_end - 714*2882Svi117747 sip_content->sip_content_start; 715*2882Svi117747 (void) strncpy(p, sip_content->sip_content_start, len); 716*2882Svi117747 p += len; 717*2882Svi117747 sip_content = sip_content->sip_content_next; 718*2882Svi117747 } 719*2882Svi117747 content[_sip_msg->sip_msg_content_len] = '\0'; 720*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 721*2882Svi117747 return (content); 722*2882Svi117747 } 723*2882Svi117747 724*2882Svi117747 /* 725*2882Svi117747 * copy sip_header with param, if any, to sip_msg 726*2882Svi117747 */ 727*2882Svi117747 int 728*2882Svi117747 sip_copy_header(sip_msg_t sip_msg, sip_header_t sip_header, char *param) 729*2882Svi117747 { 730*2882Svi117747 _sip_msg_t *_sip_msg; 731*2882Svi117747 _sip_header_t *_sip_header; 732*2882Svi117747 int ret; 733*2882Svi117747 734*2882Svi117747 if (sip_msg == NULL || sip_header == NULL) 735*2882Svi117747 return (EINVAL); 736*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 737*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 738*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 739*2882Svi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 740*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 741*2882Svi117747 return (EPERM); 742*2882Svi117747 } 743*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 744*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 745*2882Svi117747 return (EINVAL); 746*2882Svi117747 } 747*2882Svi117747 748*2882Svi117747 ret = _sip_copy_header(_sip_msg, _sip_header, param, B_TRUE); 749*2882Svi117747 if (_sip_msg->sip_msg_buf != NULL) 750*2882Svi117747 _sip_msg->sip_msg_modified = B_TRUE; 751*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 752*2882Svi117747 return (ret); 753*2882Svi117747 } 754*2882Svi117747 755*2882Svi117747 /* 756*2882Svi117747 * copy the header specified by header_name, with param, if any 757*2882Svi117747 */ 758*2882Svi117747 int 759*2882Svi117747 sip_copy_header_by_name(sip_msg_t old_msg, sip_msg_t new_msg, 760*2882Svi117747 char *header_name, char *param) 761*2882Svi117747 { 762*2882Svi117747 int ret; 763*2882Svi117747 _sip_msg_t *_old_msg = (_sip_msg_t *)old_msg; 764*2882Svi117747 _sip_msg_t *_new_msg = (_sip_msg_t *)new_msg; 765*2882Svi117747 766*2882Svi117747 if (_old_msg == NULL || _new_msg == NULL || header_name == NULL || 767*2882Svi117747 _old_msg == _new_msg) { 768*2882Svi117747 return (EINVAL); 769*2882Svi117747 } 770*2882Svi117747 (void) pthread_mutex_lock(&_new_msg->sip_msg_mutex); 771*2882Svi117747 if (_new_msg->sip_msg_cannot_be_modified) { 772*2882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 773*2882Svi117747 return (EPERM); 774*2882Svi117747 } 775*2882Svi117747 776*2882Svi117747 (void) pthread_mutex_lock(&_old_msg->sip_msg_mutex); 777*2882Svi117747 ret = _sip_find_and_copy_header(_old_msg, _new_msg, header_name, param, 778*2882Svi117747 B_FALSE); 779*2882Svi117747 (void) pthread_mutex_unlock(&_old_msg->sip_msg_mutex); 780*2882Svi117747 if (_new_msg->sip_msg_buf != NULL) 781*2882Svi117747 _new_msg->sip_msg_modified = B_TRUE; 782*2882Svi117747 (void) pthread_mutex_unlock(&_new_msg->sip_msg_mutex); 783*2882Svi117747 return (ret); 784*2882Svi117747 } 785*2882Svi117747 786*2882Svi117747 /* 787*2882Svi117747 * add the given header to sip_message 788*2882Svi117747 */ 789*2882Svi117747 int 790*2882Svi117747 sip_add_header(sip_msg_t sip_msg, char *header_string) 791*2882Svi117747 { 792*2882Svi117747 int header_size; 793*2882Svi117747 _sip_header_t *new_header; 794*2882Svi117747 _sip_msg_t *_sip_msg; 795*2882Svi117747 796*2882Svi117747 if (sip_msg == NULL || header_string == NULL) 797*2882Svi117747 return (EINVAL); 798*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 799*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 800*2882Svi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 801*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 802*2882Svi117747 return (EPERM); 803*2882Svi117747 } 804*2882Svi117747 header_size = strlen(header_string) + strlen(SIP_CRLF); 805*2882Svi117747 new_header = sip_new_header(header_size); 806*2882Svi117747 if (new_header == NULL) { 807*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 808*2882Svi117747 return (ENOMEM); 809*2882Svi117747 } 810*2882Svi117747 811*2882Svi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, "%s%s", 812*2882Svi117747 header_string, SIP_CRLF); 813*2882Svi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 814*2882Svi117747 if (_sip_msg->sip_msg_buf != NULL) 815*2882Svi117747 _sip_msg->sip_msg_modified = B_TRUE; 816*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 817*2882Svi117747 return (0); 818*2882Svi117747 } 819*2882Svi117747 820*2882Svi117747 /* 821*2882Svi117747 * add the given param to the sip_header. create a new header with the param 822*2882Svi117747 * and mark the old header as deleted. 823*2882Svi117747 */ 824*2882Svi117747 sip_header_t 825*2882Svi117747 sip_add_param(sip_header_t sip_header, char *param, int *error) 826*2882Svi117747 { 827*2882Svi117747 _sip_header_t *_sip_header; 828*2882Svi117747 _sip_header_t *new_header; 829*2882Svi117747 int hdrlen; 830*2882Svi117747 _sip_msg_t *_sip_msg; 831*2882Svi117747 int param_len; 832*2882Svi117747 char *tmp_ptr; 833*2882Svi117747 834*2882Svi117747 if (error != NULL) 835*2882Svi117747 *error = 0; 836*2882Svi117747 837*2882Svi117747 if (param == NULL || sip_header == NULL) { 838*2882Svi117747 if (error != NULL) 839*2882Svi117747 *error = EINVAL; 840*2882Svi117747 return (NULL); 841*2882Svi117747 } 842*2882Svi117747 843*2882Svi117747 _sip_header = (_sip_header_t *)sip_header; 844*2882Svi117747 845*2882Svi117747 (void) pthread_mutex_lock(&_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 846*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_cannot_be_modified) { 847*2882Svi117747 if (error != NULL) 848*2882Svi117747 *error = EPERM; 849*2882Svi117747 (void) pthread_mutex_unlock( 850*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 851*2882Svi117747 return (NULL); 852*2882Svi117747 } 853*2882Svi117747 if (_sip_header->sip_header_state == SIP_HEADER_DELETED) { 854*2882Svi117747 if (error != NULL) 855*2882Svi117747 *error = EINVAL; 856*2882Svi117747 (void) pthread_mutex_unlock( 857*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 858*2882Svi117747 return (NULL); 859*2882Svi117747 } 860*2882Svi117747 861*2882Svi117747 param_len = SIP_SPACE_LEN + sizeof (char) + SIP_SPACE_LEN + 862*2882Svi117747 strlen(param); 863*2882Svi117747 hdrlen = _sip_header->sip_hdr_end - _sip_header->sip_hdr_start; 864*2882Svi117747 new_header = sip_new_header(hdrlen + param_len); 865*2882Svi117747 if (new_header == NULL) { 866*2882Svi117747 if (error != NULL) 867*2882Svi117747 *error = ENOMEM; 868*2882Svi117747 (void) pthread_mutex_unlock( 869*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 870*2882Svi117747 return (NULL); 871*2882Svi117747 } 872*2882Svi117747 (void) memcpy(new_header->sip_hdr_start, _sip_header->sip_hdr_start, 873*2882Svi117747 hdrlen); 874*2882Svi117747 new_header->sip_hdr_end = new_header->sip_hdr_start + hdrlen; 875*2882Svi117747 hdrlen = param_len + 1; 876*2882Svi117747 /* 877*2882Svi117747 * Find CRLF 878*2882Svi117747 */ 879*2882Svi117747 tmp_ptr = new_header->sip_hdr_end; 880*2882Svi117747 while (*tmp_ptr-- != '\n') { 881*2882Svi117747 hdrlen++; 882*2882Svi117747 if (tmp_ptr == new_header->sip_hdr_start) { 883*2882Svi117747 sip_free_header(new_header); 884*2882Svi117747 if (error != NULL) 885*2882Svi117747 *error = EINVAL; 886*2882Svi117747 (void) pthread_mutex_unlock( 887*2882Svi117747 &_sip_header->sip_hdr_sipmsg->sip_msg_mutex); 888*2882Svi117747 return (NULL); 889*2882Svi117747 } 890*2882Svi117747 } 891*2882Svi117747 (void) snprintf(tmp_ptr, hdrlen + 1, 892*2882Svi117747 " %c %s%s", SIP_SEMI, param, SIP_CRLF); 893*2882Svi117747 new_header->sip_hdr_end += param_len; 894*2882Svi117747 new_header->sip_header_functions = _sip_header->sip_header_functions; 895*2882Svi117747 _sip_msg = _sip_header->sip_hdr_sipmsg; 896*2882Svi117747 _sip_add_header(_sip_msg, new_header, B_TRUE, B_FALSE, NULL); 897*2882Svi117747 if (_sip_header->sip_hdr_sipmsg->sip_msg_buf != NULL) 898*2882Svi117747 _sip_header->sip_hdr_sipmsg->sip_msg_modified = B_TRUE; 899*2882Svi117747 (void) pthread_mutex_unlock(&new_header->sip_hdr_sipmsg->sip_msg_mutex); 900*2882Svi117747 (void) sip_delete_header(sip_header); 901*2882Svi117747 return ((sip_header_t)new_header); 902*2882Svi117747 } 903*2882Svi117747 904*2882Svi117747 /* 905*2882Svi117747 * Get Request URI 906*2882Svi117747 */ 907*2882Svi117747 const struct sip_uri * 908*2882Svi117747 sip_get_request_uri(sip_msg_t sip_msg, int *error) 909*2882Svi117747 { 910*2882Svi117747 _sip_msg_t *_sip_msg; 911*2882Svi117747 sip_message_type_t *sip_msg_info; 912*2882Svi117747 const struct sip_uri *ret = NULL; 913*2882Svi117747 914*2882Svi117747 if (error != NULL) 915*2882Svi117747 *error = 0; 916*2882Svi117747 917*2882Svi117747 if (sip_msg == NULL) { 918*2882Svi117747 if (error != NULL) 919*2882Svi117747 *error = EINVAL; 920*2882Svi117747 return (NULL); 921*2882Svi117747 } 922*2882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 923*2882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 924*2882Svi117747 sip_msg_info = _sip_msg->sip_msg_req_res; 925*2882Svi117747 if (sip_msg_info != NULL && sip_msg_info->is_request) { 926*2882Svi117747 ret = sip_msg_info->sip_req_parse_uri; 927*2882Svi117747 } else { 928*2882Svi117747 if (error != NULL) 929*2882Svi117747 *error = EINVAL; 930*2882Svi117747 } 931*2882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 932*2882Svi117747 933*2882Svi117747 if (ret != NULL) { 934*2882Svi117747 if (ret->sip_uri_scheme.sip_str_len == 0 || 935*2882Svi117747 ret->sip_uri_scheme.sip_str_ptr == NULL) { 936*2882Svi117747 ret = NULL; 937*2882Svi117747 if (error != NULL) 938*2882Svi117747 *error = EINVAL; 939*2882Svi117747 } else if (ret->sip_uri_errflags != 0 && error != NULL) { 940*2882Svi117747 *error = EINVAL; 941*2882Svi117747 } 942*2882Svi117747 } 943*2882Svi117747 return ((sip_uri_t)ret); 944*2882Svi117747 } 945*2882Svi117747 946*2882Svi117747 /* 947*2882Svi117747 * returns a comma separated string of all the sent-by values registered by 948*2882Svi117747 * the UA. 949*2882Svi117747 */ 950*2882Svi117747 char * 951*2882Svi117747 sip_sent_by_to_str(int *error) 952*2882Svi117747 { 953*2882Svi117747 sent_by_list_t *sb; 954*2882Svi117747 int sb_len = 0; 955*2882Svi117747 int slen; 956*2882Svi117747 char *sb_str; 957*2882Svi117747 char *p; 958*2882Svi117747 int count = 0; 959*2882Svi117747 int cnt = 0; 960*2882Svi117747 961*2882Svi117747 if (error != NULL) 962*2882Svi117747 *error = 0; 963*2882Svi117747 964*2882Svi117747 (void) pthread_mutex_lock(&sip_sent_by_lock); 965*2882Svi117747 if (sip_sent_by == NULL) { 966*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 967*2882Svi117747 return (NULL); 968*2882Svi117747 } 969*2882Svi117747 sb = sip_sent_by; 970*2882Svi117747 for (cnt = 0; cnt < sip_sent_by_count; cnt++) { 971*2882Svi117747 sb_len += strlen(sb->sb_val); 972*2882Svi117747 sb = sb->sb_next; 973*2882Svi117747 } 974*2882Svi117747 /* 975*2882Svi117747 * for the commas 976*2882Svi117747 */ 977*2882Svi117747 sb_len += sip_sent_by_count - 1; 978*2882Svi117747 sb_str = malloc(sb_len + 1); 979*2882Svi117747 if (sb_str == NULL) { 980*2882Svi117747 if (error != NULL) 981*2882Svi117747 *error = ENOMEM; 982*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 983*2882Svi117747 return (NULL); 984*2882Svi117747 } 985*2882Svi117747 sb = sip_sent_by; 986*2882Svi117747 p = sb_str; 987*2882Svi117747 slen = sb_len + 1; 988*2882Svi117747 for (cnt = 0; cnt < sip_sent_by_count; cnt++) { 989*2882Svi117747 if (cnt == 0) { 990*2882Svi117747 count = snprintf(p, slen, "%s", sb->sb_val); 991*2882Svi117747 } else { 992*2882Svi117747 count = snprintf(p, slen, "%c%s", SIP_COMMA, 993*2882Svi117747 sb->sb_val); 994*2882Svi117747 } 995*2882Svi117747 p += count; 996*2882Svi117747 slen -= count; 997*2882Svi117747 sb = sb->sb_next; 998*2882Svi117747 } 999*2882Svi117747 sb_str[sb_len] = '\0'; 1000*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 1001*2882Svi117747 return (sb_str); 1002*2882Svi117747 } 1003*2882Svi117747 1004*2882Svi117747 /* 1005*2882Svi117747 * A comma separated list of sent-by values. 1006*2882Svi117747 */ 1007*2882Svi117747 int 1008*2882Svi117747 sip_register_sent_by(char *val) 1009*2882Svi117747 { 1010*2882Svi117747 sent_by_list_t *sb = NULL; 1011*2882Svi117747 sent_by_list_t *sb_tail = NULL; 1012*2882Svi117747 char *str; 1013*2882Svi117747 int count = 0; 1014*2882Svi117747 1015*2882Svi117747 if (val == NULL) 1016*2882Svi117747 return (EINVAL); 1017*2882Svi117747 str = strtok(val, ","); 1018*2882Svi117747 while (str != NULL) { 1019*2882Svi117747 int slen; 1020*2882Svi117747 char *start = str; 1021*2882Svi117747 char *end = str + strlen(str) - 1; 1022*2882Svi117747 1023*2882Svi117747 while (isspace(*start)) 1024*2882Svi117747 start++; 1025*2882Svi117747 while (isspace(*end)) 1026*2882Svi117747 end--; 1027*2882Svi117747 if (end <= start) 1028*2882Svi117747 goto err_ret; 1029*2882Svi117747 slen = end - start + 1; 1030*2882Svi117747 sb_tail = (sent_by_list_t *)malloc(sizeof (*sb_tail)); 1031*2882Svi117747 if (sb_tail == NULL) 1032*2882Svi117747 goto err_ret; 1033*2882Svi117747 sb_tail->sb_next = sb_tail->sb_prev = NULL; 1034*2882Svi117747 if ((sb_tail->sb_val = (char *)malloc(slen + 1)) == NULL) { 1035*2882Svi117747 free(sb_tail); 1036*2882Svi117747 goto err_ret; 1037*2882Svi117747 } 1038*2882Svi117747 (void) strncpy(sb_tail->sb_val, start, slen); 1039*2882Svi117747 sb_tail->sb_val[slen] = '\0'; 1040*2882Svi117747 if (sb == NULL) { 1041*2882Svi117747 sb = sb_tail; 1042*2882Svi117747 } else { 1043*2882Svi117747 sb_tail->sb_next = sb; 1044*2882Svi117747 sb->sb_prev = sb_tail; 1045*2882Svi117747 sb = sb_tail; 1046*2882Svi117747 } 1047*2882Svi117747 count++; 1048*2882Svi117747 str = strtok(NULL, ","); 1049*2882Svi117747 } 1050*2882Svi117747 sb_tail = sb; 1051*2882Svi117747 while (sb_tail->sb_next != NULL) 1052*2882Svi117747 sb_tail = sb_tail->sb_next; 1053*2882Svi117747 (void) pthread_mutex_lock(&sip_sent_by_lock); 1054*2882Svi117747 if (sip_sent_by != NULL) { 1055*2882Svi117747 sb_tail->sb_next = sip_sent_by; 1056*2882Svi117747 sip_sent_by->sb_prev = sb_tail; 1057*2882Svi117747 } 1058*2882Svi117747 sip_sent_by = sb; 1059*2882Svi117747 sip_sent_by_count += count; 1060*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 1061*2882Svi117747 return (0); 1062*2882Svi117747 err_ret: 1063*2882Svi117747 sb_tail = sb; 1064*2882Svi117747 for (; count > 0; count--) { 1065*2882Svi117747 sb = sb_tail->sb_next; 1066*2882Svi117747 free(sb_tail->sb_val); 1067*2882Svi117747 sb_tail->sb_next = NULL; 1068*2882Svi117747 sb_tail->sb_prev = NULL; 1069*2882Svi117747 free(sb_tail); 1070*2882Svi117747 sb_tail = sb; 1071*2882Svi117747 } 1072*2882Svi117747 return (EINVAL); 1073*2882Svi117747 } 1074*2882Svi117747 1075*2882Svi117747 /* 1076*2882Svi117747 * Un-register sent-by values; 'val' contains a comma separated list 1077*2882Svi117747 */ 1078*2882Svi117747 void 1079*2882Svi117747 sip_unregister_sent_by(char *val) 1080*2882Svi117747 { 1081*2882Svi117747 sent_by_list_t *sb; 1082*2882Svi117747 char *str; 1083*2882Svi117747 int count = 0; 1084*2882Svi117747 1085*2882Svi117747 (void) pthread_mutex_lock(&sip_sent_by_lock); 1086*2882Svi117747 str = strtok(val, ","); 1087*2882Svi117747 while (str != NULL) { 1088*2882Svi117747 sb = sip_sent_by; 1089*2882Svi117747 for (count = 0; count < sip_sent_by_count; count++) { 1090*2882Svi117747 if (strncmp(sb->sb_val, str, strlen(str)) == 0) { 1091*2882Svi117747 if (sb == sip_sent_by) { 1092*2882Svi117747 if (sb->sb_next != NULL) 1093*2882Svi117747 sip_sent_by = sb->sb_next; 1094*2882Svi117747 else 1095*2882Svi117747 sip_sent_by = NULL; 1096*2882Svi117747 } else if (sb->sb_next == NULL) { 1097*2882Svi117747 sb->sb_prev->sb_next = NULL; 1098*2882Svi117747 } else { 1099*2882Svi117747 sb->sb_prev->sb_next = sb->sb_next; 1100*2882Svi117747 sb->sb_next->sb_prev = sb->sb_prev; 1101*2882Svi117747 } 1102*2882Svi117747 sip_sent_by_count--; 1103*2882Svi117747 sb->sb_next = NULL; 1104*2882Svi117747 sb->sb_prev = NULL; 1105*2882Svi117747 free(sb->sb_val); 1106*2882Svi117747 free(sb); 1107*2882Svi117747 break; 1108*2882Svi117747 } 1109*2882Svi117747 sb = sb->sb_next; 1110*2882Svi117747 } 1111*2882Svi117747 str = strtok(NULL, ","); 1112*2882Svi117747 } 1113*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 1114*2882Svi117747 } 1115*2882Svi117747 1116*2882Svi117747 /* 1117*2882Svi117747 * Un-register all the sent-by values 1118*2882Svi117747 */ 1119*2882Svi117747 void 1120*2882Svi117747 sip_unregister_all_sent_by() 1121*2882Svi117747 { 1122*2882Svi117747 sent_by_list_t *sb; 1123*2882Svi117747 int count; 1124*2882Svi117747 1125*2882Svi117747 (void) pthread_mutex_lock(&sip_sent_by_lock); 1126*2882Svi117747 sb = sip_sent_by; 1127*2882Svi117747 for (count = 0; count < sip_sent_by_count; count++) { 1128*2882Svi117747 sip_sent_by = sb->sb_next; 1129*2882Svi117747 free(sb->sb_val); 1130*2882Svi117747 sb->sb_next = NULL; 1131*2882Svi117747 sb->sb_prev = NULL; 1132*2882Svi117747 free(sb); 1133*2882Svi117747 sb = sip_sent_by; 1134*2882Svi117747 } 1135*2882Svi117747 sip_sent_by = NULL; 1136*2882Svi117747 sip_sent_by_count = 0; 1137*2882Svi117747 (void) pthread_mutex_unlock(&sip_sent_by_lock); 1138*2882Svi117747 } 1139*2882Svi117747 1140*2882Svi117747 /* 1141*2882Svi117747 * Given a response code, return the corresponding phrase 1142*2882Svi117747 */ 1143*2882Svi117747 char * 1144*2882Svi117747 sip_get_resp_desc(int resp_code) 1145*2882Svi117747 { 1146*2882Svi117747 switch (resp_code) { 1147*2882Svi117747 case SIP_TRYING: 1148*2882Svi117747 return ("TRYING"); 1149*2882Svi117747 case SIP_RINGING: 1150*2882Svi117747 return ("RINGING"); 1151*2882Svi117747 case SIP_CALL_IS_BEING_FORWARDED: 1152*2882Svi117747 return ("CALL_IS_BEING_FORWARDED"); 1153*2882Svi117747 case SIP_QUEUED: 1154*2882Svi117747 return ("QUEUED"); 1155*2882Svi117747 case SIP_SESSION_PROGRESS: 1156*2882Svi117747 return ("SESSION_PROGRESS"); 1157*2882Svi117747 case SIP_OK: 1158*2882Svi117747 return ("OK"); 1159*2882Svi117747 case SIP_ACCEPTED: 1160*2882Svi117747 return ("ACCEPTED"); 1161*2882Svi117747 case SIP_MULTIPLE_CHOICES: 1162*2882Svi117747 return ("MULTIPLE_CHOICES"); 1163*2882Svi117747 case SIP_MOVED_PERMANENTLY: 1164*2882Svi117747 return ("MOVED_PERMANENTLY"); 1165*2882Svi117747 case SIP_MOVED_TEMPORARILY: 1166*2882Svi117747 return ("MOVED_TEMPORARILY"); 1167*2882Svi117747 case SIP_USE_PROXY: 1168*2882Svi117747 return ("USE_PROXY"); 1169*2882Svi117747 case SIP_ALTERNATIVE_SERVICE: 1170*2882Svi117747 return ("ALTERNATIVE_SERVICE"); 1171*2882Svi117747 case SIP_BAD_REQUEST: 1172*2882Svi117747 return ("BAD_REQUEST"); 1173*2882Svi117747 case SIP_UNAUTHORIZED: 1174*2882Svi117747 return ("UNAUTHORIZED"); 1175*2882Svi117747 case SIP_PAYMENT_REQUIRED: 1176*2882Svi117747 return ("PAYMENT_REQUIRED"); 1177*2882Svi117747 case SIP_FORBIDDEN: 1178*2882Svi117747 return ("FORBIDDEN"); 1179*2882Svi117747 case SIP_NOT_FOUND: 1180*2882Svi117747 return ("NOT_FOUND"); 1181*2882Svi117747 case SIP_METHOD_NOT_ALLOWED: 1182*2882Svi117747 return ("METHOD_NOT_ALLOWED"); 1183*2882Svi117747 case SIP_NOT_ACCEPTABLE: 1184*2882Svi117747 return ("NOT_ACCEPTABLE"); 1185*2882Svi117747 case SIP_PROXY_AUTH_REQUIRED: 1186*2882Svi117747 return ("PROXY_AUTH_REQUIRED"); 1187*2882Svi117747 case SIP_REQUEST_TIMEOUT: 1188*2882Svi117747 return ("REQUEST_TIMEOUT"); 1189*2882Svi117747 case SIP_GONE: 1190*2882Svi117747 return ("GONE"); 1191*2882Svi117747 case SIP_REQUEST_ENTITY_2_LARGE: 1192*2882Svi117747 return ("REQUEST_ENTITY_2_LARGE"); 1193*2882Svi117747 case SIP_REQUEST_URI_2_LONG: 1194*2882Svi117747 return ("REQUEST_URI_2_LONG"); 1195*2882Svi117747 case SIP_UNSUPPORTED_MEDIA_TYPE: 1196*2882Svi117747 return ("UNSUPPORTED_MEDIA_TYPE"); 1197*2882Svi117747 case SIP_UNSUPPORTED_URI_SCHEME: 1198*2882Svi117747 return ("UNSUPPORTED_URI_SCHEME"); 1199*2882Svi117747 case SIP_BAD_EXTENSION: 1200*2882Svi117747 return ("BAD_EXTENSION"); 1201*2882Svi117747 case SIP_EXTENSION_REQUIRED: 1202*2882Svi117747 return ("EXTENSION_REQUIRED"); 1203*2882Svi117747 case SIP_INTERVAL_2_BRIEF: 1204*2882Svi117747 return ("INTERVAL_2_BRIEF"); 1205*2882Svi117747 case SIP_TEMPORARILY_UNAVAIL: 1206*2882Svi117747 return ("TEMPORARILY_UNAVAIL"); 1207*2882Svi117747 case SIP_CALL_NON_EXISTANT: 1208*2882Svi117747 return ("CALL_NON_EXISTANT"); 1209*2882Svi117747 case SIP_LOOP_DETECTED: 1210*2882Svi117747 return ("LOOP_DETECTED"); 1211*2882Svi117747 case SIP_TOO_MANY_HOOPS: 1212*2882Svi117747 return ("TOO_MANY_HOOPS"); 1213*2882Svi117747 case SIP_ADDRESS_INCOMPLETE: 1214*2882Svi117747 return ("ADDRESS_INCOMPLETE"); 1215*2882Svi117747 case SIP_AMBIGUOUS: 1216*2882Svi117747 return ("AMBIGUOUS"); 1217*2882Svi117747 case SIP_BUSY_HERE: 1218*2882Svi117747 return ("BUSY_HERE"); 1219*2882Svi117747 case SIP_REQUEST_TERMINATED: 1220*2882Svi117747 return ("REQUEST_TERMINATED"); 1221*2882Svi117747 case SIP_NOT_ACCEPTABLE_HERE: 1222*2882Svi117747 return ("NOT_ACCEPTABLE_HERE"); 1223*2882Svi117747 case SIP_BAD_EVENT: 1224*2882Svi117747 return ("BAD_EVENT"); 1225*2882Svi117747 case SIP_REQUEST_PENDING: 1226*2882Svi117747 return ("REQUEST_PENDING"); 1227*2882Svi117747 case SIP_UNDECIPHERABLE: 1228*2882Svi117747 return ("UNDECIPHERABLE"); 1229*2882Svi117747 case SIP_SERVER_INTERNAL_ERROR: 1230*2882Svi117747 return ("SERVER_INTERNAL_ERROR"); 1231*2882Svi117747 case SIP_NOT_IMPLEMENTED: 1232*2882Svi117747 return ("NOT_IMPLEMENTED"); 1233*2882Svi117747 case SIP_BAD_GATEWAY: 1234*2882Svi117747 return ("BAD_GATEWAY"); 1235*2882Svi117747 case SIP_SERVICE_UNAVAILABLE: 1236*2882Svi117747 return ("SERVICE_UNAVAILABLE"); 1237*2882Svi117747 case SIP_SERVER_TIMEOUT: 1238*2882Svi117747 return ("SERVER_TIMEOUT"); 1239*2882Svi117747 case SIP_VERSION_NOT_SUPPORTED: 1240*2882Svi117747 return ("VERSION_NOT_SUPPORTED"); 1241*2882Svi117747 case SIP_MESSAGE_2_LARGE: 1242*2882Svi117747 return ("MESSAGE_2_LARGE"); 1243*2882Svi117747 case SIP_BUSY_EVERYWHERE: 1244*2882Svi117747 return ("BUSY_EVERYWHERE"); 1245*2882Svi117747 case SIP_DECLINE: 1246*2882Svi117747 return ("DECLINE"); 1247*2882Svi117747 case SIP_DOES_NOT_EXIST_ANYWHERE: 1248*2882Svi117747 return ("DOES_NOT_EXIST_ANYWHERE"); 1249*2882Svi117747 case SIP_NOT_ACCEPTABLE_ANYWHERE: 1250*2882Svi117747 return ("NOT_ACCEPTABLE_ANYWHERE"); 1251*2882Svi117747 default: 1252*2882Svi117747 return ("UNKNOWN"); 1253*2882Svi117747 } 1254*2882Svi117747 } 1255*2882Svi117747 1256*2882Svi117747 /* 1257*2882Svi117747 * The following three fns initialize and destroy the private library 1258*2882Svi117747 * data in sip_conn_object_t. The assumption is that the 1st member 1259*2882Svi117747 * of sip_conn_object_t is reserved for library use. The private data 1260*2882Svi117747 * is used only for byte-stream protocols such as TCP to accumulate 1261*2882Svi117747 * a complete SIP message, based on the CONTENT-LENGTH value, before 1262*2882Svi117747 * processing it. 1263*2882Svi117747 */ 1264*2882Svi117747 int 1265*2882Svi117747 sip_init_conn_object(sip_conn_object_t obj) 1266*2882Svi117747 { 1267*2882Svi117747 void **obj_val; 1268*2882Svi117747 sip_conn_obj_pvt_t *pvt_data; 1269*2882Svi117747 1270*2882Svi117747 if (obj == NULL) 1271*2882Svi117747 return (EINVAL); 1272*2882Svi117747 pvt_data = malloc(sizeof (sip_conn_obj_pvt_t)); 1273*2882Svi117747 if (pvt_data == NULL) 1274*2882Svi117747 return (ENOMEM); 1275*2882Svi117747 pvt_data->sip_conn_obj_cache = NULL; 1276*2882Svi117747 pvt_data->sip_conn_obj_reass = malloc(sizeof (sip_reass_entry_t)); 1277*2882Svi117747 if (pvt_data->sip_conn_obj_reass == NULL) { 1278*2882Svi117747 free(pvt_data); 1279*2882Svi117747 return (ENOMEM); 1280*2882Svi117747 } 1281*2882Svi117747 bzero(pvt_data->sip_conn_obj_reass, sizeof (sip_reass_entry_t)); 1282*2882Svi117747 (void) pthread_mutex_init(&pvt_data->sip_conn_obj_reass_lock, NULL); 1283*2882Svi117747 (void) pthread_mutex_init(&pvt_data->sip_conn_obj_cache_lock, NULL); 1284*2882Svi117747 sip_refhold_conn(obj); 1285*2882Svi117747 obj_val = (void *)obj; 1286*2882Svi117747 *obj_val = (void *)pvt_data; 1287*2882Svi117747 1288*2882Svi117747 return (0); 1289*2882Svi117747 } 1290*2882Svi117747 1291*2882Svi117747 /* 1292*2882Svi117747 * Clear private date, if any 1293*2882Svi117747 */ 1294*2882Svi117747 void 1295*2882Svi117747 sip_clear_stale_data(sip_conn_object_t obj) 1296*2882Svi117747 { 1297*2882Svi117747 void **obj_val; 1298*2882Svi117747 sip_conn_obj_pvt_t *pvt_data; 1299*2882Svi117747 sip_reass_entry_t *reass; 1300*2882Svi117747 1301*2882Svi117747 if (obj == NULL) 1302*2882Svi117747 return; 1303*2882Svi117747 obj_val = (void *)obj; 1304*2882Svi117747 pvt_data = (sip_conn_obj_pvt_t *)*obj_val; 1305*2882Svi117747 (void) pthread_mutex_lock(&pvt_data->sip_conn_obj_reass_lock); 1306*2882Svi117747 reass = pvt_data->sip_conn_obj_reass; 1307*2882Svi117747 if (reass->sip_reass_msg != NULL) { 1308*2882Svi117747 assert(reass->sip_reass_msglen > 0); 1309*2882Svi117747 free(reass->sip_reass_msg); 1310*2882Svi117747 reass->sip_reass_msglen = 0; 1311*2882Svi117747 } 1312*2882Svi117747 assert(reass->sip_reass_msglen == 0); 1313*2882Svi117747 (void) pthread_mutex_unlock(&pvt_data->sip_conn_obj_reass_lock); 1314*2882Svi117747 } 1315*2882Svi117747 1316*2882Svi117747 /* 1317*2882Svi117747 * Walk through all the transactions, remove if this obj has been cached 1318*2882Svi117747 * by any. 1319*2882Svi117747 */ 1320*2882Svi117747 void 1321*2882Svi117747 sip_conn_destroyed(sip_conn_object_t obj) 1322*2882Svi117747 { 1323*2882Svi117747 void **obj_val; 1324*2882Svi117747 sip_conn_obj_pvt_t *pvt_data; 1325*2882Svi117747 1326*2882Svi117747 if (obj == NULL) 1327*2882Svi117747 return; 1328*2882Svi117747 obj_val = (void *)obj; 1329*2882Svi117747 pvt_data = (sip_conn_obj_pvt_t *)*obj_val; 1330*2882Svi117747 1331*2882Svi117747 sip_clear_stale_data(obj); 1332*2882Svi117747 free(pvt_data->sip_conn_obj_reass); 1333*2882Svi117747 pvt_data->sip_conn_obj_reass = NULL; 1334*2882Svi117747 (void) pthread_mutex_destroy(&pvt_data->sip_conn_obj_reass_lock); 1335*2882Svi117747 1336*2882Svi117747 sip_del_conn_obj_cache(obj, NULL); 1337*2882Svi117747 (void) pthread_mutex_destroy(&pvt_data->sip_conn_obj_cache_lock); 1338*2882Svi117747 1339*2882Svi117747 free(pvt_data); 1340*2882Svi117747 *obj_val = NULL; 1341*2882Svi117747 sip_refrele_conn(obj); 1342*2882Svi117747 } 1343