Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belle-sip
Commits
030ba21b
Commit
030ba21b
authored
May 31, 2013
by
Simon Morlat
Browse files
fix bug in stream parser resulting in channel corruption
clean input stream parser (no more goto, no more recursion)
parent
a5569489
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/channel.c
View file @
030ba21b
...
...
@@ -140,32 +140,25 @@ static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_i
return
MAX_CHANNEL_BUFF_SIZE
-
(
input_stream
->
write_ptr
-
input_stream
->
buff
);
}
int
belle_sip_channel_process_data
(
belle_sip_channel_t
*
obj
,
unsigned
int
revents
){
int
num
;
static
void
belle_sip_channel_message_ready
(
belle_sip_channel_t
*
obj
){
obj
->
incoming_messages
=
belle_sip_list_append
(
obj
->
incoming_messages
,
obj
->
input_stream
.
msg
);
obj
->
input_stream
.
msg
=
NULL
;
obj
->
input_stream
.
state
=
WAITING_MESSAGE_START
;
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2
(
obj
->
listeners
,
belle_sip_channel_listener_t
,
on_event
,
obj
,
BELLE_SIP_EVENT_READ
/*always a read event*/
);
if
(
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
<=
0
)
{
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
/*end of strem, back to home*/
}
}
static
void
belle_sip_channel_parse_stream
(
belle_sip_channel_t
*
obj
){
int
offset
;
int
i
;
size_t
read_size
=
0
;
belle_sip_header_content_length_t
*
content_length_header
;
int
content_length
;
if
(
revents
&
BELLE_SIP_EVENT_READ
)
{
if
(
obj
->
simulated_recv_return
>
0
)
{
num
=
belle_sip_channel_recv
(
obj
,
obj
->
input_stream
.
write_ptr
,
belle_sip_channel_input_stream_get_buff_length
(
&
obj
->
input_stream
)
-
1
);
/*write ptr is only incremented if data were acquired from the transport*/
obj
->
input_stream
.
write_ptr
+=
num
;
/*first null terminate the read buff*/
*
obj
->
input_stream
.
write_ptr
=
'\0'
;
}
else
{
belle_sip_message
(
"channel [%p]: simulating recv() returning %i"
,
obj
,
obj
->
simulated_recv_return
);
num
=
obj
->
simulated_recv_return
;
}
}
else
if
(
!
revents
)
{
num
=
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
;
}
else
{
belle_sip_error
(
"Unexpected event [%i] on channel [%p]"
,
revents
,
obj
);
num
=-
1
;
/*to trigger an error*/
}
if
(
num
>
0
){
int
num
;
while
((
num
=
(
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
))
>
0
){
if
(
obj
->
input_stream
.
state
==
WAITING_MESSAGE_START
)
{
/*search for request*/
if
((
offset
=
get_message_start_pos
(
obj
->
input_stream
.
read_ptr
,
num
))
>=
0
)
{
...
...
@@ -178,40 +171,39 @@ int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents
}
else
{
belle_sip_debug
(
"Unexpected [%s] received on channel [%p], trashing"
,
obj
->
input_stream
.
read_ptr
,
obj
);
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
continue
;
}
}
if
(
obj
->
input_stream
.
state
==
MESSAGE_AQUISITION
)
{
/*search for \r\n\r\n*/
for
(
i
=
0
;
i
<
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
;
i
++
)
{
if
(
strncmp
(
"
\r\n\r\n
"
,
&
obj
->
input_stream
.
read_ptr
[
i
],
4
)
==
0
)
{
/*end of message found*/
belle_sip_message
(
"channel [%p] read message from %s:%i
\n
%s"
,
obj
,
obj
->
peer_name
,
obj
->
peer_port
,
obj
->
input_stream
.
read_ptr
);
obj
->
input_stream
.
msg
=
belle_sip_message_parse_raw
(
obj
->
input_stream
.
read_ptr
,
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
,
&
read_size
);
obj
->
input_stream
.
read_ptr
+=
read_size
;
if
(
obj
->
input_stream
.
msg
&&
read_size
>
0
){
belle_sip_message
(
"channel [%p] [%i] bytes parsed"
,
obj
,
read_size
);
belle_sip_object_ref
(
obj
->
input_stream
.
msg
);
if
(
belle_sip_message_is_request
(
obj
->
input_stream
.
msg
))
fix_incoming_via
(
BELLE_SIP_REQUEST
(
obj
->
input_stream
.
msg
),
obj
->
current_peer
);
/*check for body*/
if
((
content_length_header
=
(
belle_sip_header_content_length_t
*
)
belle_sip_message_get_header
(
obj
->
input_stream
.
msg
,
BELLE_SIP_CONTENT_LENGTH
))
!=
NULL
&&
belle_sip_header_content_length_get_content_length
(
content_length_header
)
>
0
)
{
obj
->
input_stream
.
state
=
BODY_AQUISITION
;
break
;
/*don't avoid to exist from loop, because 2 response can be linked*/
}
else
{
/*no body*/
goto
message_ready
;
}
}
else
{
belle_sip_error
(
"Could not parse [%s], resetting channel [%p]"
,
obj
->
input_stream
.
read_ptr
,
obj
);
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
if
(
strstr
(
obj
->
input_stream
.
read_ptr
,
"
\r\n\r\n
"
)){
/*end of message found*/
belle_sip_message
(
"channel [%p] read message from %s:%i
\n
%s"
,
obj
,
obj
->
peer_name
,
obj
->
peer_port
,
obj
->
input_stream
.
read_ptr
);
obj
->
input_stream
.
msg
=
belle_sip_message_parse_raw
(
obj
->
input_stream
.
read_ptr
,
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
,
&
read_size
);
obj
->
input_stream
.
read_ptr
+=
read_size
;
if
(
obj
->
input_stream
.
msg
&&
read_size
>
0
){
belle_sip_message
(
"channel [%p] [%i] bytes parsed"
,
obj
,
read_size
);
belle_sip_object_ref
(
obj
->
input_stream
.
msg
);
if
(
belle_sip_message_is_request
(
obj
->
input_stream
.
msg
))
fix_incoming_via
(
BELLE_SIP_REQUEST
(
obj
->
input_stream
.
msg
),
obj
->
current_peer
);
/*check for body*/
if
((
content_length_header
=
(
belle_sip_header_content_length_t
*
)
belle_sip_message_get_header
(
obj
->
input_stream
.
msg
,
BELLE_SIP_CONTENT_LENGTH
))
!=
NULL
&&
belle_sip_header_content_length_get_content_length
(
content_length_header
)
>
0
)
{
obj
->
input_stream
.
state
=
BODY_AQUISITION
;
}
else
{
/*no body*/
belle_sip_channel_message_ready
(
obj
);
continue
;
}
}
else
{
belle_sip_error
(
"Could not parse [%s], resetting channel [%p]"
,
obj
->
input_stream
.
read_ptr
,
obj
);
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
continue
;
}
}
}
else
break
;
/*The message isn't finished to be receive, we need more data*/
}
if
(
obj
->
input_stream
.
state
==
BODY_AQUISITION
)
{
...
...
@@ -219,30 +211,41 @@ int belle_sip_channel_process_data(belle_sip_channel_t *obj,unsigned int revents
if
(
content_length
<=
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
)
{
/*great body completed*/
belle_sip_message
(
"channel [%p] read [%i] bytes of body from %s:%i
\n
%s"
,
obj
,
content_length
,
obj
->
peer_name
,
obj
->
peer_port
,
obj
->
input_stream
.
read_ptr
);
,
content_length
,
obj
->
peer_name
,
obj
->
peer_port
,
obj
->
input_stream
.
read_ptr
);
belle_sip_message_set_body
(
obj
->
input_stream
.
msg
,
obj
->
input_stream
.
read_ptr
,
content_length
);
read_size
+=
content_length
;
/*read size is used in message ready to compute residu*/
obj
->
input_stream
.
read_ptr
+=
content_length
;
goto
message_ready
;
belle_sip_channel_message_ready
(
obj
);
}
else
{
/*body is not finished, we need more data*/
break
;
}
}
return
BELLE_SIP_CONTINUE
;
message_ready:
obj
->
incoming_messages
=
belle_sip_list_append
(
obj
->
incoming_messages
,
obj
->
input_stream
.
msg
);
obj
->
input_stream
.
msg
=
NULL
;
obj
->
input_stream
.
state
=
WAITING_MESSAGE_START
;
BELLE_SIP_INVOKE_LISTENERS_ARG1_ARG2
(
obj
->
listeners
,
belle_sip_channel_listener_t
,
on_event
,
obj
,
BELLE_SIP_EVENT_READ
/*always a read event*/
);
if
(
obj
->
input_stream
.
write_ptr
-
obj
->
input_stream
.
read_ptr
>
0
)
{
/*process residu*/
belle_sip_channel_
process_data
(
obj
,
0
);
}
}
int
belle_sip_channel_process_data
(
belle_sip_channel_t
*
obj
,
unsigned
int
revents
){
int
num
;
if
(
revents
&
BELLE_SIP_EVENT_READ
)
{
if
(
obj
->
simulated_recv_return
>
0
)
{
num
=
belle_sip_channel_
recv
(
obj
,
obj
->
input_stream
.
write_ptr
,
belle_sip_channel_input_stream_get_buff_length
(
&
obj
->
input_stream
)
-
1
);
}
else
{
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
/*end of strem, back to home*/
belle_sip_message
(
"channel [%p]: simulating recv() returning %i"
,
obj
,
obj
->
simulated_recv_return
);
num
=
obj
->
simulated_recv_return
;
}
return
BELLE_SIP_CONTINUE
;
}
else
{
belle_sip_error
(
"Unexpected event [%i] on channel [%p]"
,
revents
,
obj
);
num
=-
1
;
/*to trigger an error*/
}
if
(
num
>
0
){
obj
->
input_stream
.
write_ptr
+=
num
;
/*first null terminate the read buff*/
*
obj
->
input_stream
.
write_ptr
=
'\0'
;
belle_sip_channel_parse_stream
(
obj
);
}
else
if
(
num
==
0
)
{
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_DISCONNECTED
);
return
BELLE_SIP_STOP
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment