12882Svi117747 /* 22882Svi117747 * CDDL HEADER START 32882Svi117747 * 42882Svi117747 * The contents of this file are subject to the terms of the 52882Svi117747 * Common Development and Distribution License (the "License"). 62882Svi117747 * You may not use this file except in compliance with the License. 72882Svi117747 * 82882Svi117747 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92882Svi117747 * or http://www.opensolaris.org/os/licensing. 102882Svi117747 * See the License for the specific language governing permissions 112882Svi117747 * and limitations under the License. 122882Svi117747 * 132882Svi117747 * When distributing Covered Code, include this CDDL HEADER in each 142882Svi117747 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152882Svi117747 * If applicable, add the following below this CDDL HEADER, with the 162882Svi117747 * fields enclosed by brackets "[]" replaced with your own identifying 172882Svi117747 * information: Portions Copyright [yyyy] [name of copyright owner] 182882Svi117747 * 192882Svi117747 * CDDL HEADER END 202882Svi117747 */ 212882Svi117747 222882Svi117747 /* 23*3439Svi117747 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 242882Svi117747 * Use is subject to license terms. 252882Svi117747 */ 262882Svi117747 272882Svi117747 #pragma ident "%Z%%M% %I% %E% SMI" 282882Svi117747 29*3439Svi117747 #include <stdio.h> 30*3439Svi117747 #include <assert.h> 31*3439Svi117747 #include <errno.h> 32*3439Svi117747 #include <pthread.h> 33*3439Svi117747 #include <stdlib.h> 34*3439Svi117747 #include <string.h> 35*3439Svi117747 #include <sip.h> 36*3439Svi117747 372882Svi117747 #include "sip_msg.h" 382882Svi117747 #include "sip_miscdefs.h" 392882Svi117747 #include "sip_parse_generic.h" 402882Svi117747 412882Svi117747 /* 422882Svi117747 * Response consists of SIP version, response code, response phrase and CRLF. 432882Svi117747 */ 442882Svi117747 #define SIP_RESPONSE "%s %d %s%s" 452882Svi117747 462882Svi117747 void sip_free_content(_sip_msg_t *); 472882Svi117747 482882Svi117747 /* 492882Svi117747 * Allocate a new sip msg struct. 502882Svi117747 */ 512882Svi117747 sip_msg_t 522882Svi117747 sip_new_msg() 532882Svi117747 { 542882Svi117747 _sip_msg_t *sip_msg; 552882Svi117747 562882Svi117747 sip_msg = calloc(1, sizeof (_sip_msg_t)); 572882Svi117747 if (sip_msg != NULL) { 582882Svi117747 sip_msg->sip_msg_ref_cnt = 1; 592882Svi117747 (void) pthread_mutex_init(&sip_msg->sip_msg_mutex, NULL); 602882Svi117747 } 612882Svi117747 return ((sip_msg_t)sip_msg); 622882Svi117747 } 632882Svi117747 642882Svi117747 /* 652882Svi117747 * Free all resources. The lock is taken by SIP_MSG_REFCNT_DECR. The 662882Svi117747 * thread that decrements the last refcount should take care that 672882Svi117747 * the message is not accessible to other threads before doing so. 682882Svi117747 * Else, if the message is still accessible to others, it is 692882Svi117747 * possible that the other thread could be waiting to take the 702882Svi117747 * lock when we proceed to destroy it. 712882Svi117747 */ 722882Svi117747 void 732882Svi117747 sip_destroy_msg(_sip_msg_t *_sip_msg) 742882Svi117747 { 752882Svi117747 #ifdef __solaris__ 762882Svi117747 assert(mutex_held(&_sip_msg->sip_msg_mutex)); 772882Svi117747 #endif 782882Svi117747 (void) sip_delete_start_line_locked(_sip_msg); 792882Svi117747 assert(_sip_msg->sip_msg_ref_cnt == 0); 802882Svi117747 sip_delete_all_headers((sip_msg_t)_sip_msg); 812882Svi117747 sip_free_content(_sip_msg); 822882Svi117747 if (_sip_msg->sip_msg_buf != NULL) 832882Svi117747 free(_sip_msg->sip_msg_buf); 842882Svi117747 852882Svi117747 if (_sip_msg->sip_msg_old_buf != NULL) 862882Svi117747 free(_sip_msg->sip_msg_old_buf); 872882Svi117747 882882Svi117747 while (_sip_msg->sip_msg_req_res != NULL) { 892882Svi117747 sip_message_type_t *sip_msg_type_ptr; 902882Svi117747 912882Svi117747 sip_msg_type_ptr = _sip_msg->sip_msg_req_res->sip_next; 922882Svi117747 if (_sip_msg->sip_msg_req_res->is_request) { 932882Svi117747 sip_request_t *reqline; 942882Svi117747 952882Svi117747 reqline = &_sip_msg->sip_msg_req_res->U.sip_request; 962882Svi117747 if (reqline->sip_parse_uri != NULL) { 972882Svi117747 sip_free_parsed_uri(reqline->sip_parse_uri); 982882Svi117747 reqline->sip_parse_uri = NULL; 992882Svi117747 } 1002882Svi117747 } 1012882Svi117747 free(_sip_msg->sip_msg_req_res); 1022882Svi117747 _sip_msg->sip_msg_req_res = sip_msg_type_ptr; 1032882Svi117747 } 1042882Svi117747 (void) pthread_mutex_destroy(&_sip_msg->sip_msg_mutex); 1052882Svi117747 free(_sip_msg); 1062882Svi117747 } 1072882Svi117747 1082882Svi117747 /* 1092882Svi117747 * Free a sip msg struct. 1102882Svi117747 */ 1112882Svi117747 void 1122882Svi117747 sip_free_msg(sip_msg_t sip_msg) 1132882Svi117747 { 1142882Svi117747 if (sip_msg == NULL) 1152882Svi117747 return; 1162882Svi117747 1172882Svi117747 SIP_MSG_REFCNT_DECR((_sip_msg_t *)sip_msg); 1182882Svi117747 } 1192882Svi117747 1202882Svi117747 /* 1212882Svi117747 * Hold a sip msg struct. 1222882Svi117747 */ 1232882Svi117747 void 1242882Svi117747 sip_hold_msg(sip_msg_t sip_msg) 1252882Svi117747 { 1262882Svi117747 1272882Svi117747 if (sip_msg == NULL) 1282882Svi117747 return; 1292882Svi117747 1302882Svi117747 SIP_MSG_REFCNT_INCR((_sip_msg_t *)sip_msg); 1312882Svi117747 } 1322882Svi117747 1332882Svi117747 /* 1342882Svi117747 * Clone a message 1352882Svi117747 */ 1362882Svi117747 sip_msg_t 1372882Svi117747 sip_clone_msg(sip_msg_t sip_msg) 1382882Svi117747 { 1392882Svi117747 _sip_msg_t *new_msg; 1402882Svi117747 _sip_msg_t *_sip_msg; 1412882Svi117747 sip_content_t *sip_content; 1422882Svi117747 sip_content_t *msg_content; 1432882Svi117747 sip_content_t *new_content = NULL; 1442882Svi117747 int len; 1452882Svi117747 1462882Svi117747 if (sip_msg == NULL) 1472882Svi117747 return (NULL); 1482882Svi117747 new_msg = (_sip_msg_t *)sip_new_msg(); 1492882Svi117747 if (new_msg == NULL) 1502882Svi117747 return (NULL); 1512882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 1522882Svi117747 /* 1532882Svi117747 * Get start line 1542882Svi117747 */ 1552882Svi117747 if (sip_copy_start_line(_sip_msg, new_msg) != 0) { 1562882Svi117747 sip_free_msg((sip_msg_t)new_msg); 1572882Svi117747 return (NULL); 1582882Svi117747 } 1592882Svi117747 if (sip_copy_all_headers(_sip_msg, new_msg) != 0) { 1602882Svi117747 sip_free_msg((sip_msg_t)new_msg); 1612882Svi117747 return (NULL); 1622882Svi117747 } 1632882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 1642882Svi117747 sip_content = _sip_msg->sip_msg_content; 1652882Svi117747 while (sip_content != NULL) { 1662882Svi117747 msg_content = calloc(1, sizeof (sip_content_t)); 1672882Svi117747 if (msg_content == NULL) { 1682882Svi117747 sip_free_msg((sip_msg_t)new_msg); 1692882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 1702882Svi117747 return (NULL); 1712882Svi117747 } 1722882Svi117747 len = sip_content->sip_content_end - 1732882Svi117747 sip_content->sip_content_start; 1742882Svi117747 msg_content->sip_content_start = malloc(len + 1); 1752882Svi117747 if (msg_content->sip_content_start == NULL) { 1762882Svi117747 sip_free_msg((sip_msg_t)new_msg); 1772882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 1782882Svi117747 return (NULL); 1792882Svi117747 } 1802882Svi117747 (void) strncpy(msg_content->sip_content_start, 1812882Svi117747 sip_content->sip_content_start, len); 1822882Svi117747 msg_content->sip_content_start[len] = '\0'; 1832882Svi117747 msg_content->sip_content_current = 1842882Svi117747 msg_content->sip_content_start; 1852882Svi117747 msg_content->sip_content_end = msg_content->sip_content_start + 1862882Svi117747 len; 1872882Svi117747 msg_content->sip_content_allocated = B_TRUE; 1882882Svi117747 new_msg->sip_msg_content_len += len; 1892882Svi117747 new_msg->sip_msg_len += len; 1902882Svi117747 if (new_msg->sip_msg_content == NULL) 1912882Svi117747 new_msg->sip_msg_content = msg_content; 1922882Svi117747 else 1932882Svi117747 new_content->sip_content_next = msg_content; 1942882Svi117747 new_content = msg_content; 1952882Svi117747 sip_content = sip_content->sip_content_next; 1962882Svi117747 } 1972882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 1982882Svi117747 /* 1992882Svi117747 * Since this is a new message, no threads should be referring 2002882Svi117747 * to this, so it is not necessary to take the lock, however, 2012882Svi117747 * since sip_msg_to_msgbuf() expects the lock to be held, we'll 2022882Svi117747 * take it here. 2032882Svi117747 */ 2042882Svi117747 (void) pthread_mutex_lock(&new_msg->sip_msg_mutex); 2052882Svi117747 new_msg->sip_msg_buf = sip_msg_to_msgbuf((sip_msg_t)new_msg, NULL); 2062882Svi117747 if (new_msg->sip_msg_buf == NULL) { 2072882Svi117747 (void) pthread_mutex_unlock(&new_msg->sip_msg_mutex); 2082882Svi117747 sip_free_msg((sip_msg_t)new_msg); 2092882Svi117747 return (NULL); 2102882Svi117747 } 2112882Svi117747 new_msg->sip_msg_cannot_be_modified = B_TRUE; 2122882Svi117747 (void) pthread_mutex_unlock(&new_msg->sip_msg_mutex); 2132882Svi117747 2142882Svi117747 return ((sip_msg_t)new_msg); 2152882Svi117747 } 2162882Svi117747 2172882Svi117747 /* 2182882Svi117747 * Return the SIP message as a string. Caller frees the string 2192882Svi117747 */ 2202882Svi117747 char * 2212882Svi117747 sip_msg_to_str(sip_msg_t sip_msg, int *error) 2222882Svi117747 { 2232882Svi117747 _sip_msg_t *msg; 2242882Svi117747 char *msgstr; 2252882Svi117747 2262882Svi117747 if (sip_msg == NULL) { 2272882Svi117747 if (error != NULL) 2282882Svi117747 *error = EINVAL; 2292882Svi117747 return (NULL); 2302882Svi117747 } 2312882Svi117747 msg = (_sip_msg_t *)sip_msg; 2322882Svi117747 (void) pthread_mutex_lock(&msg->sip_msg_mutex); 2332882Svi117747 msgstr = sip_msg_to_msgbuf(msg, error); 2342882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 2352882Svi117747 return (msgstr); 2362882Svi117747 } 2372882Svi117747 2382882Svi117747 /* 2392882Svi117747 * Given a message generate a string that includes all the headers and the 2402882Svi117747 * content. 2412882Svi117747 */ 2422882Svi117747 char * 2432882Svi117747 sip_msg_to_msgbuf(_sip_msg_t *msg, int *error) 2442882Svi117747 { 2452882Svi117747 _sip_header_t *header; 2462882Svi117747 int len = 0; 2472882Svi117747 char *p; 2482882Svi117747 char *e; 2492882Svi117747 sip_content_t *sip_content; 2502882Svi117747 #ifdef _DEBUG 2512882Svi117747 int tlen = 0; 2522882Svi117747 int clen = 0; 2532882Svi117747 #endif 2542882Svi117747 2552882Svi117747 if (error != NULL) 2562882Svi117747 *error = 0; 2572882Svi117747 2582882Svi117747 if (msg == NULL) { 2592882Svi117747 if (error != NULL) 2602882Svi117747 *error = EINVAL; 2612882Svi117747 return (NULL); 2622882Svi117747 } 2632882Svi117747 #ifdef __solaris__ 2642882Svi117747 assert(mutex_held(&msg->sip_msg_mutex)); 2652882Svi117747 #endif 2662882Svi117747 2672882Svi117747 p = (char *)malloc(msg->sip_msg_len + 1); 2682882Svi117747 if (p == NULL) { 2692882Svi117747 if (error != 0) 2702882Svi117747 *error = ENOMEM; 2712882Svi117747 return (NULL); 2722882Svi117747 } 2732882Svi117747 e = p; 2742882Svi117747 2752882Svi117747 /* 2762882Svi117747 * Get the start line 2772882Svi117747 */ 2782882Svi117747 if (msg->sip_msg_start_line != NULL) { 2792882Svi117747 len = msg->sip_msg_start_line->sip_hdr_end - 2802882Svi117747 msg->sip_msg_start_line->sip_hdr_start; 2812882Svi117747 (void) strncpy(e, msg->sip_msg_start_line->sip_hdr_start, len); 2822882Svi117747 e += len; 2832882Svi117747 #ifdef _DEBUG 2842882Svi117747 tlen += len; 2852882Svi117747 #endif 2862882Svi117747 } 2872882Svi117747 header = sip_search_for_header(msg, NULL, NULL); 2882882Svi117747 while (header != NULL) { 2892882Svi117747 if (header->sip_header_state != SIP_HEADER_DELETED) { 2902882Svi117747 if (header->sip_header_state == 2912882Svi117747 SIP_HEADER_DELETED_VAL) { 2922882Svi117747 len = sip_copy_values(e, header); 2932882Svi117747 } else { 2942882Svi117747 len = header->sip_hdr_end - 2952882Svi117747 header->sip_hdr_start; 2962882Svi117747 (void) strncpy(e, header->sip_hdr_start, len); 2972882Svi117747 } 2982882Svi117747 #ifdef _DEBUG 2992882Svi117747 tlen += len; 3002882Svi117747 assert(tlen <= msg->sip_msg_len); 3012882Svi117747 #endif 3022882Svi117747 } 3032882Svi117747 header = sip_search_for_header(msg, NULL, header); 3042882Svi117747 e += len; 3052882Svi117747 } 3062882Svi117747 sip_content = msg->sip_msg_content; 3072882Svi117747 while (sip_content != NULL) { 3082882Svi117747 len = sip_content->sip_content_end - 3092882Svi117747 sip_content->sip_content_start; 3102882Svi117747 #ifdef _DEBUG 3112882Svi117747 clen += len; 3122882Svi117747 assert(clen <= msg->sip_msg_content_len); 3132882Svi117747 tlen += len; 3142882Svi117747 assert(tlen <= msg->sip_msg_len); 3152882Svi117747 #endif 3162882Svi117747 (void) strncpy(e, sip_content->sip_content_start, len); 3172882Svi117747 e += len; 3182882Svi117747 sip_content = sip_content->sip_content_next; 3192882Svi117747 } 3202882Svi117747 p[msg->sip_msg_len] = '\0'; 3212882Svi117747 return (p); 3222882Svi117747 } 3232882Svi117747 3242882Svi117747 /* 3252882Svi117747 * This is called just before sending the message to the transport. It 3262882Svi117747 * creates the sip_msg_buf from the SIP headers. 3272882Svi117747 */ 3282882Svi117747 int 3292882Svi117747 sip_adjust_msgbuf(_sip_msg_t *msg) 3302882Svi117747 { 3312882Svi117747 _sip_header_t *header; 3322882Svi117747 int ret; 3332882Svi117747 #ifdef _DEBUG 3342882Svi117747 int tlen = 0; 3352882Svi117747 int clen = 0; 3362882Svi117747 #endif 3372882Svi117747 3382882Svi117747 if (msg == NULL) 3392882Svi117747 return (EINVAL); 3402882Svi117747 3412882Svi117747 (void) pthread_mutex_lock(&msg->sip_msg_mutex); 3422882Svi117747 if ((msg->sip_msg_buf != NULL) && (!msg->sip_msg_modified)) { 3432882Svi117747 /* 3442882Svi117747 * We could just be forwarding the message we 3452882Svi117747 * received. 3462882Svi117747 */ 3472882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 3482882Svi117747 return (0); 3492882Svi117747 } 3502882Svi117747 3512882Svi117747 /* 3522882Svi117747 * We are sending a new message or a message that we received 3532882Svi117747 * but have modified it. We keep the old 3542882Svi117747 * msgbuf till the message is freed as some 3552882Svi117747 * headers still point to it. 3562882Svi117747 */ 3572882Svi117747 3582882Svi117747 assert(msg->sip_msg_old_buf == NULL); 3592882Svi117747 msg->sip_msg_old_buf = msg->sip_msg_buf; 3602882Svi117747 /* 3612882Svi117747 * We add the content-length header here, if it has not 3622882Svi117747 * already been added. 3632882Svi117747 */ 3642882Svi117747 header = sip_search_for_header(msg, SIP_CONTENT_LENGTH, NULL); 3652882Svi117747 if (header != NULL) { 3662882Svi117747 /* 3672882Svi117747 * Mark the previous header as deleted. 3682882Svi117747 */ 3692882Svi117747 header->sip_header_state = SIP_HEADER_DELETED; 3702882Svi117747 header->sip_hdr_sipmsg->sip_msg_len -= header->sip_hdr_end - 3712882Svi117747 header->sip_hdr_start; 3722882Svi117747 } 3732882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 3742882Svi117747 ret = sip_add_content_length(msg, msg->sip_msg_content_len); 3752882Svi117747 if (ret != 0) { 3762882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 3772882Svi117747 return (ret); 3782882Svi117747 } 3792882Svi117747 (void) pthread_mutex_lock(&msg->sip_msg_mutex); 3802882Svi117747 msg->sip_msg_modified = B_FALSE; 3812882Svi117747 3822882Svi117747 msg->sip_msg_buf = sip_msg_to_msgbuf((sip_msg_t)msg, &ret); 3832882Svi117747 if (msg->sip_msg_buf == NULL) { 3842882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 3852882Svi117747 return (ret); 3862882Svi117747 } 3872882Svi117747 /* 3882882Svi117747 * Once the message has been sent it can not be modified 3892882Svi117747 * any furthur as we keep a pointer to it for retransmission 3902882Svi117747 */ 3912882Svi117747 msg->sip_msg_cannot_be_modified = B_TRUE; 3922882Svi117747 3932882Svi117747 (void) pthread_mutex_unlock(&msg->sip_msg_mutex); 3942882Svi117747 return (0); 3952882Svi117747 } 3962882Svi117747 3972882Svi117747 /* 3982882Svi117747 * Copy header values into ptr 3992882Svi117747 */ 4002882Svi117747 int 4012882Svi117747 sip_copy_values(char *ptr, _sip_header_t *header) 4022882Svi117747 { 4032882Svi117747 sip_header_value_t value; 4042882Svi117747 int tlen = 0; 4052882Svi117747 int len = 0; 4062882Svi117747 boolean_t first = B_TRUE; 4072882Svi117747 char *p = ptr; 4082882Svi117747 char *s; 4092882Svi117747 boolean_t crlf_present = B_FALSE; 4102882Svi117747 4112882Svi117747 if (sip_parse_goto_values(header) != 0) 4122882Svi117747 return (0); 4132882Svi117747 4142882Svi117747 len = header->sip_hdr_current - header->sip_hdr_start; 4152882Svi117747 (void) strncpy(p, header->sip_hdr_start, len); 4162882Svi117747 tlen += len; 4172882Svi117747 p += len; 4182882Svi117747 value = header->sip_hdr_parsed->value; 4192882Svi117747 while (value != NULL) { 4202882Svi117747 if (value->value_state != SIP_VALUE_DELETED) { 4212882Svi117747 crlf_present = B_FALSE; 4222882Svi117747 len = value->value_end - value->value_start; 4232882Svi117747 if (first) { 4242882Svi117747 (void) strncpy(p, value->value_start, len); 4252882Svi117747 first = B_FALSE; 4262882Svi117747 } else { 4272882Svi117747 s = value->value_start; 4282882Svi117747 while (*s != SIP_COMMA) 4292882Svi117747 s--; 4302882Svi117747 len += value->value_start - s; 4312882Svi117747 (void) strncpy(p, s, len); 4322882Svi117747 } 4332882Svi117747 tlen += len; 4342882Svi117747 p += len; 4352882Svi117747 s = value->value_end; 4362882Svi117747 while (s != value->value_start) { 4372882Svi117747 if (*s == '\r' && strncmp(s, SIP_CRLF, 4382882Svi117747 strlen(SIP_CRLF)) == 0) { 4392882Svi117747 crlf_present = B_TRUE; 4402882Svi117747 break; 4412882Svi117747 } 4422882Svi117747 s--; 4432882Svi117747 } 4442882Svi117747 } else { 4452882Svi117747 if (value->next == NULL && !first && !crlf_present) { 4462882Svi117747 s = value->value_end; 4472882Svi117747 while (*s != '\r') 4482882Svi117747 s--; 4492882Svi117747 len = value->value_end - s; 4502882Svi117747 (void) strncpy(p, s, len); 4512882Svi117747 tlen += len; 4522882Svi117747 p += len; 4532882Svi117747 } 4542882Svi117747 } 4552882Svi117747 value = value->next; 4562882Svi117747 } 4572882Svi117747 return (tlen); 4582882Svi117747 } 4592882Svi117747 4602882Svi117747 4612882Svi117747 /* 4622882Svi117747 * Add content (message body) to sip_msg 4632882Svi117747 */ 4642882Svi117747 int 4652882Svi117747 sip_add_content(sip_msg_t sip_msg, char *content) 4662882Svi117747 { 4672882Svi117747 size_t len; 4682882Svi117747 sip_content_t **loc; 4692882Svi117747 sip_content_t *msg_content; 4702882Svi117747 _sip_msg_t *_sip_msg; 4712882Svi117747 4722882Svi117747 if (sip_msg == NULL || content == NULL || strlen(content) == 0) 4732882Svi117747 return (EINVAL); 4742882Svi117747 len = strlen(content); 4752882Svi117747 _sip_msg = (_sip_msg_t *)sip_msg; 4762882Svi117747 (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); 4772882Svi117747 4782882Svi117747 if (_sip_msg->sip_msg_cannot_be_modified) { 4792882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 4802882Svi117747 return (ENOTSUP); 4812882Svi117747 } 4822882Svi117747 4832882Svi117747 msg_content = calloc(1, sizeof (sip_content_t)); 4842882Svi117747 if (msg_content == NULL) { 4852882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 4862882Svi117747 return (ENOMEM); 4872882Svi117747 } 4882882Svi117747 msg_content->sip_content_start = malloc(strlen(content) + 1); 4892882Svi117747 if (msg_content->sip_content_start == NULL) { 4902882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 4912882Svi117747 free(msg_content); 4922882Svi117747 return (ENOMEM); 4932882Svi117747 } 4942882Svi117747 (void) strncpy(msg_content->sip_content_start, content, 4952882Svi117747 strlen(content)); 4962882Svi117747 msg_content->sip_content_start[strlen(content)] = '\0'; 4972882Svi117747 msg_content->sip_content_current = msg_content->sip_content_start; 4982882Svi117747 msg_content->sip_content_end = msg_content->sip_content_start + 4992882Svi117747 strlen(msg_content->sip_content_start); 5002882Svi117747 msg_content->sip_content_allocated = B_TRUE; 5012882Svi117747 5022882Svi117747 loc = &_sip_msg->sip_msg_content; 5032882Svi117747 while (*loc != NULL) 5042882Svi117747 loc = &((*loc)->sip_content_next); 5052882Svi117747 *loc = msg_content; 5062882Svi117747 5072882Svi117747 _sip_msg->sip_msg_content_len += len; 5082882Svi117747 _sip_msg->sip_msg_len += len; 5092882Svi117747 if (_sip_msg->sip_msg_buf != NULL) 5102882Svi117747 _sip_msg->sip_msg_modified = B_TRUE; 5112882Svi117747 (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); 5122882Svi117747 return (0); 5132882Svi117747 } 5142882Svi117747 5152882Svi117747 /* 5162882Svi117747 * Free the message content 5172882Svi117747 */ 5182882Svi117747 void 5192882Svi117747 sip_free_content(_sip_msg_t *sip_msg) 5202882Svi117747 { 5212882Svi117747 sip_content_t *content; 5222882Svi117747 5232882Svi117747 if (sip_msg == NULL) 5242882Svi117747 return; 5252882Svi117747 content = sip_msg->sip_msg_content; 5262882Svi117747 while (content != NULL) { 5272882Svi117747 sip_content_t *content_tmp; 5282882Svi117747 5292882Svi117747 content_tmp = content; 5302882Svi117747 content = content->sip_content_next; 5312882Svi117747 if (content_tmp->sip_content_allocated) 5322882Svi117747 free(content_tmp->sip_content_start); 5332882Svi117747 free(content_tmp); 5342882Svi117747 } 5352882Svi117747 sip_msg->sip_msg_content = NULL; 5362882Svi117747 } 5372882Svi117747 5382882Svi117747 5392882Svi117747 /* 5402882Svi117747 * Add a response line to sip_response 5412882Svi117747 */ 5422882Svi117747 int 5432882Svi117747 sip_add_response_line(sip_msg_t sip_response, int response, char *response_code) 5442882Svi117747 { 5452882Svi117747 _sip_header_t *new_header; 5462882Svi117747 int header_size; 5472882Svi117747 _sip_msg_t *_sip_response; 5482882Svi117747 int ret; 5492882Svi117747 5502882Svi117747 if (sip_response == NULL || response < 0 || response_code == NULL) 5512882Svi117747 return (EINVAL); 5522882Svi117747 _sip_response = (_sip_msg_t *)sip_response; 5532882Svi117747 (void) pthread_mutex_lock(&_sip_response->sip_msg_mutex); 5542882Svi117747 if (_sip_response->sip_msg_cannot_be_modified) { 5552882Svi117747 (void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex); 5562882Svi117747 return (ENOTSUP); 5572882Svi117747 } 5582882Svi117747 header_size = strlen(SIP_VERSION) + SIP_SPACE_LEN + 5592882Svi117747 SIP_SIZE_OF_STATUS_CODE + SIP_SPACE_LEN + strlen(response_code) + 5602882Svi117747 strlen(SIP_CRLF); 5612882Svi117747 5622882Svi117747 new_header = sip_new_header(header_size); 5632882Svi117747 if (new_header == NULL) { 5642882Svi117747 (void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex); 5652882Svi117747 return (ENOMEM); 5662882Svi117747 } 5672882Svi117747 new_header->sip_hdr_sipmsg = _sip_response; 5682882Svi117747 5692882Svi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 5702882Svi117747 SIP_RESPONSE, SIP_VERSION, response, response_code, SIP_CRLF); 5712882Svi117747 5722882Svi117747 new_header->sip_hdr_next = _sip_response->sip_msg_start_line; 5732882Svi117747 _sip_response->sip_msg_start_line = new_header; 5742882Svi117747 _sip_response->sip_msg_len += header_size; 5752882Svi117747 ret = sip_parse_first_line(_sip_response->sip_msg_start_line, 5762882Svi117747 &_sip_response->sip_msg_req_res); 5772882Svi117747 if (_sip_response->sip_msg_buf != NULL) 5782882Svi117747 _sip_response->sip_msg_modified = B_TRUE; 5792882Svi117747 (void) pthread_mutex_unlock(&_sip_response->sip_msg_mutex); 5802882Svi117747 return (ret); 5812882Svi117747 } 5822882Svi117747 5832882Svi117747 /* 5842882Svi117747 * create a response based on the sip_request. 5852882Svi117747 * Copies Call-ID, CSeq, From, To and Via headers from the request. 5862882Svi117747 */ 5872882Svi117747 sip_msg_t 5882882Svi117747 sip_create_response(sip_msg_t sip_request, int response, char *response_code, 5892882Svi117747 char *totag, char *mycontact) 5902882Svi117747 { 5912882Svi117747 _sip_msg_t *new_msg; 5922882Svi117747 _sip_msg_t *_sip_request; 5932882Svi117747 boolean_t ttag_present; 5942882Svi117747 5952882Svi117747 if (sip_request == NULL || response_code == NULL) 5962882Svi117747 return (NULL); 5972882Svi117747 5982882Svi117747 ttag_present = sip_get_to_tag(sip_request, NULL) != NULL; 5992882Svi117747 6002882Svi117747 new_msg = (_sip_msg_t *)sip_new_msg(); 6012882Svi117747 if (new_msg == NULL) 6022882Svi117747 return (NULL); 6032882Svi117747 _sip_request = (_sip_msg_t *)sip_request; 6042882Svi117747 6052882Svi117747 (void) pthread_mutex_lock(&_sip_request->sip_msg_mutex); 6062882Svi117747 6072882Svi117747 /* 6082882Svi117747 * Add response line. 6092882Svi117747 */ 6102882Svi117747 if (sip_add_response_line(new_msg, response, response_code) != 0) 6112882Svi117747 goto error; 6122882Svi117747 6132882Svi117747 /* 6142882Svi117747 * Copy Via headers 6152882Svi117747 */ 6162882Svi117747 if (_sip_find_and_copy_all_header(_sip_request, new_msg, SIP_VIA) != 0) 6172882Svi117747 goto error; 6182882Svi117747 6192882Svi117747 /* 6202882Svi117747 * Copy From header. 6212882Svi117747 */ 6222882Svi117747 if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_FROM, 6232882Svi117747 NULL, B_FALSE)) { 6242882Svi117747 goto error; 6252882Svi117747 } 6262882Svi117747 /* 6272882Svi117747 * Copy To header. If To tag is present, copy it, if not then 6282882Svi117747 * add one if the repsonse is not provisional. 6292882Svi117747 */ 6302882Svi117747 if (ttag_present || (totag == NULL && response == SIP_TRYING)) { 6312882Svi117747 if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_TO, 6322882Svi117747 NULL, B_FALSE)) { 6332882Svi117747 goto error; 6342882Svi117747 } 6352882Svi117747 } else { 6362882Svi117747 char *xtra_param; 6372882Svi117747 boolean_t tag_alloc = B_FALSE; 6382882Svi117747 int taglen; 6392882Svi117747 6402882Svi117747 if (totag == NULL) { 6412882Svi117747 totag = sip_guid(); 6422882Svi117747 if (totag == NULL) 6432882Svi117747 goto error; 6442882Svi117747 tag_alloc = B_TRUE; 6452882Svi117747 } 6462882Svi117747 taglen = strlen(SIP_TAG) + strlen(totag) + 1; 6472882Svi117747 xtra_param = (char *)malloc(taglen); 6482882Svi117747 if (xtra_param == NULL) { 6492882Svi117747 if (tag_alloc) 6502882Svi117747 free(totag); 6512882Svi117747 goto error; 6522882Svi117747 } 6532882Svi117747 (void) snprintf(xtra_param, taglen, "%s%s", SIP_TAG, totag); 6542882Svi117747 if (tag_alloc) 6552882Svi117747 free(totag); 6562882Svi117747 if (_sip_find_and_copy_header(_sip_request, new_msg, 6572882Svi117747 SIP_TO, xtra_param, B_FALSE)) { 6582882Svi117747 free(xtra_param); 6592882Svi117747 goto error; 6602882Svi117747 } 6612882Svi117747 free(xtra_param); 6622882Svi117747 } 6632882Svi117747 6642882Svi117747 /* 6652882Svi117747 * Copy Call-ID header. 6662882Svi117747 */ 6672882Svi117747 if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_CALL_ID, NULL, 6682882Svi117747 B_FALSE)) { 6692882Svi117747 goto error; 6702882Svi117747 } 6712882Svi117747 /* 6722882Svi117747 * Copy CSEQ header 6732882Svi117747 */ 6742882Svi117747 if (_sip_find_and_copy_header(_sip_request, new_msg, SIP_CSEQ, NULL, 6752882Svi117747 B_FALSE)) { 6762882Svi117747 goto error; 6772882Svi117747 } 6782882Svi117747 /* 6792882Svi117747 * Copy RECORD-ROUTE header, if present. 6802882Svi117747 */ 6812882Svi117747 if (sip_search_for_header(_sip_request, SIP_RECORD_ROUTE, NULL) != 6822882Svi117747 NULL) { 6832882Svi117747 if (_sip_find_and_copy_all_header(_sip_request, new_msg, 6842882Svi117747 SIP_RECORD_ROUTE) != 0) { 6852882Svi117747 goto error; 6862882Svi117747 } 6872882Svi117747 } 6882882Svi117747 if (mycontact != NULL) { 6892882Svi117747 if (sip_add_contact(new_msg, NULL, mycontact, B_FALSE, 6902882Svi117747 NULL) != 0) { 6912882Svi117747 goto error; 6922882Svi117747 } 6932882Svi117747 } 6942882Svi117747 (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); 6952882Svi117747 return ((sip_msg_t)new_msg); 6962882Svi117747 error: 6972882Svi117747 sip_free_msg((sip_msg_t)new_msg); 6982882Svi117747 (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); 6992882Svi117747 return (NULL); 7002882Svi117747 } 7012882Svi117747 7022882Svi117747 /* 7032882Svi117747 * NON OK ACK : MUST contain values for the Call-ID, From, and Request-URI 7042882Svi117747 * that are equal to the values of those header fields in the orig request 7052882Svi117747 * passed to the transport. The To header field in the ACK MUST equal the To 7062882Svi117747 * header field in the response being acknowledged. The ACK MUST contain the 7072882Svi117747 * top Via header field of the original request. The CSeq header field in 7082882Svi117747 * the ACK MUST contain the same value for the sequence number as was 7092882Svi117747 * present in the original request, but the method parameter MUST be equal 7102882Svi117747 * to "ACK". 7112882Svi117747 */ 7122882Svi117747 int 7132882Svi117747 sip_create_nonOKack(sip_msg_t request, sip_msg_t response, sip_msg_t ack_msg) 7142882Svi117747 { 7152882Svi117747 int seqno; 7162882Svi117747 char *uri; 7172882Svi117747 _sip_msg_t *_request; 7182882Svi117747 _sip_msg_t *_response; 7192882Svi117747 _sip_msg_t *_ack_msg; 7202882Svi117747 int ret; 7212882Svi117747 7222882Svi117747 if (request == NULL || response == NULL || ack_msg == NULL || 7232882Svi117747 request == ack_msg) { 7242882Svi117747 return (EINVAL); 7252882Svi117747 } 7262882Svi117747 _request = (_sip_msg_t *)request; 7272882Svi117747 _response = (_sip_msg_t *)response; 7282882Svi117747 _ack_msg = (_sip_msg_t *)ack_msg; 7292882Svi117747 7302882Svi117747 (void) pthread_mutex_lock(&_request->sip_msg_mutex); 7312882Svi117747 if (_request->sip_msg_req_res == NULL) { 7322882Svi117747 if ((ret = sip_parse_first_line(_request->sip_msg_start_line, 7332882Svi117747 &_request->sip_msg_req_res)) != 0) { 7342882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7352882Svi117747 return (ret); 7362882Svi117747 } 7372882Svi117747 } 7382882Svi117747 if (_request->sip_msg_req_res->U.sip_request.sip_request_uri. 7392882Svi117747 sip_str_ptr == NULL) { 7402882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7412882Svi117747 return (EINVAL); 7422882Svi117747 } 7432882Svi117747 uri = (char *)malloc(_request->sip_msg_req_res->U.sip_request. 7442882Svi117747 sip_request_uri.sip_str_len + 1); 7452882Svi117747 if (uri == NULL) { 7462882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7472882Svi117747 return (EINVAL); 7482882Svi117747 } 7492882Svi117747 (void) strncpy(uri, 7502882Svi117747 _request->sip_msg_req_res->U.sip_request.sip_request_uri. 7512882Svi117747 sip_str_ptr, _request->sip_msg_req_res->U.sip_request. 7522882Svi117747 sip_request_uri.sip_str_len); 7532882Svi117747 uri[_request->sip_msg_req_res->U.sip_request. 7542882Svi117747 sip_request_uri.sip_str_len] = '\0'; 7552882Svi117747 if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) { 7562882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7572882Svi117747 return (ret); 7582882Svi117747 } 7592882Svi117747 free(uri); 7602882Svi117747 if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_VIA, 7612882Svi117747 NULL, B_TRUE)) != 0) { 7622882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7632882Svi117747 return (ret); 7642882Svi117747 } 7652882Svi117747 (void) _sip_find_and_copy_header(_request, _ack_msg, 7662882Svi117747 SIP_MAX_FORWARDS, NULL, B_TRUE); 7672882Svi117747 7682882Svi117747 (void) pthread_mutex_lock(&_response->sip_msg_mutex); 7692882Svi117747 if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO, 7702882Svi117747 NULL, B_TRUE)) != 0) { 7712882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 7722882Svi117747 return (ret); 7732882Svi117747 } 7742882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 7752882Svi117747 if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_FROM, 7762882Svi117747 NULL, B_TRUE)) != 0) { 7772882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7782882Svi117747 return (ret); 7792882Svi117747 } 7802882Svi117747 if ((ret = _sip_find_and_copy_header(_request, _ack_msg, SIP_CALL_ID, 7812882Svi117747 NULL, B_TRUE)) != 0) { 7822882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7832882Svi117747 return (ret); 7842882Svi117747 } 7852882Svi117747 (void) pthread_mutex_unlock(&_request->sip_msg_mutex); 7862882Svi117747 seqno = sip_get_callseq_num(_request, &ret); 7872882Svi117747 if (ret != 0) 7882882Svi117747 return (ret); 7892882Svi117747 if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0) 7902882Svi117747 return (ret); 7912882Svi117747 if ((ret = sip_adjust_msgbuf(_ack_msg)) != 0) 7922882Svi117747 return (ret); 7932882Svi117747 return (0); 7942882Svi117747 } 7952882Svi117747 7962882Svi117747 /* 7972882Svi117747 * This is a 2XX ACK, for others ACK is constructed differently, 7982882Svi117747 * esp. the branch id is retained. 7992882Svi117747 */ 8002882Svi117747 int 8012882Svi117747 sip_create_OKack(sip_msg_t response, sip_msg_t ack_msg, char *transport, 8022882Svi117747 char *sent_by, int sent_by_port, char *via_params) 8032882Svi117747 { 8042882Svi117747 int seqno; 8052882Svi117747 char *uri; 8062882Svi117747 sip_parsed_header_t *parsed_header; 8072882Svi117747 sip_hdr_value_t *contact_value; 8082882Svi117747 _sip_header_t *header; 8092882Svi117747 _sip_msg_t *_response; 8102882Svi117747 _sip_msg_t *_ack_msg; 8112882Svi117747 int ret; 8122882Svi117747 8132882Svi117747 if (response == NULL || response == NULL || transport == NULL) 8142882Svi117747 return (EINVAL); 8152882Svi117747 _response = (_sip_msg_t *)response; 8162882Svi117747 _ack_msg = (_sip_msg_t *)ack_msg; 8172882Svi117747 8182882Svi117747 /* 8192882Svi117747 * Get URI from the response, Contact field 8202882Svi117747 */ 8212882Svi117747 (void) pthread_mutex_lock(&_response->sip_msg_mutex); 8222882Svi117747 if ((header = sip_search_for_header(_response, SIP_CONTACT, 8232882Svi117747 NULL)) == NULL) { 8242882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8252882Svi117747 return (EINVAL); 8262882Svi117747 } 8272882Svi117747 if ((ret = sip_parse_cftr_header(header, (void *)&parsed_header)) != 8282882Svi117747 0) { 8292882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8302882Svi117747 return (ret); 8312882Svi117747 } 8322882Svi117747 contact_value = (sip_hdr_value_t *)parsed_header->value; 8332882Svi117747 if (contact_value->cftr_uri.sip_str_ptr == NULL) { 8342882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8352882Svi117747 return (EINVAL); 8362882Svi117747 } 8372882Svi117747 uri = (char *)malloc(contact_value->cftr_uri.sip_str_len + 1); 8382882Svi117747 if (uri == NULL) { 8392882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8402882Svi117747 return (ENOMEM); 8412882Svi117747 } 8422882Svi117747 (void) strncpy(uri, contact_value->cftr_uri.sip_str_ptr, 8432882Svi117747 contact_value->cftr_uri.sip_str_len); 8442882Svi117747 uri[contact_value->cftr_uri.sip_str_len] = '\0'; 8452882Svi117747 if ((ret = sip_add_request_line(_ack_msg, ACK, uri)) != 0) { 8462882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8472882Svi117747 return (ret); 8482882Svi117747 } 8492882Svi117747 free(uri); 8502882Svi117747 if ((ret = sip_add_via(_ack_msg, transport, sent_by, sent_by_port, 8512882Svi117747 via_params)) != 0) { 8522882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8532882Svi117747 return (ret); 8542882Svi117747 } 8552882Svi117747 8562882Svi117747 if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_TO, 8572882Svi117747 NULL, B_TRUE)) != 0) { 8582882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8592882Svi117747 return (ret); 8602882Svi117747 } 8612882Svi117747 if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_FROM, 8622882Svi117747 NULL, B_TRUE)) != 0) { 8632882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8642882Svi117747 return (ret); 8652882Svi117747 } 8662882Svi117747 if ((ret = _sip_find_and_copy_header(_response, _ack_msg, SIP_CALL_ID, 8672882Svi117747 NULL, B_TRUE)) != 0) { 8682882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8692882Svi117747 return (ret); 8702882Svi117747 } 8712882Svi117747 /* 8722882Svi117747 * Copy Max-Forward if present 8732882Svi117747 */ 8742882Svi117747 if (sip_search_for_header(_response, SIP_MAX_FORWARDS, NULL) != NULL) { 8752882Svi117747 if ((ret = _sip_find_and_copy_header(_response, _ack_msg, 8762882Svi117747 SIP_MAX_FORWARDS, NULL, B_TRUE)) != 0) { 8772882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8782882Svi117747 return (ret); 8792882Svi117747 } 8802882Svi117747 } 8812882Svi117747 (void) pthread_mutex_unlock(&_response->sip_msg_mutex); 8822882Svi117747 seqno = sip_get_callseq_num(_response, &ret); 8832882Svi117747 if (ret != 0) 8842882Svi117747 return (ret); 8852882Svi117747 if ((ret = sip_add_cseq(_ack_msg, ACK, seqno)) != 0) 8862882Svi117747 return (ret); 8872882Svi117747 8882882Svi117747 return (0); 8892882Svi117747 } 8902882Svi117747 8912882Svi117747 /* 8922882Svi117747 * Request-Line = Method SP Request-URI SP SIP-Version CRLF 8932882Svi117747 */ 8942882Svi117747 int 8952882Svi117747 sip_add_request_line(sip_msg_t sip_request, sip_method_t method, 8962882Svi117747 char *request_uri) 8972882Svi117747 { 8982882Svi117747 _sip_header_t *new_header; 8992882Svi117747 int header_size; 9002882Svi117747 _sip_msg_t *_sip_request; 9012882Svi117747 9022882Svi117747 if (method < INVITE || method >= MAX_SIP_METHODS || 9032882Svi117747 request_uri == NULL || sip_request == NULL) { 9042882Svi117747 return (EINVAL); 9052882Svi117747 } 9062882Svi117747 9072882Svi117747 _sip_request = (_sip_msg_t *)sip_request; 9082882Svi117747 (void) pthread_mutex_lock(&_sip_request->sip_msg_mutex); 9092882Svi117747 if (_sip_request->sip_msg_cannot_be_modified) { 9102882Svi117747 (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); 9112882Svi117747 return (ENOTSUP); 9122882Svi117747 } 9132882Svi117747 9142882Svi117747 header_size = strlen(sip_methods[method].name) + SIP_SPACE_LEN + 9152882Svi117747 strlen(request_uri) + SIP_SPACE_LEN + strlen(SIP_VERSION) + 9162882Svi117747 strlen(SIP_CRLF); 9172882Svi117747 9182882Svi117747 new_header = sip_new_header(header_size); 9192882Svi117747 if (new_header == NULL) { 9202882Svi117747 (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); 9212882Svi117747 return (ENOMEM); 9222882Svi117747 } 9232882Svi117747 new_header->sip_hdr_sipmsg = _sip_request; 9242882Svi117747 9252882Svi117747 (void) snprintf(new_header->sip_hdr_start, header_size + 1, 9262882Svi117747 "%s %s %s%s", sip_methods[method].name, request_uri, 9272882Svi117747 SIP_VERSION, SIP_CRLF); 9282882Svi117747 9292882Svi117747 new_header->sip_hdr_next = _sip_request->sip_msg_start_line; 9302882Svi117747 _sip_request->sip_msg_start_line = new_header; 9312882Svi117747 _sip_request->sip_msg_len += header_size; 9322882Svi117747 (void) sip_parse_first_line(_sip_request->sip_msg_start_line, 9332882Svi117747 &_sip_request->sip_msg_req_res); 9342882Svi117747 if (_sip_request->sip_msg_buf != NULL) 9352882Svi117747 _sip_request->sip_msg_modified = B_TRUE; 9362882Svi117747 (void) pthread_mutex_unlock(&_sip_request->sip_msg_mutex); 9372882Svi117747 return (0); 9382882Svi117747 } 939