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"
39 #include "sip_miscdefs.h"
40 #include "sip_parse_uri.h"
41 #include "sip_xaction.h"
43 #define SIP_BUF_SIZE 128
46 * Find the header named header, consecutive calls with old_header
47 * passed in will return next header of the same type.
48 * If no name is passed the first header is returned. consectutive calls
49 * with no name but an old header will return the next header.
51 const struct sip_header
*
52 sip_get_header(sip_msg_t sip_msg
, char *header_name
, sip_header_t old_header
,
56 const struct sip_header
*sip_hdr
;
60 if (sip_msg
== NULL
) {
65 _sip_msg
= (_sip_msg_t
*)sip_msg
;
66 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
67 sip_hdr
= (sip_header_t
)sip_search_for_header((_sip_msg_t
*)sip_msg
,
68 header_name
, (_sip_header_t
*)old_header
);
69 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
70 if (sip_hdr
== NULL
&& error
!= NULL
)
76 * Return the request line as a string. Caller releases the returned string.
79 sip_reqline_to_str(sip_msg_t sip_msg
, int *error
)
85 if (sip_msg
== NULL
|| !sip_msg_is_request(sip_msg
, error
)) {
90 reqstr
= _sip_startline_to_str((_sip_msg_t
*)sip_msg
, error
);
95 * Return the response line as a string. Caller releases the returned string.
98 sip_respline_to_str(sip_msg_t sip_msg
, int *error
)
104 if (sip_msg
== NULL
|| sip_msg_is_request(sip_msg
, error
)) {
109 respstr
= _sip_startline_to_str((_sip_msg_t
*)sip_msg
, error
);
114 * return the first value of the header
116 const struct sip_value
*
117 sip_get_header_value(const struct sip_header
*sip_header
, int *error
)
119 _sip_header_t
*_sip_header
;
120 sip_parsed_header_t
*sip_parsed_header
;
122 const struct sip_value
*value
;
126 if (sip_header
== NULL
) {
131 _sip_header
= (_sip_header_t
*)sip_header
;
132 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
133 (void) pthread_mutex_lock(
134 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
136 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
137 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
138 (void) pthread_mutex_unlock(
139 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
145 ret
= _sip_header
->sip_header_functions
->header_parse_func(
146 _sip_header
, &sip_parsed_header
);
147 if (_sip_header
->sip_hdr_sipmsg
!= NULL
) {
148 (void) pthread_mutex_unlock
149 (&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
156 value
= (sip_header_value_t
)sip_parsed_header
->value
;
157 while (value
!= NULL
&& value
->value_state
== SIP_VALUE_DELETED
)
159 if (value
!= NULL
&& value
->value_state
== SIP_VALUE_BAD
&&
163 return ((sip_header_value_t
)value
);
167 * Return the next value of the header.
169 const struct sip_value
*
170 sip_get_next_value(sip_header_value_t old_value
, int *error
)
172 const struct sip_value
*value
;
176 if (old_value
== NULL
|| old_value
->next
== NULL
) {
182 * We never free the deleted values so no need to hold a lock.
184 value
= (sip_header_value_t
)old_value
->next
;
185 while (value
!= NULL
&& value
->value_state
== SIP_VALUE_DELETED
)
187 if (value
!= NULL
&& value
->value_state
== SIP_VALUE_BAD
&&
191 return ((sip_header_value_t
)value
);
195 * Given a SIP message, delete the header "header_name".
198 sip_delete_header_by_name(sip_msg_t msg
, char *header_name
)
200 _sip_msg_t
*_msg
= (_sip_msg_t
*)msg
;
201 sip_header_t sip_hdr
;
202 _sip_header_t
*_sip_hdr
;
204 if (_msg
== NULL
|| header_name
== NULL
)
206 (void) pthread_mutex_lock(&_msg
->sip_msg_mutex
);
207 if (_msg
->sip_msg_cannot_be_modified
) {
208 (void) pthread_mutex_unlock(&_msg
->sip_msg_mutex
);
211 sip_hdr
= (sip_header_t
)sip_search_for_header(_msg
, header_name
, NULL
);
212 if (sip_hdr
== NULL
) {
213 (void) pthread_mutex_unlock(&_msg
->sip_msg_mutex
);
216 _sip_hdr
= (_sip_header_t
*)sip_hdr
;
217 _sip_hdr
->sip_header_state
= SIP_HEADER_DELETED
;
218 _sip_hdr
->sip_hdr_sipmsg
->sip_msg_len
-= _sip_hdr
->sip_hdr_end
-
219 _sip_hdr
->sip_hdr_start
;
220 assert(_sip_hdr
->sip_hdr_sipmsg
->sip_msg_len
>= 0);
221 if (_msg
->sip_msg_buf
!= NULL
)
222 _msg
->sip_msg_modified
= B_TRUE
;
223 (void) pthread_mutex_unlock(&_msg
->sip_msg_mutex
);
229 * Mark the header as deleted.
232 sip_delete_header(sip_header_t sip_header
)
234 _sip_header_t
*_sip_header
;
236 if (sip_header
== NULL
)
238 _sip_header
= (_sip_header_t
*)sip_header
;
239 (void) pthread_mutex_lock(&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
240 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_cannot_be_modified
) {
241 (void) pthread_mutex_unlock
242 (&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
245 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
246 (void) pthread_mutex_unlock(
247 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
250 _sip_header
->sip_header_state
= SIP_HEADER_DELETED
;
251 _sip_header
->sip_hdr_sipmsg
->sip_msg_len
-= _sip_header
->sip_hdr_end
-
252 _sip_header
->sip_hdr_start
;
253 assert(_sip_header
->sip_hdr_sipmsg
->sip_msg_len
>= 0);
254 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_buf
!= NULL
)
255 _sip_header
->sip_hdr_sipmsg
->sip_msg_modified
= B_TRUE
;
256 (void) pthread_mutex_unlock
257 (&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
262 * Mark the value as deleted.
265 sip_delete_value(sip_header_t sip_header
, sip_header_value_t sip_header_value
)
267 _sip_header_t
*_sip_header
;
268 sip_value_t
*_sip_header_value
;
272 if (sip_header
== NULL
|| sip_header_value
== NULL
)
274 _sip_header
= (_sip_header_t
*)sip_header
;
275 (void) pthread_mutex_lock(&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
276 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_cannot_be_modified
) {
277 (void) pthread_mutex_unlock(&_sip_header
->
278 sip_hdr_sipmsg
->sip_msg_mutex
);
281 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
282 (void) pthread_mutex_unlock(
283 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
286 _sip_header_value
= (sip_value_t
*)sip_header_value
;
287 if (_sip_header_value
->value_state
== SIP_VALUE_DELETED
) {
288 (void) pthread_mutex_unlock(
289 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
292 _sip_header
->sip_header_state
= SIP_HEADER_DELETED_VAL
;
293 _sip_header_value
->value_state
= SIP_VALUE_DELETED
;
294 vlen
= _sip_header_value
->value_end
- _sip_header_value
->value_start
;
295 if (_sip_header
->sip_hdr_parsed
->value
== _sip_header_value
) {
296 c
= _sip_header_value
->value_start
;
297 while (*c
-- != SIP_HCOLON
)
300 c
= _sip_header_value
->value_start
;
301 while (*c
-- != SIP_COMMA
)
304 if (_sip_header_value
->next
== NULL
) {
305 sip_value_t
*value
= _sip_header
->sip_hdr_parsed
->value
;
306 boolean_t crlf_present
= B_FALSE
;
309 while (value
!= NULL
&& value
!= _sip_header_value
) {
310 crlf_present
= B_FALSE
;
312 if (value
->value_state
== SIP_VALUE_DELETED
) {
316 s
= value
->value_end
;
317 while (s
!= value
->value_start
) {
318 if (*s
== '\r' && strncmp(s
, SIP_CRLF
,
319 strlen(SIP_CRLF
)) == 0) {
320 crlf_present
= B_TRUE
;
328 c
= _sip_header_value
->value_end
;
334 _sip_header
->sip_hdr_sipmsg
->sip_msg_len
-= vlen
;
335 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_buf
!= NULL
)
336 _sip_header
->sip_hdr_sipmsg
->sip_msg_modified
= B_TRUE
;
337 (void) pthread_mutex_unlock
338 (&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
343 * Given a param list, check if a param name exists.
346 sip_is_param_present(const sip_param_t
*param_list
, char *param_name
,
349 const sip_param_t
*param
= param_list
;
351 while (param
!= NULL
) {
352 if (param
->param_name
.sip_str_len
== param_len
&&
353 strncasecmp(param
->param_name
.sip_str_ptr
, param_name
,
357 param
= param
->param_next
;
364 * Given a value header return the value of the named param.
367 sip_get_param_value(sip_header_value_t header_value
, char *param_name
,
370 sip_value_t
*_sip_header_value
;
371 sip_param_t
*sip_param
;
375 if (header_value
== NULL
|| param_name
== NULL
) {
380 _sip_header_value
= (sip_value_t
*)header_value
;
381 if (_sip_header_value
->value_state
== SIP_VALUE_DELETED
) {
386 if (_sip_header_value
->param_list
== NULL
) {
391 sip_param
= sip_get_param_from_list(_sip_header_value
->param_list
,
393 if (sip_param
!= NULL
)
394 return (&sip_param
->param_value
);
399 * Return the list of params in the header
402 sip_get_params(sip_header_value_t header_value
, int *error
)
404 sip_value_t
*sip_header_value
;
408 if (header_value
== NULL
) {
413 sip_header_value
= (sip_value_t
*)header_value
;
414 if (sip_header_value
->value_state
== SIP_VALUE_DELETED
) {
419 return (sip_header_value
->param_list
);
423 * Return true if this is a SIP request
426 sip_msg_is_request(sip_msg_t sip_msg
, int *error
)
428 _sip_msg_t
*_sip_msg
;
429 sip_message_type_t
*sip_msg_info
;
434 if (sip_msg
== NULL
) {
439 _sip_msg
= (_sip_msg_t
*)sip_msg
;
440 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
441 if (_sip_msg
->sip_msg_req_res
== NULL
) {
442 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
447 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
448 ret
= sip_msg_info
->is_request
;
449 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
454 * Return true if this is a SIP response
457 sip_msg_is_response(sip_msg_t sip_msg
, int *error
)
460 _sip_msg_t
*_sip_msg
;
461 sip_message_type_t
*sip_msg_info
;
465 if (sip_msg
== NULL
) {
470 _sip_msg
= (_sip_msg_t
*)sip_msg
;
471 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
472 if (_sip_msg
->sip_msg_req_res
== NULL
) {
473 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
478 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
479 is_resp
= !sip_msg_info
->is_request
;
480 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
485 * Return the method in the request line
488 sip_get_request_method(sip_msg_t sip_msg
, int *error
)
490 _sip_msg_t
*_sip_msg
;
491 sip_message_type_t
*sip_msg_info
;
492 sip_method_t ret
= -1;
496 if (sip_msg
== NULL
) {
501 _sip_msg
= (_sip_msg_t
*)sip_msg
;
502 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
503 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
504 if (_sip_msg
->sip_msg_req_res
== NULL
) {
505 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
510 if (sip_msg_info
->is_request
)
511 ret
= sip_msg_info
->sip_req_method
;
512 else if (error
!= NULL
)
514 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
519 * Return the URI from the request line
522 sip_get_request_uri_str(sip_msg_t sip_msg
, int *error
)
524 _sip_msg_t
*_sip_msg
;
525 sip_message_type_t
*sip_msg_info
;
526 sip_str_t
*ret
= NULL
;
527 struct sip_uri
*parsed_uri
;
531 if (sip_msg
== NULL
) {
536 _sip_msg
= (_sip_msg_t
*)sip_msg
;
537 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
538 if (_sip_msg
->sip_msg_req_res
== NULL
) {
539 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
544 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
545 if (sip_msg_info
->is_request
)
546 ret
= &sip_msg_info
->sip_req_uri
;
547 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
550 * If the error is required, check the validity of the URI via
554 parsed_uri
= sip_parse_uri(ret
, error
);
555 if (parsed_uri
!= NULL
)
556 sip_free_parsed_uri((sip_uri_t
)parsed_uri
);
562 * Return the response code
565 sip_get_response_code(sip_msg_t sip_msg
, int *error
)
567 _sip_msg_t
*_sip_msg
;
568 sip_message_type_t
*sip_msg_info
;
573 if (sip_msg
== NULL
) {
578 _sip_msg
= (_sip_msg_t
*)sip_msg
;
579 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
580 if (_sip_msg
->sip_msg_req_res
== NULL
) {
581 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
586 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
587 if (!sip_msg_info
->is_request
)
588 ret
= sip_msg_info
->sip_resp_code
;
589 else if (error
!= NULL
)
591 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
596 * Get the response phrase
599 sip_get_response_phrase(sip_msg_t sip_msg
, int *error
)
601 _sip_msg_t
*_sip_msg
;
602 sip_message_type_t
*sip_msg_info
;
603 sip_str_t
*ret
= NULL
;
607 if (sip_msg
== NULL
) {
612 _sip_msg
= (_sip_msg_t
*)sip_msg
;
613 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
614 if (_sip_msg
->sip_msg_req_res
== NULL
) {
615 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
620 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
621 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
622 if (!sip_msg_info
->is_request
) {
623 if (sip_msg_info
->sip_resp_phrase_len
== 0)
626 ret
= &sip_msg_info
->sip_resp_phrase
;
627 } else if (error
!= NULL
) {
634 * Get the SIP version string
637 sip_get_sip_version(sip_msg_t sip_msg
, int *error
)
639 _sip_msg_t
*_sip_msg
;
640 sip_message_type_t
*sip_msg_info
;
641 sip_str_t
*ret
= NULL
;
645 if (sip_msg
== NULL
) {
650 _sip_msg
= (_sip_msg_t
*)sip_msg
;
651 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
652 if (_sip_msg
->sip_msg_req_res
== NULL
) {
653 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
658 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
659 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
660 ret
= &sip_msg_info
->sip_proto_version
.version
;
665 * Return the length of the SIP message
668 sip_get_msg_len(sip_msg_t sip_msg
, int *error
)
670 _sip_msg_t
*_sip_msg
;
674 if (sip_msg
== NULL
) {
679 _sip_msg
= (_sip_msg_t
*)sip_msg
;
681 return (_sip_msg
->sip_msg_len
);
685 * Get content as a string. Caller frees the string
688 sip_get_content(sip_msg_t sip_msg
, int *error
)
690 _sip_msg_t
*_sip_msg
;
691 sip_content_t
*sip_content
;
699 if (sip_msg
== NULL
) {
704 _sip_msg
= (_sip_msg_t
*)sip_msg
;
705 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
706 if (_sip_msg
->sip_msg_content
== NULL
) {
707 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
712 content
= malloc(_sip_msg
->sip_msg_content_len
+ 1);
713 if (content
== NULL
) {
714 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
720 sip_content
= _sip_msg
->sip_msg_content
;
721 while (sip_content
!= NULL
) {
722 len
= sip_content
->sip_content_end
-
723 sip_content
->sip_content_start
;
724 (void) strncpy(p
, sip_content
->sip_content_start
, len
);
726 sip_content
= sip_content
->sip_content_next
;
728 content
[_sip_msg
->sip_msg_content_len
] = '\0';
729 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
734 * copy sip_header with param, if any, to sip_msg
737 sip_copy_header(sip_msg_t sip_msg
, sip_header_t sip_header
, char *param
)
739 _sip_msg_t
*_sip_msg
;
740 _sip_header_t
*_sip_header
;
743 if (sip_msg
== NULL
|| sip_header
== NULL
)
745 _sip_msg
= (_sip_msg_t
*)sip_msg
;
746 _sip_header
= (_sip_header_t
*)sip_header
;
747 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
748 if (_sip_msg
->sip_msg_cannot_be_modified
) {
749 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
752 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
753 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
757 ret
= _sip_copy_header(_sip_msg
, _sip_header
, param
, B_TRUE
);
758 if (_sip_msg
->sip_msg_buf
!= NULL
)
759 _sip_msg
->sip_msg_modified
= B_TRUE
;
760 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
765 * copy the header specified by header_name, with param, if any
768 sip_copy_header_by_name(sip_msg_t old_msg
, sip_msg_t new_msg
,
769 char *header_name
, char *param
)
772 _sip_msg_t
*_old_msg
= (_sip_msg_t
*)old_msg
;
773 _sip_msg_t
*_new_msg
= (_sip_msg_t
*)new_msg
;
775 if (_old_msg
== NULL
|| _new_msg
== NULL
|| header_name
== NULL
||
776 _old_msg
== _new_msg
) {
779 (void) pthread_mutex_lock(&_new_msg
->sip_msg_mutex
);
780 if (_new_msg
->sip_msg_cannot_be_modified
) {
781 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
785 (void) pthread_mutex_lock(&_old_msg
->sip_msg_mutex
);
786 ret
= _sip_find_and_copy_header(_old_msg
, _new_msg
, header_name
, param
,
788 (void) pthread_mutex_unlock(&_old_msg
->sip_msg_mutex
);
789 if (_new_msg
->sip_msg_buf
!= NULL
)
790 _new_msg
->sip_msg_modified
= B_TRUE
;
791 (void) pthread_mutex_unlock(&_new_msg
->sip_msg_mutex
);
796 * add the given header to sip_message
799 sip_add_header(sip_msg_t sip_msg
, char *header_string
)
802 _sip_header_t
*new_header
;
803 _sip_msg_t
*_sip_msg
;
805 if (sip_msg
== NULL
|| header_string
== NULL
)
807 _sip_msg
= (_sip_msg_t
*)sip_msg
;
808 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
809 if (_sip_msg
->sip_msg_cannot_be_modified
) {
810 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
813 header_size
= strlen(header_string
) + strlen(SIP_CRLF
);
814 new_header
= sip_new_header(header_size
);
815 if (new_header
== NULL
) {
816 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
820 (void) snprintf(new_header
->sip_hdr_start
, header_size
+ 1, "%s%s",
821 header_string
, SIP_CRLF
);
822 _sip_add_header(_sip_msg
, new_header
, B_TRUE
, B_FALSE
, NULL
);
823 if (_sip_msg
->sip_msg_buf
!= NULL
)
824 _sip_msg
->sip_msg_modified
= B_TRUE
;
825 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
830 * add the given param to the sip_header. create a new header with the param
831 * and mark the old header as deleted.
834 sip_add_param(sip_header_t sip_header
, char *param
, int *error
)
836 _sip_header_t
*_sip_header
;
837 _sip_header_t
*new_header
;
839 _sip_msg_t
*_sip_msg
;
846 if (param
== NULL
|| sip_header
== NULL
) {
852 _sip_header
= (_sip_header_t
*)sip_header
;
854 (void) pthread_mutex_lock(&_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
855 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_cannot_be_modified
) {
858 (void) pthread_mutex_unlock(
859 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
862 if (_sip_header
->sip_header_state
== SIP_HEADER_DELETED
) {
865 (void) pthread_mutex_unlock(
866 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
870 param_len
= SIP_SPACE_LEN
+ sizeof (char) + SIP_SPACE_LEN
+
872 hdrlen
= _sip_header
->sip_hdr_end
- _sip_header
->sip_hdr_start
;
873 new_header
= sip_new_header(hdrlen
+ param_len
);
874 if (new_header
== NULL
) {
877 (void) pthread_mutex_unlock(
878 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
881 (void) memcpy(new_header
->sip_hdr_start
, _sip_header
->sip_hdr_start
,
883 new_header
->sip_hdr_end
= new_header
->sip_hdr_start
+ hdrlen
;
884 hdrlen
= param_len
+ 1;
888 tmp_ptr
= new_header
->sip_hdr_end
;
889 while (*tmp_ptr
-- != '\n') {
891 if (tmp_ptr
== new_header
->sip_hdr_start
) {
892 sip_free_header(new_header
);
895 (void) pthread_mutex_unlock(
896 &_sip_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
900 (void) snprintf(tmp_ptr
, hdrlen
+ 1,
901 " %c %s%s", SIP_SEMI
, param
, SIP_CRLF
);
902 new_header
->sip_hdr_end
+= param_len
;
903 new_header
->sip_header_functions
= _sip_header
->sip_header_functions
;
904 _sip_msg
= _sip_header
->sip_hdr_sipmsg
;
905 _sip_add_header(_sip_msg
, new_header
, B_TRUE
, B_FALSE
, NULL
);
906 if (_sip_header
->sip_hdr_sipmsg
->sip_msg_buf
!= NULL
)
907 _sip_header
->sip_hdr_sipmsg
->sip_msg_modified
= B_TRUE
;
908 (void) pthread_mutex_unlock(&new_header
->sip_hdr_sipmsg
->sip_msg_mutex
);
909 (void) sip_delete_header(sip_header
);
910 return ((sip_header_t
)new_header
);
916 const struct sip_uri
*
917 sip_get_request_uri(sip_msg_t sip_msg
, int *error
)
919 _sip_msg_t
*_sip_msg
;
920 sip_message_type_t
*sip_msg_info
;
921 const struct sip_uri
*ret
= NULL
;
926 if (sip_msg
== NULL
) {
931 _sip_msg
= (_sip_msg_t
*)sip_msg
;
932 (void) pthread_mutex_lock(&_sip_msg
->sip_msg_mutex
);
933 sip_msg_info
= _sip_msg
->sip_msg_req_res
;
934 if (sip_msg_info
!= NULL
&& sip_msg_info
->is_request
) {
935 ret
= sip_msg_info
->sip_req_parse_uri
;
940 (void) pthread_mutex_unlock(&_sip_msg
->sip_msg_mutex
);
943 if (ret
->sip_uri_scheme
.sip_str_len
== 0 ||
944 ret
->sip_uri_scheme
.sip_str_ptr
== NULL
) {
948 } else if (ret
->sip_uri_errflags
!= 0 && error
!= NULL
) {
952 return ((sip_uri_t
)ret
);
956 * returns a comma separated string of all the sent-by values registered by
960 sip_sent_by_to_str(int *error
)
973 (void) pthread_mutex_lock(&sip_sent_by_lock
);
974 if (sip_sent_by
== NULL
) {
975 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
979 for (cnt
= 0; cnt
< sip_sent_by_count
; cnt
++) {
980 sb_len
+= strlen(sb
->sb_val
);
986 sb_len
+= sip_sent_by_count
- 1;
987 sb_str
= malloc(sb_len
+ 1);
988 if (sb_str
== NULL
) {
991 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
997 for (cnt
= 0; cnt
< sip_sent_by_count
; cnt
++) {
999 count
= snprintf(p
, slen
, "%s", sb
->sb_val
);
1001 count
= snprintf(p
, slen
, "%c%s", SIP_COMMA
,
1008 sb_str
[sb_len
] = '\0';
1009 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
1014 * A comma separated list of sent-by values.
1017 sip_register_sent_by(char *val
)
1019 sent_by_list_t
*sb
= NULL
;
1020 sent_by_list_t
*sb_tail
= NULL
;
1026 str
= strtok(val
, ",");
1027 while (str
!= NULL
) {
1030 char *end
= str
+ strlen(str
) - 1;
1032 while (isspace(*start
))
1034 while (isspace(*end
))
1038 slen
= end
- start
+ 1;
1039 sb_tail
= (sent_by_list_t
*)malloc(sizeof (*sb_tail
));
1040 if (sb_tail
== NULL
)
1042 sb_tail
->sb_next
= sb_tail
->sb_prev
= NULL
;
1043 if ((sb_tail
->sb_val
= (char *)malloc(slen
+ 1)) == NULL
) {
1047 (void) strncpy(sb_tail
->sb_val
, start
, slen
);
1048 sb_tail
->sb_val
[slen
] = '\0';
1052 sb_tail
->sb_next
= sb
;
1053 sb
->sb_prev
= sb_tail
;
1057 str
= strtok(NULL
, ",");
1060 while (sb_tail
->sb_next
!= NULL
)
1061 sb_tail
= sb_tail
->sb_next
;
1062 (void) pthread_mutex_lock(&sip_sent_by_lock
);
1063 if (sip_sent_by
!= NULL
) {
1064 sb_tail
->sb_next
= sip_sent_by
;
1065 sip_sent_by
->sb_prev
= sb_tail
;
1068 sip_sent_by_count
+= count
;
1069 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
1073 for (; count
> 0; count
--) {
1074 sb
= sb_tail
->sb_next
;
1075 free(sb_tail
->sb_val
);
1076 sb_tail
->sb_next
= NULL
;
1077 sb_tail
->sb_prev
= NULL
;
1085 * Un-register sent-by values; 'val' contains a comma separated list
1088 sip_unregister_sent_by(char *val
)
1094 (void) pthread_mutex_lock(&sip_sent_by_lock
);
1095 str
= strtok(val
, ",");
1096 while (str
!= NULL
) {
1098 for (count
= 0; count
< sip_sent_by_count
; count
++) {
1099 if (strncmp(sb
->sb_val
, str
, strlen(str
)) == 0) {
1100 if (sb
== sip_sent_by
) {
1101 if (sb
->sb_next
!= NULL
)
1102 sip_sent_by
= sb
->sb_next
;
1105 } else if (sb
->sb_next
== NULL
) {
1106 sb
->sb_prev
->sb_next
= NULL
;
1108 sb
->sb_prev
->sb_next
= sb
->sb_next
;
1109 sb
->sb_next
->sb_prev
= sb
->sb_prev
;
1111 sip_sent_by_count
--;
1120 str
= strtok(NULL
, ",");
1122 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
1126 * Un-register all the sent-by values
1129 sip_unregister_all_sent_by()
1134 (void) pthread_mutex_lock(&sip_sent_by_lock
);
1136 for (count
= 0; count
< sip_sent_by_count
; count
++) {
1137 sip_sent_by
= sb
->sb_next
;
1145 sip_sent_by_count
= 0;
1146 (void) pthread_mutex_unlock(&sip_sent_by_lock
);
1150 * Given a response code, return the corresponding phrase
1153 sip_get_resp_desc(int resp_code
)
1155 switch (resp_code
) {
1160 case SIP_CALL_IS_BEING_FORWARDED
:
1161 return ("CALL_IS_BEING_FORWARDED");
1164 case SIP_SESSION_PROGRESS
:
1165 return ("SESSION_PROGRESS");
1169 return ("ACCEPTED");
1170 case SIP_MULTIPLE_CHOICES
:
1171 return ("MULTIPLE_CHOICES");
1172 case SIP_MOVED_PERMANENTLY
:
1173 return ("MOVED_PERMANENTLY");
1174 case SIP_MOVED_TEMPORARILY
:
1175 return ("MOVED_TEMPORARILY");
1177 return ("USE_PROXY");
1178 case SIP_ALTERNATIVE_SERVICE
:
1179 return ("ALTERNATIVE_SERVICE");
1180 case SIP_BAD_REQUEST
:
1181 return ("BAD_REQUEST");
1182 case SIP_UNAUTHORIZED
:
1183 return ("UNAUTHORIZED");
1184 case SIP_PAYMENT_REQUIRED
:
1185 return ("PAYMENT_REQUIRED");
1187 return ("FORBIDDEN");
1189 return ("NOT_FOUND");
1190 case SIP_METHOD_NOT_ALLOWED
:
1191 return ("METHOD_NOT_ALLOWED");
1192 case SIP_NOT_ACCEPTABLE
:
1193 return ("NOT_ACCEPTABLE");
1194 case SIP_PROXY_AUTH_REQUIRED
:
1195 return ("PROXY_AUTH_REQUIRED");
1196 case SIP_REQUEST_TIMEOUT
:
1197 return ("REQUEST_TIMEOUT");
1200 case SIP_REQUEST_ENTITY_2_LARGE
:
1201 return ("REQUEST_ENTITY_2_LARGE");
1202 case SIP_REQUEST_URI_2_LONG
:
1203 return ("REQUEST_URI_2_LONG");
1204 case SIP_UNSUPPORTED_MEDIA_TYPE
:
1205 return ("UNSUPPORTED_MEDIA_TYPE");
1206 case SIP_UNSUPPORTED_URI_SCHEME
:
1207 return ("UNSUPPORTED_URI_SCHEME");
1208 case SIP_BAD_EXTENSION
:
1209 return ("BAD_EXTENSION");
1210 case SIP_EXTENSION_REQUIRED
:
1211 return ("EXTENSION_REQUIRED");
1212 case SIP_INTERVAL_2_BRIEF
:
1213 return ("INTERVAL_2_BRIEF");
1214 case SIP_TEMPORARILY_UNAVAIL
:
1215 return ("TEMPORARILY_UNAVAIL");
1216 case SIP_CALL_NON_EXISTANT
:
1217 return ("CALL_NON_EXISTANT");
1218 case SIP_LOOP_DETECTED
:
1219 return ("LOOP_DETECTED");
1220 case SIP_TOO_MANY_HOOPS
:
1221 return ("TOO_MANY_HOOPS");
1222 case SIP_ADDRESS_INCOMPLETE
:
1223 return ("ADDRESS_INCOMPLETE");
1225 return ("AMBIGUOUS");
1227 return ("BUSY_HERE");
1228 case SIP_REQUEST_TERMINATED
:
1229 return ("REQUEST_TERMINATED");
1230 case SIP_NOT_ACCEPTABLE_HERE
:
1231 return ("NOT_ACCEPTABLE_HERE");
1233 return ("BAD_EVENT");
1234 case SIP_REQUEST_PENDING
:
1235 return ("REQUEST_PENDING");
1236 case SIP_UNDECIPHERABLE
:
1237 return ("UNDECIPHERABLE");
1238 case SIP_SERVER_INTERNAL_ERROR
:
1239 return ("SERVER_INTERNAL_ERROR");
1240 case SIP_NOT_IMPLEMENTED
:
1241 return ("NOT_IMPLEMENTED");
1242 case SIP_BAD_GATEWAY
:
1243 return ("BAD_GATEWAY");
1244 case SIP_SERVICE_UNAVAILABLE
:
1245 return ("SERVICE_UNAVAILABLE");
1246 case SIP_SERVER_TIMEOUT
:
1247 return ("SERVER_TIMEOUT");
1248 case SIP_VERSION_NOT_SUPPORTED
:
1249 return ("VERSION_NOT_SUPPORTED");
1250 case SIP_MESSAGE_2_LARGE
:
1251 return ("MESSAGE_2_LARGE");
1252 case SIP_BUSY_EVERYWHERE
:
1253 return ("BUSY_EVERYWHERE");
1256 case SIP_DOES_NOT_EXIST_ANYWHERE
:
1257 return ("DOES_NOT_EXIST_ANYWHERE");
1258 case SIP_NOT_ACCEPTABLE_ANYWHERE
:
1259 return ("NOT_ACCEPTABLE_ANYWHERE");
1266 * The following three fns initialize and destroy the private library
1267 * data in sip_conn_object_t. The assumption is that the 1st member
1268 * of sip_conn_object_t is reserved for library use. The private data
1269 * is used only for byte-stream protocols such as TCP to accumulate
1270 * a complete SIP message, based on the CONTENT-LENGTH value, before
1274 sip_init_conn_object(sip_conn_object_t obj
)
1277 sip_conn_obj_pvt_t
*pvt_data
;
1281 pvt_data
= malloc(sizeof (sip_conn_obj_pvt_t
));
1282 if (pvt_data
== NULL
)
1284 pvt_data
->sip_conn_obj_cache
= NULL
;
1285 pvt_data
->sip_conn_obj_reass
= malloc(sizeof (sip_reass_entry_t
));
1286 if (pvt_data
->sip_conn_obj_reass
== NULL
) {
1290 bzero(pvt_data
->sip_conn_obj_reass
, sizeof (sip_reass_entry_t
));
1291 (void) pthread_mutex_init(&pvt_data
->sip_conn_obj_reass_lock
, NULL
);
1292 (void) pthread_mutex_init(&pvt_data
->sip_conn_obj_cache_lock
, NULL
);
1293 sip_refhold_conn(obj
);
1294 obj_val
= (void *)obj
;
1295 *obj_val
= (void *)pvt_data
;
1301 * Clear private date, if any
1304 sip_clear_stale_data(sip_conn_object_t obj
)
1307 sip_conn_obj_pvt_t
*pvt_data
;
1308 sip_reass_entry_t
*reass
;
1312 obj_val
= (void *)obj
;
1313 pvt_data
= (sip_conn_obj_pvt_t
*)*obj_val
;
1314 (void) pthread_mutex_lock(&pvt_data
->sip_conn_obj_reass_lock
);
1315 reass
= pvt_data
->sip_conn_obj_reass
;
1316 if (reass
->sip_reass_msg
!= NULL
) {
1317 assert(reass
->sip_reass_msglen
> 0);
1318 free(reass
->sip_reass_msg
);
1319 reass
->sip_reass_msglen
= 0;
1321 assert(reass
->sip_reass_msglen
== 0);
1322 (void) pthread_mutex_unlock(&pvt_data
->sip_conn_obj_reass_lock
);
1326 * Walk through all the transactions, remove if this obj has been cached
1330 sip_conn_destroyed(sip_conn_object_t obj
)
1333 sip_conn_obj_pvt_t
*pvt_data
;
1337 obj_val
= (void *)obj
;
1338 pvt_data
= (sip_conn_obj_pvt_t
*)*obj_val
;
1340 sip_clear_stale_data(obj
);
1341 free(pvt_data
->sip_conn_obj_reass
);
1342 pvt_data
->sip_conn_obj_reass
= NULL
;
1343 (void) pthread_mutex_destroy(&pvt_data
->sip_conn_obj_reass_lock
);
1345 sip_del_conn_obj_cache(obj
, NULL
);
1346 (void) pthread_mutex_destroy(&pvt_data
->sip_conn_obj_cache_lock
);
1350 sip_refrele_conn(obj
);