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.
34 #include "sip_miscdefs.h"
37 * Local version of case insensitive strstr().
40 sip_reass_strstr(const char *as1
, const char *as2
)
50 if (s2
== NULL
|| *s2
== '\0')
55 if (tolower(*s1
++) == c
) {
57 while ((c
= *++s2
) == tolower(*s1
++) && c
)
60 return ((char *)tptr
- 1);
70 * Get the value in the content-length field and add it to the header length
71 * and return the total length. returns -1 if the length cannot be determined
72 * or if the message does not contain the entire message.
75 sip_get_msglen(char *p
, size_t msglen
)
86 if ((c
= sip_reass_strstr(p
, "content-length")) == NULL
)
89 if ((hlen
+ strlen("content-length")) >= msglen
)
91 c
+= strlen("content-length");
93 while (*e
== ' ' || *e
== ':') {
98 while (*e
!= '\r' && *e
!= ' ') {
101 if (*e
>= '0' && *e
<= '9')
105 value
= (value
* base
) + digits
;
113 hlen
= e
- p
+ 4; /* 4 for 2 CRLFs ?? */
120 * We have determined that msg does not contain a *single* complete message.
121 * Add it to the reassembly list and check if we have a complete message.
122 * a NULL 'msg' means we are just checking if there are more complete
123 * messages in the list that can be passed up.
126 sip_get_tcp_msg(sip_conn_object_t obj
, char *msg
, size_t *msglen
)
129 sip_conn_obj_pvt_t
*pvt_data
;
130 sip_reass_entry_t
*reass
;
138 msgbuf
= (char *)malloc(*msglen
+ 1);
141 (void) strncpy(msgbuf
, msg
, *msglen
);
142 msgbuf
[*msglen
] = '\0';
145 obj_val
= (void *)obj
;
146 pvt_data
= (sip_conn_obj_pvt_t
*)*obj_val
;
148 * connection object not initialized
150 if (pvt_data
== NULL
) {
153 value
= sip_get_msglen(msg
, *msglen
);
154 if (value
== *msglen
) {
161 (void) pthread_mutex_lock(&pvt_data
->sip_conn_obj_reass_lock
);
162 reass
= pvt_data
->sip_conn_obj_reass
;
163 assert(reass
!= NULL
);
164 if (reass
->sip_reass_msg
== NULL
) {
165 assert(reass
->sip_reass_msglen
== 0);
167 (void) pthread_mutex_unlock(
168 &pvt_data
->sip_conn_obj_reass_lock
);
171 value
= sip_get_msglen(msg
, *msglen
);
172 if (value
== *msglen
) {
173 (void) pthread_mutex_unlock(
174 &pvt_data
->sip_conn_obj_reass_lock
);
177 reass
->sip_reass_msg
= msg
;
178 reass
->sip_reass_msglen
= *msglen
;
179 if (value
!= -1 && value
< reass
->sip_reass_msglen
)
181 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
183 } else if (msg
!= NULL
) {
185 * Resize, not optimal
187 int newlen
= reass
->sip_reass_msglen
+ *msglen
;
190 assert(strlen(reass
->sip_reass_msg
) == reass
->sip_reass_msglen
);
191 newmsg
= malloc(newlen
+ 1);
192 if (newmsg
== NULL
) {
193 (void) pthread_mutex_unlock(
194 &pvt_data
->sip_conn_obj_reass_lock
);
198 (void) strncpy(newmsg
, reass
->sip_reass_msg
,
199 reass
->sip_reass_msglen
);
200 newmsg
[reass
->sip_reass_msglen
] = '\0';
201 (void) strncat(newmsg
, msg
, *msglen
);
202 newmsg
[newlen
] = '\0';
203 assert(strlen(newmsg
) == newlen
);
204 reass
->sip_reass_msglen
= newlen
;
206 free(reass
->sip_reass_msg
);
207 reass
->sip_reass_msg
= newmsg
;
209 value
= sip_get_msglen(reass
->sip_reass_msg
, reass
->sip_reass_msglen
);
210 if (value
== -1 || value
> reass
->sip_reass_msglen
) {
211 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
215 if (value
== reass
->sip_reass_msglen
) {
216 msg
= reass
->sip_reass_msg
;
217 *msglen
= reass
->sip_reass_msglen
;
218 reass
->sip_reass_msg
= NULL
;
219 reass
->sip_reass_msglen
= 0;
220 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
223 splitlen
= reass
->sip_reass_msglen
- value
;
224 msg
= (char *)malloc(value
+ 1);
225 splitbuf
= (char *)malloc(splitlen
+ 1);
226 if (msg
== NULL
|| splitbuf
== NULL
) {
229 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
232 (void) strncpy(msg
, reass
->sip_reass_msg
, value
);
234 (void) strncpy(splitbuf
, reass
->sip_reass_msg
+ value
, splitlen
);
235 splitbuf
[splitlen
] = '\0';
236 free(reass
->sip_reass_msg
);
237 reass
->sip_reass_msg
= splitbuf
;
238 reass
->sip_reass_msglen
= splitlen
;
239 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);