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
581a80f8
Commit
581a80f8
authored
Jul 19, 2013
by
jehan
Browse files
add channel parser tests
better management of partial SIP message
parent
f311b807
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
6 deletions
+175
-6
src/channel.c
src/channel.c
+53
-5
src/transports/stream_channel.h
src/transports/stream_channel.h
+7
-1
tester/belle_sip_message_tester.c
tester/belle_sip_message_tester.c
+115
-0
No files found.
src/channel.c
View file @
581a80f8
...
...
@@ -84,6 +84,10 @@ static void fix_incoming_via(belle_sip_request_t *msg, const struct addrinfo* or
char
received
[
NI_MAXHOST
];
char
rport
[
NI_MAXSERV
];
belle_sip_header_via_t
*
via
;
if
(
!
origin
)
{
belle_sip_warning
(
"cannot fix via for message [%p], probably a test"
,
msg
);
return
;
}
int
err
=
getnameinfo
(
origin
->
ai_addr
,
origin
->
ai_addrlen
,
received
,
sizeof
(
received
),
rport
,
sizeof
(
rport
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
if
(
err
!=
0
){
...
...
@@ -105,6 +109,37 @@ static void fix_incoming_via(belle_sip_request_t *msg, const struct addrinfo* or
}
}
/*token = 1*(alphanum / "-" / "." / "!" / "%" / "*"
/ "_" / "+" / "`" / "'" / "~" )
*
* */
static
int
is_token
(
const
char
*
buff
,
size_t
bufflen
)
{
int
i
;
for
(
i
=
0
;
i
<
bufflen
&&
buff
[
i
]
!=
'\0'
;
i
++
)
{
switch
(
buff
[
i
])
{
case
'-'
:
case
'.'
:
case
'!'
:
case
'%'
:
case
'*'
:
case
'_'
:
case
'+'
:
case
'`'
:
case
'\''
:
case
'~'
:
break
;
default:
if
((
buff
[
i
]
>=
'0'
&&
buff
[
i
]
<=
'9'
)
||
(
buff
[
i
]
>=
'A'
&&
buff
[
i
]
<=
'Z'
)
||
(
buff
[
i
]
>=
'a'
&&
buff
[
i
]
<=
'z'
)
||
(
buff
[
i
]
==
'\0'
))
continue
;
else
return
0
;
}
}
return
1
;
}
static
int
get_message_start_pos
(
char
*
buff
,
size_t
bufflen
)
{
/*FIXME still to optimize an better tested, specially REQUEST PATH and error path*/
int
i
;
...
...
@@ -116,12 +151,20 @@ static int get_message_start_pos(char *buff, size_t bufflen) {
int
saved_char1_index
;
for
(
i
=
0
;
i
<
(
int
)
bufflen
-
12
;
i
++
)
{
/*9=strlen( SIP/2.0\r\n)*/
switch
(
buff
[
i
])
{
/*to avoid this character to be ignored by scanf*/
case
'\r'
:
case
'\n'
:
continue
;
default:
break
;
}
saved_char1_index
=
bufflen
-
1
;
saved_char1
=
buff
[
saved_char1_index
];
/*make sure buff is null terminated*/
buff
[
saved_char1_index
]
=
'\0'
;
res
=
sscanf
(
buff
+
i
,
"SIP/2.0 %d "
,
&
status_code
);
if
(
res
!=
1
)
{
res
=
sscanf
(
buff
+
i
,
"%16s %*s %9s
\r\n
"
,
method
,
sip_version
)
==
2
&&
is_token
(
method
,
sizeof
(
method
))
&&
strcmp
(
"SIP/2.0"
,
sip_version
)
==
0
;
}
buff
[
saved_char1_index
]
=
saved_char1
;
...
...
@@ -150,7 +193,7 @@ static void belle_sip_channel_message_ready(belle_sip_channel_t *obj){
}
}
static
void
belle_sip_channel_parse_stream
(
belle_sip_channel_t
*
obj
){
void
belle_sip_channel_parse_stream
(
belle_sip_channel_t
*
obj
){
int
offset
;
size_t
read_size
=
0
;
belle_sip_header_content_length_t
*
content_length_header
;
...
...
@@ -177,11 +220,13 @@ static void belle_sip_channel_parse_stream(belle_sip_channel_t *obj){
if
(
obj
->
input_stream
.
state
==
MESSAGE_AQUISITION
)
{
/*search for \r\n\r\n*/
if
(
strstr
(
obj
->
input_stream
.
read_ptr
,
"
\r\n\r\n
"
)){
char
*
end_of_message
=
NULL
;
if
((
end_of_message
=
strstr
(
obj
->
input_stream
.
read_ptr
,
"
\r\n\r\n
"
))){
/*end of message found*/
end_of_message
+=
4
;
/*add \r\n\r\n*/
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
,
end_of_message
-
obj
->
input_stream
.
read_ptr
,
&
read_size
);
obj
->
input_stream
.
read_ptr
+=
read_size
;
if
(
obj
->
input_stream
.
msg
&&
read_size
>
0
){
...
...
@@ -199,8 +244,11 @@ static void belle_sip_channel_parse_stream(belle_sip_channel_t *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
);
belle_sip_error
(
"Could not parse [%s], on channel [%p] skipping to [%s]"
,
obj
->
input_stream
.
read_ptr
,
obj
,
end_of_message
);
obj
->
input_stream
.
read_ptr
=
end_of_message
;
obj
->
input_stream
.
state
=
WAITING_MESSAGE_START
;
continue
;
}
}
else
break
;
/*The message isn't finished to be receive, we need more data*/
...
...
src/transports/stream_channel.h
View file @
581a80f8
...
...
@@ -18,7 +18,9 @@
#ifndef STREAM_CHANNEL_H_
#define STREAM_CHANNEL_H_
#ifdef __APPLE_
#include "TargetConditionals.h"
#endif
#if TARGET_OS_IPHONE
#include <CoreFoundation/CFStream.h>
...
...
@@ -50,4 +52,8 @@ int stream_channel_connect(belle_sip_stream_channel_t *obj, const struct addrinf
int
finalize_stream_connection
(
belle_sip_stream_channel_t
*
obj
,
struct
sockaddr
*
addr
,
socklen_t
*
slen
);
int
stream_channel_send
(
belle_sip_stream_channel_t
*
obj
,
const
void
*
buf
,
size_t
buflen
);
int
stream_channel_recv
(
belle_sip_stream_channel_t
*
obj
,
void
*
buf
,
size_t
buflen
);
/*for testing purpose*/
void
belle_sip_channel_parse_stream
(
belle_sip_channel_t
*
obj
);
#endif
/* STREAM_CHANNEL_H_ */
tester/belle_sip_message_tester.c
View file @
581a80f8
...
...
@@ -328,7 +328,120 @@ static void testMalformedMessageWithWrongStart(void) {
belle_sip_message_t
*
message
=
belle_sip_message_parse
(
raw_message
);
CU_ASSERT_PTR_NULL
(
message
);
}
#include "belle_sip_internal.h"
void
channel_parser_tester_recovery_from_error
()
{
belle_sip_stack_t
*
stack
=
belle_sip_stack_new
(
NULL
);
belle_sip_channel_t
*
channel
=
belle_sip_stream_channel_new_client
(
stack
,
NULL
,
45421
,
NULL
,
"127.0.0.1"
,
45421
);
const
char
*
raw_message
=
"debut de stream tout pourrit
\r\n
"
"INVITE je_suis_une_fause_request_uri_hihihi SIP/2.0
\r\n
"
"Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2
\r\n
"
"Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg
\r\n
"
"Record-Route: <sip:37.59.129.73;lr;transport=tcp>
\r\n
"
"Record-Route: <sip:37.59.129.73;lr>
\r\n
"
"Max-Forwards: 70
\r\n
"
"From: <sip:jehan@sip.linphone.org>;tag=711138653
\r\n
"
"To: <sip:jehan@sip.linphone.org>
\r\n
"
"Call-ID: 977107319
\r\n
"
"CSeq: 21 INVITE
\r\n
"
"Contact: <sip:jehan-mac@192.168.1.8:5062>
\r\n
"
"Subject: Phone call
\r\n
"
"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)
\r\n
"
"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
\r\n
"
"Content-Length: 0
\r\n
"
"
\r\n
"
"REGISTER sip:192.168.0.20 SIP/2.0
\r\n
"
\
"Via: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806
\r\n
"
\
"From: <sip:jehan-mac@sip.linphone.org>;tag=465687829
\r\n
"
\
"To: <sip:jehan-mac@sip.linphone.org>
\r\n
"
\
"Call-ID: 1053183492
\r\n
"
\
"CSeq: 1 REGISTER
\r\n
"
\
"Contact: <sip:jehan-mac@192.168.1.8:5062>
\r\n
"
\
"Max-Forwards: 70
\r\n
"
\
"User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)
\r\n
"
\
"Expires: 3600
\r\n
"
\
"Proxy-Authorization: Digest username=
\"
8117396
\"
, realm=
\"
Realm
\"
, nonce=
\"
MTMwNDAwMjIxMjA4NzVkODY4ZmZhODMzMzU4ZDJkOTA1NzM2NTQ2NDZlNmIz"
\
", uri=
\"
sip:linphone.net
\"
, response=
\"
eed376ff7c963441255ec66594e470e7
\"
, algorithm=MD5, cnonce=
\"
0a4f113b
\"
, qop=auth, nc=00000001
\r\n
"
\
"Content-Length: 0
\r\n
"
"
\r\n
"
;
belle_sip_request_t
*
request
;
belle_sip_message_t
*
message
;
channel
->
input_stream
.
write_ptr
=
strcpy
(
channel
->
input_stream
.
write_ptr
,
raw_message
);
channel
->
input_stream
.
write_ptr
+=
strlen
(
raw_message
);
belle_sip_channel_parse_stream
(
channel
);
CU_ASSERT_PTR_NOT_NULL
(
channel
->
incoming_messages
);
CU_ASSERT_PTR_NOT_NULL
(
channel
->
incoming_messages
->
data
);
message
=
BELLE_SIP_MESSAGE
(
channel
->
incoming_messages
->
data
);
CU_ASSERT_TRUE
(
belle_sip_object_is_instance_of
(
BELLE_SIP_OBJECT
(
message
),
belle_sip_request_t_id
));
request
=
BELLE_SIP_REQUEST
(
message
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_request_get_method
(
request
),
"REGISTER"
);
CU_ASSERT_PTR_NOT_NULL
(
belle_sip_message_get_header
(
message
,
"Expires"
));
CU_ASSERT_PTR_NOT_NULL
(
BELLE_SIP_HEADER_EXPIRES
(
belle_sip_message_get_header
(
message
,
"Expires"
)));
CU_ASSERT_PTR_NOT_NULL
(
belle_sip_message_get_header
(
message
,
"Proxy-Authorization"
));
check_uri_and_headers
(
message
);
belle_sip_object_unref
(
BELLE_SIP_OBJECT
(
message
));
belle_sip_object_unref
(
stack
);
}
void
channel_parser_malformed_start
()
{
belle_sip_stack_t
*
stack
=
belle_sip_stack_new
(
NULL
);
belle_sip_channel_t
*
channel
=
belle_sip_stream_channel_new_client
(
stack
,
NULL
,
45421
,
NULL
,
"127.0.0.1"
,
45421
);
const
char
*
raw_message
=
"debut de stream tout pourrit
\r\n
"
"REGISTER sip:192.168.0.20 SIP/2.0
\r\n
"
"Via: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806
\r\n
"
"From: <sip:jehan-mac@sip.linphone.org>;tag=465687829
\r\n
"
"To: <sip:jehan-mac@sip.linphone.org>
\r\n
"
"Call-ID: 1053183492
\r\n
"
"CSeq: 1 REGISTER
\r\n
"
"Contact: <sip:jehan-mac@192.168.1.8:5062>
\r\n
"
"Max-Forwards: 70
\r\n
"
"User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)
\r\n
"
"Expires: 3600
\r\n
"
"Proxy-Authorization: Digest username=
\"
8117396
\"
, realm=
\"
Realm
\"
, nonce=
\"
MTMwNDAwMjIxMjA4NzVkODY4ZmZhODMzMzU4ZDJkOTA1NzM2NTQ2NDZlNmIz"
", uri=
\"
sip:linphone.net
\"
, response=
\"
eed376ff7c963441255ec66594e470e7
\"
, algorithm=MD5, cnonce=
\"
0a4f113b
\"
, qop=auth, nc=00000001
\r\n
"
"Content-Length: 0
\r\n
"
"
\r\n
"
;
belle_sip_request_t
*
request
;
belle_sip_message_t
*
message
;
channel
->
input_stream
.
write_ptr
=
strcpy
(
channel
->
input_stream
.
write_ptr
,
raw_message
);
channel
->
input_stream
.
write_ptr
+=
strlen
(
raw_message
);
belle_sip_channel_parse_stream
(
channel
);
CU_ASSERT_PTR_NOT_NULL
(
channel
->
incoming_messages
);
CU_ASSERT_PTR_NOT_NULL
(
channel
->
incoming_messages
->
data
);
message
=
BELLE_SIP_MESSAGE
(
channel
->
incoming_messages
->
data
);
CU_ASSERT_TRUE
(
belle_sip_object_is_instance_of
(
BELLE_SIP_OBJECT
(
message
),
belle_sip_request_t_id
));
request
=
BELLE_SIP_REQUEST
(
message
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_request_get_method
(
request
),
"REGISTER"
);
CU_ASSERT_PTR_NOT_NULL
(
belle_sip_message_get_header
(
message
,
"Expires"
));
CU_ASSERT_PTR_NOT_NULL
(
BELLE_SIP_HEADER_EXPIRES
(
belle_sip_message_get_header
(
message
,
"Expires"
)));
CU_ASSERT_PTR_NOT_NULL
(
belle_sip_message_get_header
(
message
,
"Proxy-Authorization"
));
check_uri_and_headers
(
message
);
belle_sip_object_unref
(
BELLE_SIP_OBJECT
(
message
));
belle_sip_object_unref
(
stack
);
}
/* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */
test_t
message_tests
[]
=
{
...
...
@@ -342,6 +455,8 @@ test_t message_tests[] = {
{
"Malformed invite"
,
testMalformedMessage
},
{
"Malformed invite with bad begin"
,
testMalformedMessageWithWrongStart
},
{
"Malformed register"
,
testMalformedOptionnalHeaderInMessage
},
{
"Channel parser error recovery"
,
channel_parser_tester_recovery_from_error
},
{
"Channel parser malformed start"
,
channel_parser_malformed_start
}
};
test_suite_t
message_test_suite
=
{
...
...
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