4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include "sip_miscdefs.h"
39 * Local version of case insensitive strstr().
42 sip_reass_strstr(const char *as1
, const char *as2
)
52 if (s2
== NULL
|| *s2
== '\0')
57 if (tolower(*s1
++) == c
) {
59 while ((c
= *++s2
) == tolower(*s1
++) && c
)
62 return ((char *)tptr
- 1);
72 * Get the value in the content-length field and add it to the header length
73 * and return the total length. returns -1 if the length cannot be determined
74 * or if the message does not contain the entire message.
77 sip_get_msglen(char *p
, size_t msglen
)
88 if ((c
= sip_reass_strstr(p
, "content-length")) == NULL
)
91 if ((hlen
+ strlen("content-length")) >= msglen
)
93 c
+= strlen("content-length");
95 while (*e
== ' ' || *e
== ':') {
100 while (*e
!= '\r' && *e
!= ' ') {
103 if (*e
>= '0' && *e
<= '9')
107 value
= (value
* base
) + digits
;
115 hlen
= e
- p
+ 4; /* 4 for 2 CRLFs ?? */
122 * We have determined that msg does not contain a *single* complete message.
123 * Add it to the reassembly list and check if we have a complete message.
124 * a NULL 'msg' means we are just checking if there are more complete
125 * messages in the list that can be passed up.
128 sip_get_tcp_msg(sip_conn_object_t obj
, char *msg
, size_t *msglen
)
131 sip_conn_obj_pvt_t
*pvt_data
;
132 sip_reass_entry_t
*reass
;
140 msgbuf
= (char *)malloc(*msglen
+ 1);
143 (void) strncpy(msgbuf
, msg
, *msglen
);
144 msgbuf
[*msglen
] = '\0';
147 obj_val
= (void *)obj
;
148 pvt_data
= (sip_conn_obj_pvt_t
*)*obj_val
;
150 * connection object not initialized
152 if (pvt_data
== NULL
) {
155 value
= sip_get_msglen(msg
, *msglen
);
156 if (value
== *msglen
) {
164 (void) pthread_mutex_lock(&pvt_data
->sip_conn_obj_reass_lock
);
165 reass
= pvt_data
->sip_conn_obj_reass
;
166 assert(reass
!= NULL
);
167 if (reass
->sip_reass_msg
== NULL
) {
168 assert(reass
->sip_reass_msglen
== 0);
170 (void) pthread_mutex_unlock(
171 &pvt_data
->sip_conn_obj_reass_lock
);
174 value
= sip_get_msglen(msg
, *msglen
);
175 if (value
== *msglen
) {
176 (void) pthread_mutex_unlock(
177 &pvt_data
->sip_conn_obj_reass_lock
);
180 reass
->sip_reass_msg
= msg
;
181 reass
->sip_reass_msglen
= *msglen
;
182 if (value
!= -1 && value
< reass
->sip_reass_msglen
)
184 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
186 } else if (msg
!= NULL
) {
188 * Resize, not optimal
190 int newlen
= reass
->sip_reass_msglen
+ *msglen
;
193 assert(strlen(reass
->sip_reass_msg
) == reass
->sip_reass_msglen
);
194 newmsg
= malloc(newlen
+ 1);
195 if (newmsg
== NULL
) {
196 (void) pthread_mutex_unlock(
197 &pvt_data
->sip_conn_obj_reass_lock
);
202 (void) strncpy(newmsg
, reass
->sip_reass_msg
,
203 reass
->sip_reass_msglen
);
204 newmsg
[reass
->sip_reass_msglen
] = '\0';
205 (void) strncat(newmsg
, msg
, *msglen
);
206 newmsg
[newlen
] = '\0';
207 assert(strlen(newmsg
) == newlen
);
208 reass
->sip_reass_msglen
= newlen
;
210 free(reass
->sip_reass_msg
);
211 reass
->sip_reass_msg
= newmsg
;
213 value
= sip_get_msglen(reass
->sip_reass_msg
, reass
->sip_reass_msglen
);
214 if (value
== -1 || value
> reass
->sip_reass_msglen
) {
215 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
219 if (value
== reass
->sip_reass_msglen
) {
220 msg
= reass
->sip_reass_msg
;
221 *msglen
= reass
->sip_reass_msglen
;
222 reass
->sip_reass_msg
= NULL
;
223 reass
->sip_reass_msglen
= 0;
224 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
227 splitlen
= reass
->sip_reass_msglen
- value
;
228 msg
= (char *)malloc(value
+ 1);
229 splitbuf
= (char *)malloc(splitlen
+ 1);
230 if (msg
== NULL
|| splitbuf
== NULL
) {
233 if (splitbuf
!= NULL
)
235 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
238 (void) strncpy(msg
, reass
->sip_reass_msg
, value
);
240 (void) strncpy(splitbuf
, reass
->sip_reass_msg
+ value
, splitlen
);
241 splitbuf
[splitlen
] = '\0';
242 free(reass
->sip_reass_msg
);
243 reass
->sip_reass_msg
= splitbuf
;
244 reass
->sip_reass_msglen
= splitlen
;
245 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);