Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-03-19 14:58:29 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
841f0f8899ccd943f9ab4a7cbbb28abe8426e014
841f0f88
1 parent
152d3539
change to 0.9.19, verify the s1/s2/c2, refine the handshake.
隐藏空白字符变更
内嵌
并排对比
正在显示
8 个修改的文件
包含
349 行增加
和
118 行删除
trunk/src/core/srs_core.hpp
trunk/src/core/srs_core_autofree.hpp
trunk/src/rtmp/srs_protocol_handshake.cpp
trunk/src/rtmp/srs_protocol_handshake.hpp
trunk/src/rtmp/srs_protocol_rtmp.cpp
trunk/src/rtmp/srs_protocol_rtmp.hpp
trunk/src/rtmp/srs_protocol_utility.cpp
trunk/src/rtmp/srs_protocol_utility.hpp
trunk/src/core/srs_core.hpp
查看文件 @
841f0f8
...
...
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR "0"
#define VERSION_MINOR "9"
#define VERSION_REVISION "1
8
"
#define VERSION_REVISION "1
9
"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info.
#define RTMP_SIG_SRS_KEY "srs"
...
...
trunk/src/core/srs_core_autofree.hpp
查看文件 @
841f0f8
...
...
@@ -34,7 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* auto free the instance in the current scope.
*/
#define SrsAutoFree(className, instance, is_array) \
__SrsAutoFree<className> _auto_free_##instance(&instance, is_array)
__SrsAutoFree<className> _auto_free_##instance(
(className**)
&instance, is_array)
template
<
class
T
>
class
__SrsAutoFree
...
...
trunk/src/rtmp/srs_protocol_handshake.cpp
查看文件 @
841f0f8
...
...
@@ -24,28 +24,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_protocol_handshake.hpp>
#include <time.h>
#include <stdlib.h>
#include <srs_core_autofree.hpp>
#include <srs_kernel_error.hpp>
#include <srs_kernel_log.hpp>
#include <srs_protocol_io.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_protocol_rtmp.hpp>
using
namespace
srs
;
void
srs_random_generate
(
char
*
bytes
,
int
size
)
{
static
char
cdata
[]
=
{
0x73
,
0x69
,
0x6d
,
0x70
,
0x6c
,
0x65
,
0x2d
,
0x72
,
0x74
,
0x6d
,
0x70
,
0x2d
,
0x73
,
0x65
,
0x72
,
0x76
,
0x65
,
0x72
,
0x2d
,
0x77
,
0x69
,
0x6e
,
0x6c
,
0x69
,
0x6e
,
0x2d
,
0x77
,
0x69
,
0x6e
,
0x74
,
0x65
,
0x72
,
0x73
,
0x65
,
0x72
,
0x76
,
0x65
,
0x72
,
0x40
,
0x31
,
0x32
,
0x36
,
0x2e
,
0x63
,
0x6f
,
0x6d
};
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
bytes
[
i
]
=
cdata
[
rand
()
%
(
sizeof
(
cdata
)
-
1
)];
}
}
#ifdef SRS_SSL
// 68bytes FMS key which is used to sign the sever packet.
...
...
@@ -569,6 +557,12 @@ void c2s2::dump(char* _c2s2)
memcpy
(
_c2s2
+
1504
,
digest
,
32
);
}
void
c2s2
::
parse
(
char
*
_c2s2
)
{
memcpy
(
random
,
_c2s2
,
1504
);
memcpy
(
digest
,
_c2s2
+
1504
,
32
);
}
int
c2s2
::
c2_create
(
c1s1
*
s1
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -592,6 +586,30 @@ int c2s2::c2_create(c1s1* s1)
return
ret
;
}
int
c2s2
::
c2_validate
(
c1s1
*
s1
,
bool
&
is_valid
)
{
is_valid
=
false
;
int
ret
=
ERROR_SUCCESS
;
char
temp_key
[
OpensslHashSize
];
if
((
ret
=
openssl_HMACsha256
(
s1
->
get_digest
(),
32
,
SrsGenuineFPKey
,
62
,
temp_key
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"create c2 temp key failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"generate c2 temp key success."
);
char
_digest
[
OpensslHashSize
];
if
((
ret
=
openssl_HMACsha256
(
random
,
1504
,
temp_key
,
32
,
_digest
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"create c2 digest failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"generate c2 digest success."
);
is_valid
=
srs_bytes_equals
(
digest
,
_digest
,
32
);
return
ret
;
}
int
c2s2
::
s2_create
(
c1s1
*
c1
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -615,6 +633,30 @@ int c2s2::s2_create(c1s1* c1)
return
ret
;
}
int
c2s2
::
s2_validate
(
c1s1
*
c1
,
bool
&
is_valid
)
{
is_valid
=
false
;
int
ret
=
ERROR_SUCCESS
;
char
temp_key
[
OpensslHashSize
];
if
((
ret
=
openssl_HMACsha256
(
c1
->
get_digest
(),
32
,
SrsGenuineFMSKey
,
68
,
temp_key
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"create s2 temp key failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"generate s2 temp key success."
);
char
_digest
[
OpensslHashSize
];
if
((
ret
=
openssl_HMACsha256
(
random
,
1504
,
temp_key
,
32
,
_digest
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"create s2 digest failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"generate s2 digest success."
);
is_valid
=
srs_bytes_equals
(
digest
,
_digest
,
32
);
return
ret
;
}
c1s1
::
c1s1
()
{
schema
=
srs_schema_invalid
;
...
...
@@ -738,6 +780,7 @@ int c1s1::c1_parse(char* _c1s1, srs_schema_type _schema)
int
c1s1
::
c1_validate_digest
(
bool
&
is_valid
)
{
is_valid
=
false
;
int
ret
=
ERROR_SUCCESS
;
char
*
c1_digest
=
NULL
;
...
...
@@ -761,6 +804,7 @@ int c1s1::c1_validate_digest(bool& is_valid)
int
c1s1
::
s1_validate_digest
(
bool
&
is_valid
)
{
is_valid
=
false
;
int
ret
=
ERROR_SUCCESS
;
char
*
s1_digest
=
NULL
;
...
...
@@ -918,125 +962,85 @@ SrsSimpleHandshake::~SrsSimpleHandshake()
{
}
int
SrsSimpleHandshake
::
handshake_with_client
(
ISrsProtocolReaderWriter
*
skt
,
SrsComplexHandshake
*
complex_hs
)
int
SrsSimpleHandshake
::
handshake_with_client
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
ssize_t
nsize
;
char
*
c0c1
=
new
char
[
1537
];
SrsAutoFree
(
char
,
c0c1
,
true
);
if
((
ret
=
skt
->
read_fully
(
c0c1
,
1537
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read c0c1 failed. ret=%d"
,
ret
);
if
((
ret
=
hs_bytes
->
read_c0c1
(
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_verbose
(
"read c0c1 success."
);
// plain text required.
if
(
c0c1
[
0
]
!=
0x03
)
{
if
(
hs_bytes
->
c0c1
[
0
]
!=
0x03
)
{
ret
=
ERROR_RTMP_PLAIN_REQUIRED
;
srs_warn
(
"only support rtmp plain text. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"check c0 success, required plain text."
);
// try complex handshake
if
(
complex_hs
)
{
ret
=
complex_hs
->
handshake_with_client
(
skt
,
c0c1
+
1
);
if
(
ret
==
ERROR_SUCCESS
)
{
srs_trace
(
"complex handshake success."
);
return
ret
;
}
if
(
ret
!=
ERROR_RTMP_TRY_SIMPLE_HS
)
{
srs_error
(
"complex handshake failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"rollback complex to simple handshake. ret=%d"
,
ret
);
if
((
ret
=
hs_bytes
->
create_s0s1s2
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
char
*
s0s1s2
=
new
char
[
3073
];
srs_random_generate
(
s0s1s2
,
3073
);
SrsAutoFree
(
char
,
s0s1s2
,
true
);
// plain text required.
s0s1s2
[
0
]
=
0x03
;
if
((
ret
=
skt
->
write
(
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
hs_bytes
->
s0s1s2
[
0
]
=
0x03
;
if
((
ret
=
io
->
write
(
hs_bytes
->
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"simple handshake send s0s1s2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"simple handshake send s0s1s2 success."
);
char
*
c2
=
new
char
[
1536
];
SrsAutoFree
(
char
,
c2
,
true
);
if
((
ret
=
skt
->
read_fully
(
c2
,
1536
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"simple handshake read c2 failed. ret=%d"
,
ret
);
if
((
ret
=
hs_bytes
->
read_c2
(
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_verbose
(
"simple handshake read c2 success."
);
srs_trace
(
"simple handshake success."
);
srs_trace
(
"simple handshake
with client
success."
);
return
ret
;
}
int
SrsSimpleHandshake
::
handshake_with_server
(
ISrsProtocolReaderWriter
*
skt
,
SrsComplexHandshake
*
complex_hs
)
int
SrsSimpleHandshake
::
handshake_with_server
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
// try complex handshake
if
(
complex_hs
)
{
ret
=
complex_hs
->
handshake_with_server
(
skt
);
if
(
ret
==
ERROR_SUCCESS
)
{
srs_trace
(
"complex handshake success."
);
return
ret
;
}
if
(
ret
!=
ERROR_RTMP_TRY_SIMPLE_HS
)
{
srs_error
(
"complex handshake failed. ret=%d"
,
ret
);
return
ret
;
}
srs_info
(
"rollback complex to simple handshake. ret=%d"
,
ret
);
}
// simple handshake
ssize_t
nsize
;
char
*
c0c1
=
new
char
[
1537
];
SrsAutoFree
(
char
,
c0c1
,
true
);
srs_random_generate
(
c0c1
,
1537
);
// simple handshake
if
((
ret
=
hs_bytes
->
create_c0c1
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// plain text required.
c0c1
[
0
]
=
0x03
;
hs_bytes
->
c0c1
[
0
]
=
0x03
;
if
((
ret
=
skt
->
write
(
c0c1
,
1537
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
io
->
write
(
hs_bytes
->
c0c1
,
1537
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"write c0c1 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"write c0c1 success."
);
char
*
s0s1s2
=
new
char
[
3073
];
SrsAutoFree
(
char
,
s0s1s2
,
true
);
if
((
ret
=
skt
->
read_fully
(
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"simple handshake recv s0s1s2 failed. ret=%d"
,
ret
);
if
((
ret
=
hs_bytes
->
read_s0s1s2
(
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_verbose
(
"simple handshake recv s0s1s2 success."
);
// plain text required.
if
(
s0s1s2
[
0
]
!=
0x03
)
{
if
(
hs_bytes
->
s0s1s2
[
0
]
!=
0x03
)
{
ret
=
ERROR_RTMP_HANDSHAKE
;
srs_warn
(
"handshake failed, plain text required. ret=%d"
,
ret
);
return
ret
;
}
char
*
c2
=
new
char
[
1536
];
SrsAutoFree
(
char
,
c2
,
true
);
srs_random_generate
(
c2
,
1536
);
if
((
ret
=
skt
->
write
(
c2
,
1536
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
hs_bytes
->
create_c2
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
((
ret
=
io
->
write
(
hs_bytes
->
c2
,
1536
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"simple handshake write c2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"simple handshake write c2 success."
);
srs_trace
(
"simple handshake success."
);
srs_trace
(
"simple handshake
with server
success."
);
return
ret
;
}
...
...
@@ -1050,36 +1054,33 @@ SrsComplexHandshake::~SrsComplexHandshake()
}
#ifndef SRS_SSL
int
SrsComplexHandshake
::
handshake_with_client
(
ISrsProtocolReaderWriter
*
/*skt*/
,
char
*
/*_c1
*/
)
int
SrsComplexHandshake
::
handshake_with_client
(
SrsHandshakeBytes
*
/*hs_bytes*/
,
ISrsProtocolReaderWriter
*
/*io
*/
)
{
srs_trace
(
"directly use simple handshake for ssl disabled."
);
return
ERROR_RTMP_TRY_SIMPLE_HS
;
}
#else
int
SrsComplexHandshake
::
handshake_with_client
(
ISrsProtocolReaderWriter
*
skt
,
char
*
_c1
)
int
SrsComplexHandshake
::
handshake_with_client
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
ssize_t
nsize
;
static
bool
_random_initialized
=
false
;
if
(
!
_random_initialized
)
{
srand
(
0
);
_random_initialized
=
true
;
srs_trace
(
"srand initialized the random."
);
if
((
ret
=
hs_bytes
->
read_c0c1
(
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// decode c1
c1s1
c1
;
// try schema0.
if
((
ret
=
c1
.
c1_parse
(
_c
1
,
srs_schema0
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
c1
.
c1_parse
(
hs_bytes
->
c0c1
+
1
,
srs_schema0
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse c1 schema%d error. ret=%d"
,
srs_schema0
,
ret
);
return
ret
;
}
// try schema1
bool
is_valid
=
false
;
if
((
ret
=
c1
.
c1_validate_digest
(
is_valid
))
!=
ERROR_SUCCESS
||
!
is_valid
)
{
if
((
ret
=
c1
.
c1_parse
(
_c
1
,
srs_schema1
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
c1
.
c1_parse
(
hs_bytes
->
c0c1
+
1
,
srs_schema1
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"parse c1 schema%d error. ret=%d"
,
srs_schema1
,
ret
);
return
ret
;
}
...
...
@@ -1102,10 +1103,10 @@ int SrsComplexHandshake::handshake_with_client(ISrsProtocolReaderWriter* skt, ch
// verify s1
if
((
ret
=
s1
.
s1_validate_digest
(
is_valid
))
!=
ERROR_SUCCESS
||
!
is_valid
)
{
ret
=
ERROR_RTMP_TRY_SIMPLE_HS
;
srs_info
(
"v
alid
s1 failed, try simple handshake. ret=%d"
,
ret
);
srs_info
(
"v
erify
s1 failed, try simple handshake. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"verify s1
from c1
success."
);
srs_verbose
(
"verify s1 success."
);
c2s2
s2
;
if
((
ret
=
s2
.
s2_create
(
&
c1
))
!=
ERROR_SUCCESS
)
{
...
...
@@ -1113,40 +1114,56 @@ int SrsComplexHandshake::handshake_with_client(ISrsProtocolReaderWriter* skt, ch
return
ret
;
}
srs_verbose
(
"create s2 from c1 success."
);
// verify s2
if
((
ret
=
s2
.
s2_validate
(
&
c1
,
is_valid
))
!=
ERROR_SUCCESS
||
!
is_valid
)
{
ret
=
ERROR_RTMP_TRY_SIMPLE_HS
;
srs_info
(
"verify s2 failed, try simple handshake. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"verify s2 success."
);
// sendout s0s1s2
char
*
s0s1s2
=
new
char
[
3073
];
SrsAutoFree
(
char
,
s0s1s2
,
true
);
if
((
ret
=
hs_bytes
->
create_s0s1s2
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// plain text required.
s0s1s2
[
0
]
=
0x03
;
s1
.
dump
(
s0s1s2
+
1
);
s2
.
dump
(
s0s1s2
+
1537
);
if
((
ret
=
skt
->
write
(
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
hs_bytes
->
s0s1s2
[
0
]
=
0x03
;
s1
.
dump
(
hs_bytes
->
s0s1s2
+
1
);
s2
.
dump
(
hs_bytes
->
s0s1s2
+
1537
);
if
((
ret
=
io
->
write
(
hs_bytes
->
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"complex handshake send s0s1s2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"complex handshake send s0s1s2 success."
);
// recv c2
char
*
c2
=
new
char
[
1536
];
SrsAutoFree
(
char
,
c2
,
true
);
if
((
ret
=
skt
->
read_fully
(
c2
,
1536
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"complex handshake read c2 failed. ret=%d"
,
ret
);
if
((
ret
=
hs_bytes
->
read_c2
(
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
c2s2
c2
;
c2
.
parse
(
hs_bytes
->
c2
);
srs_verbose
(
"complex handshake read c2 success."
);
// verify c2
if
((
ret
=
c2
.
c2_validate
(
&
s1
,
is_valid
))
!=
ERROR_SUCCESS
||
!
is_valid
)
{
ret
=
ERROR_RTMP_HANDSHAKE
;
srs_trace
(
"verify c2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"verify c2 success."
);
srs_trace
(
"comple handshake with client success"
);
return
ret
;
}
#endif
#ifndef SRS_SSL
int
SrsComplexHandshake
::
handshake_with_server
(
ISrsProtocolReaderWriter
*
/*skt
*/
)
int
SrsComplexHandshake
::
handshake_with_server
(
SrsHandshakeBytes
*
/*hs_bytes*/
,
ISrsProtocolReaderWriter
*
/*io
*/
)
{
return
ERROR_RTMP_TRY_SIMPLE_HS
;
}
#else
int
SrsComplexHandshake
::
handshake_with_server
(
ISrsProtocolReaderWriter
*
/*skt
*/
)
int
SrsComplexHandshake
::
handshake_with_server
(
SrsHandshakeBytes
*
/*hs_bytes*/
,
ISrsProtocolReaderWriter
*
/*io
*/
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
trunk/src/rtmp/srs_protocol_handshake.hpp
查看文件 @
841f0f8
...
...
@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class
ISrsProtocolReaderWriter
;
class
SrsComplexHandshake
;
class
SrsHandshakeBytes
;
/**
* try complex handshake, if failed, fallback to simple handshake.
...
...
@@ -44,12 +45,9 @@ public:
public
:
/**
* simple handshake.
* @param complex_hs, try complex handshake first,
* if NULL, use simple handshake.
* if failed, rollback to simple handshake.
*/
virtual
int
handshake_with_client
(
ISrsProtocolReaderWriter
*
io
,
SrsComplexHandshake
*
complex_hs
);
virtual
int
handshake_with_server
(
ISrsProtocolReaderWriter
*
io
,
SrsComplexHandshake
*
complex_hs
);
virtual
int
handshake_with_client
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
);
virtual
int
handshake_with_server
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
);
};
/**
...
...
@@ -65,15 +63,13 @@ public:
public
:
/**
* complex hanshake.
* @_c1, size of c1 must be 1536.
* @remark, user must free the c1.
* @return user must:
* continue connect app if success,
* try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
* otherwise, disconnect
*/
virtual
int
handshake_with_client
(
ISrsProtocolReaderWriter
*
io
,
char
*
_c1
);
virtual
int
handshake_with_server
(
ISrsProtocolReaderWriter
*
io
);
virtual
int
handshake_with_client
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
);
virtual
int
handshake_with_server
(
SrsHandshakeBytes
*
hs_bytes
,
ISrsProtocolReaderWriter
*
io
);
};
namespace
srs
...
...
@@ -241,6 +237,10 @@ namespace srs
* copy to bytes.
*/
virtual
void
dump
(
char
*
_c2s2
);
/**
* parse the c2s2
*/
virtual
void
parse
(
char
*
_c2s2
);
/**
* create c2.
...
...
@@ -253,6 +253,11 @@ namespace srs
virtual
int
c2_create
(
c1s1
*
s1
);
/**
* validate the c2 from client.
*/
virtual
int
c2_validate
(
c1s1
*
s1
,
bool
&
is_valid
);
/**
* create s2.
* random fill c2s2 1536 bytes
*
...
...
@@ -261,6 +266,11 @@ namespace srs
* s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
*/
virtual
int
s2_create
(
c1s1
*
c1
);
/**
* validate the s2 from server.
*/
virtual
int
s2_validate
(
c1s1
*
c1
,
bool
&
is_valid
);
};
/**
...
...
trunk/src/rtmp/srs_protocol_rtmp.cpp
查看文件 @
841f0f8
...
...
@@ -187,15 +187,131 @@ string srs_client_type_string(SrsClientType type)
return
"Unknown"
;
}
SrsHandshakeBytes
::
SrsHandshakeBytes
()
{
c0c1
=
s0s1s2
=
c2
=
NULL
;
}
SrsHandshakeBytes
::~
SrsHandshakeBytes
()
{
srs_freepa
(
c0c1
);
srs_freepa
(
s0s1s2
);
srs_freepa
(
c2
);
}
int
SrsHandshakeBytes
::
read_c0c1
(
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
c0c1
)
{
return
ret
;
}
ssize_t
nsize
;
c0c1
=
new
char
[
1537
];
if
((
ret
=
io
->
read_fully
(
c0c1
,
1537
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read c0c1 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"read c0c1 success."
);
return
ret
;
}
int
SrsHandshakeBytes
::
read_s0s1s2
(
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
s0s1s2
)
{
return
ret
;
}
ssize_t
nsize
;
c0c1
=
new
char
[
3073
];
if
((
ret
=
io
->
read_fully
(
s0s1s2
,
3073
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read s0s1s2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"read s0s1s2 success."
);
return
ret
;
}
int
SrsHandshakeBytes
::
read_c2
(
ISrsProtocolReaderWriter
*
io
)
{
int
ret
=
ERROR_SUCCESS
;
if
(
c2
)
{
return
ret
;
}
ssize_t
nsize
;
c2
=
new
char
[
1536
];
if
((
ret
=
io
->
read_fully
(
c2
,
1536
,
&
nsize
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read c2 failed. ret=%d"
,
ret
);
return
ret
;
}
srs_verbose
(
"read c2 success."
);
return
ret
;
}
int
SrsHandshakeBytes
::
create_c0c1
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
c0c1
)
{
return
ret
;
}
c0c1
=
new
char
[
1537
];
srs_random_generate
(
c0c1
,
1537
);
return
ret
;
}
int
SrsHandshakeBytes
::
create_s0s1s2
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
s0s1s2
)
{
return
ret
;
}
s0s1s2
=
new
char
[
3073
];
srs_random_generate
(
s0s1s2
,
3073
);
return
ret
;
}
int
SrsHandshakeBytes
::
create_c2
()
{
int
ret
=
ERROR_SUCCESS
;
if
(
c2
)
{
return
ret
;
}
c2
=
new
char
[
1536
];
srs_random_generate
(
c2
,
1536
);
return
ret
;
}
SrsRtmpClient
::
SrsRtmpClient
(
ISrsProtocolReaderWriter
*
skt
)
{
io
=
skt
;
protocol
=
new
SrsProtocol
(
skt
);
hs_bytes
=
new
SrsHandshakeBytes
();
}
SrsRtmpClient
::~
SrsRtmpClient
()
{
srs_freep
(
protocol
);
srs_freep
(
hs_bytes
);
}
void
SrsRtmpClient
::
set_recv_timeout
(
int64_t
timeout_us
)
...
...
@@ -242,12 +358,21 @@ int SrsRtmpClient::handshake()
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
hs_bytes
);
SrsComplexHandshake
complex_hs
;
SrsSimpleHandshake
simple_hs
;
if
((
ret
=
simple_hs
.
handshake_with_server
(
io
,
&
complex_hs
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
complex_hs
.
handshake_with_server
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTMP_TRY_SIMPLE_HS
)
{
SrsSimpleHandshake
simple_hs
;
if
((
ret
=
simple_hs
.
handshake_with_server
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
srs_freep
(
hs_bytes
);
return
ret
;
}
...
...
@@ -255,18 +380,32 @@ int SrsRtmpClient::simple_handshake()
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
hs_bytes
);
SrsSimpleHandshake
simple_hs
;
if
((
ret
=
simple_hs
.
handshake_with_server
(
io
,
NULL
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
simple_hs
.
handshake_with_server
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_freep
(
hs_bytes
);
return
ret
;
}
int
SrsRtmpClient
::
complex_handshake
()
{
// TODO: FIXME: only use complex handshake.
return
handshake
();
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
hs_bytes
);
SrsComplexHandshake
complex_hs
;
if
((
ret
=
complex_hs
.
handshake_with_server
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
srs_freep
(
hs_bytes
);
return
ret
;
}
int
SrsRtmpClient
::
connect_app
(
string
app
,
string
tc_url
)
...
...
@@ -537,11 +676,13 @@ SrsRtmpServer::SrsRtmpServer(ISrsProtocolReaderWriter* skt)
{
io
=
skt
;
protocol
=
new
SrsProtocol
(
skt
);
hs_bytes
=
new
SrsHandshakeBytes
();
}
SrsRtmpServer
::~
SrsRtmpServer
()
{
srs_freep
(
protocol
);
srs_freep
(
hs_bytes
);
}
SrsProtocol
*
SrsRtmpServer
::
get_protocol
()
...
...
@@ -603,12 +744,21 @@ int SrsRtmpServer::handshake()
{
int
ret
=
ERROR_SUCCESS
;
srs_assert
(
hs_bytes
);
SrsComplexHandshake
complex_hs
;
SrsSimpleHandshake
simple_hs
;
if
((
ret
=
simple_hs
.
handshake_with_client
(
io
,
&
complex_hs
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
complex_hs
.
handshake_with_client
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
if
(
ret
==
ERROR_RTMP_TRY_SIMPLE_HS
)
{
SrsSimpleHandshake
simple_hs
;
if
((
ret
=
simple_hs
.
handshake_with_client
(
hs_bytes
,
io
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
return
ret
;
}
srs_freep
(
hs_bytes
);
return
ret
;
}
...
...
trunk/src/rtmp/srs_protocol_rtmp.hpp
查看文件 @
841f0f8
...
...
@@ -109,10 +109,37 @@ enum SrsClientType
std
::
string
srs_client_type_string
(
SrsClientType
type
);
/**
* store the handshake bytes,
* for smart switch between complex and simple handshake.
*/
class
SrsHandshakeBytes
{
public
:
// [1+1536]
char
*
c0c1
;
// [1+1536+1536]
char
*
s0s1s2
;
// [1536]
char
*
c2
;
public
:
SrsHandshakeBytes
();
virtual
~
SrsHandshakeBytes
();
public
:
virtual
int
read_c0c1
(
ISrsProtocolReaderWriter
*
io
);
virtual
int
read_s0s1s2
(
ISrsProtocolReaderWriter
*
io
);
virtual
int
read_c2
(
ISrsProtocolReaderWriter
*
io
);
virtual
int
create_c0c1
();
virtual
int
create_s0s1s2
();
virtual
int
create_c2
();
};
/**
* implements the client role protocol.
*/
class
SrsRtmpClient
{
private
:
SrsHandshakeBytes
*
hs_bytes
;
protected
:
SrsProtocol
*
protocol
;
ISrsProtocolReaderWriter
*
io
;
...
...
@@ -155,6 +182,7 @@ public:
class
SrsRtmpServer
{
private
:
SrsHandshakeBytes
*
hs_bytes
;
SrsProtocol
*
protocol
;
ISrsProtocolReaderWriter
*
io
;
public
:
...
...
trunk/src/rtmp/srs_protocol_utility.cpp
查看文件 @
841f0f8
...
...
@@ -23,6 +23,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_protocol_utility.hpp>
#include <stdlib.h>
#include <srs_kernel_log.hpp>
void
srs_vhost_resolve
(
std
::
string
&
vhost
,
std
::
string
&
app
)
{
app
=
srs_replace
(
app
,
"..."
,
"?"
);
...
...
@@ -46,3 +50,23 @@ void srs_vhost_resolve(std::string& vhost, std::string& app)
}
}
}
void
srs_random_generate
(
char
*
bytes
,
int
size
)
{
static
bool
_random_initialized
=
false
;
if
(
!
_random_initialized
)
{
srand
(
0
);
_random_initialized
=
true
;
srs_trace
(
"srand initialized the random."
);
}
static
char
cdata
[]
=
{
0x73
,
0x69
,
0x6d
,
0x70
,
0x6c
,
0x65
,
0x2d
,
0x72
,
0x74
,
0x6d
,
0x70
,
0x2d
,
0x73
,
0x65
,
0x72
,
0x76
,
0x65
,
0x72
,
0x2d
,
0x77
,
0x69
,
0x6e
,
0x6c
,
0x69
,
0x6e
,
0x2d
,
0x77
,
0x69
,
0x6e
,
0x74
,
0x65
,
0x72
,
0x73
,
0x65
,
0x72
,
0x76
,
0x65
,
0x72
,
0x40
,
0x31
,
0x32
,
0x36
,
0x2e
,
0x63
,
0x6f
,
0x6d
};
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
bytes
[
i
]
=
cdata
[
rand
()
%
(
sizeof
(
cdata
)
-
1
)];
}
}
...
...
trunk/src/rtmp/srs_protocol_utility.hpp
查看文件 @
841f0f8
...
...
@@ -40,4 +40,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// app...vhost...request_vhost
extern
void
srs_vhost_resolve
(
std
::
string
&
vhost
,
std
::
string
&
app
);
extern
void
srs_random_generate
(
char
*
bytes
,
int
size
);
#endif
...
...
请
注册
或
登录
后发表评论