1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Merge branch 'master' of github.com:winlinvip/simple-rtmp-server

This commit is contained in:
winlin 2014-03-20 09:41:13 +08:00
commit c63ad48893
11 changed files with 1170 additions and 1020 deletions

View file

@ -167,6 +167,8 @@ See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-serv
* nginx v1.5.0: 139524 lines <br/> * nginx v1.5.0: 139524 lines <br/>
### History ### History
* v1.0, 2014-03-19, add vn/an for FFMPEG to drop video/audio for radio stream.
* v1.0, 2014-03-19, refine handshake, client support coplex handshake, add utest.
* v1.0, 2014-03-16, support ARM([debian armhf, v7cpu](https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLinuxArm)) with rtmp/ssl/hls/librtmp. * v1.0, 2014-03-16, support ARM([debian armhf, v7cpu](https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLinuxArm)) with rtmp/ssl/hls/librtmp.
* v1.0, 2014-03-12, finish utest for amf0 codec. * v1.0, 2014-03-12, finish utest for amf0 codec.
* v1.0, 2014-03-06, add gperftools for mem leak detect, mem/cpu profile. * v1.0, 2014-03-06, add gperftools for mem leak detect, mem/cpu profile.

21
trunk/conf/full.conf Normal file → Executable file
View file

@ -291,6 +291,25 @@ vhost audio.transcode.vhost.com {
} }
} }
} }
# disable video, transcode/copy audio.
# for example, publish pure audio stream.
vhost vn.transcode.vhost.com {
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine vn {
enabled on;
vcodec vn;
acodec libaacplus;
abitrate 45;
asample_rate 44100;
achannels 2;
aparams {
}
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
}
}
}
# ffmpeg-copy(forward implements by ffmpeg). # ffmpeg-copy(forward implements by ffmpeg).
# copy the video and audio to a new stream. # copy the video and audio to a new stream.
vhost copy.transcode.vhost.com { vhost copy.transcode.vhost.com {
@ -333,6 +352,7 @@ vhost all.transcode.vhost.com {
# video encoder name. can be: # video encoder name. can be:
# libx264: use h.264(libx264) video encoder. # libx264: use h.264(libx264) video encoder.
# copy: donot encoder the video stream, copy it. # copy: donot encoder the video stream, copy it.
# vn: disable video output.
vcodec libx264; vcodec libx264;
# video bitrate, in kbps # video bitrate, in kbps
vbitrate 1500; vbitrate 1500;
@ -364,6 +384,7 @@ vhost all.transcode.vhost.com {
# audio encoder name. can be: # audio encoder name. can be:
# libaacplus: use aac(libaacplus) audio encoder. # libaacplus: use aac(libaacplus) audio encoder.
# copy: donot encoder the audio stream, copy it. # copy: donot encoder the audio stream, copy it.
# an: disable audio output.
acodec libaacplus; acodec libaacplus;
# audio bitrate, in kbps. [16, 72] for libaacplus. # audio bitrate, in kbps. [16, 72] for libaacplus.
abitrate 70; abitrate 70;

0
trunk/conf/srs.conf Normal file → Executable file
View file

View file

@ -42,6 +42,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef SRS_FFMPEG #ifdef SRS_FFMPEG
#define SRS_ENCODER_COPY "copy" #define SRS_ENCODER_COPY "copy"
#define SRS_ENCODER_NO_VIDEO "vn"
#define SRS_ENCODER_NO_AUDIO "an"
#define SRS_ENCODER_VCODEC "libx264" #define SRS_ENCODER_VCODEC "libx264"
#define SRS_ENCODER_ACODEC "libaacplus" #define SRS_ENCODER_ACODEC "libaacplus"
@ -138,7 +140,13 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine)
} }
_transcoded_url.push_back(output); _transcoded_url.push_back(output);
if (vcodec != SRS_ENCODER_COPY) { if (vcodec == SRS_ENCODER_NO_VIDEO && acodec == SRS_ENCODER_NO_AUDIO) {
ret = ERROR_ENCODER_VCODEC;
srs_warn("video and audio disabled. ret=%d", ret);
return ret;
}
if (vcodec != SRS_ENCODER_COPY && vcodec != SRS_ENCODER_NO_VIDEO) {
if (vcodec != SRS_ENCODER_VCODEC) { if (vcodec != SRS_ENCODER_VCODEC) {
ret = ERROR_ENCODER_VCODEC; ret = ERROR_ENCODER_VCODEC;
srs_error("invalid vcodec, must be %s, actual %s, ret=%d", srs_error("invalid vcodec, must be %s, actual %s, ret=%d",
@ -182,7 +190,7 @@ int SrsFFMPEG::initialize(SrsRequest* req, SrsConfDirective* engine)
} }
} }
if (acodec != SRS_ENCODER_COPY) { if (acodec != SRS_ENCODER_COPY && acodec != SRS_ENCODER_NO_AUDIO) {
if (acodec != SRS_ENCODER_ACODEC) { if (acodec != SRS_ENCODER_ACODEC) {
ret = ERROR_ENCODER_ACODEC; ret = ERROR_ENCODER_ACODEC;
srs_error("invalid acodec, must be %s, actual %s, ret=%d", srs_error("invalid acodec, must be %s, actual %s, ret=%d",
@ -254,11 +262,15 @@ int SrsFFMPEG::start()
} }
// video specified. // video specified.
if (vcodec != SRS_ENCODER_NO_VIDEO) {
params.push_back("-vcodec"); params.push_back("-vcodec");
params.push_back(vcodec); params.push_back(vcodec);
} else {
params.push_back("-vn");
}
// the codec params is disabled when copy // the codec params is disabled when copy
if (vcodec != SRS_ENCODER_COPY) { if (vcodec != SRS_ENCODER_COPY && vcodec != SRS_ENCODER_NO_VIDEO) {
params.push_back("-b:v"); params.push_back("-b:v");
snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000); snprintf(tmp, sizeof(tmp), "%d", vbitrate * 1000);
params.push_back(tmp); params.push_back(tmp);
@ -299,11 +311,15 @@ int SrsFFMPEG::start()
} }
// audio specified. // audio specified.
if (acodec != SRS_ENCODER_NO_AUDIO) {
params.push_back("-acodec"); params.push_back("-acodec");
params.push_back(acodec); params.push_back(acodec);
} else {
params.push_back("-an");
}
// the codec params is disabled when copy // the codec params is disabled when copy
if (acodec != SRS_ENCODER_COPY) { if (acodec != SRS_ENCODER_COPY && acodec != SRS_ENCODER_NO_AUDIO) {
params.push_back("-b:a"); params.push_back("-b:a");
snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000); snprintf(tmp, sizeof(tmp), "%d", abitrate * 1000);
params.push_back(tmp); params.push_back(tmp);

View file

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version // current release version
#define VERSION_MAJOR "0" #define VERSION_MAJOR "0"
#define VERSION_MINOR "9" #define VERSION_MINOR "9"
#define VERSION_REVISION "21" #define VERSION_REVISION "22"
#define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
// server info. // server info.
#define RTMP_SIG_SRS_KEY "srs" #define RTMP_SIG_SRS_KEY "srs"

View file

@ -32,12 +32,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_protocol_utility.hpp> #include <srs_protocol_utility.hpp>
#include <srs_protocol_rtmp.hpp> #include <srs_protocol_rtmp.hpp>
using namespace srs;
#ifdef SRS_SSL #ifdef SRS_SSL
using namespace srs;
// for openssl_HMACsha256
#include <openssl/evp.h>
#include <openssl/hmac.h>
// for __openssl_generate_key
#include <openssl/dh.h>
namespace srs
{
// 68bytes FMS key which is used to sign the sever packet. // 68bytes FMS key which is used to sign the sever packet.
u_int8_t srs::SrsGenuineFMSKey[] = { u_int8_t SrsGenuineFMSKey[] = {
0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20,
0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c,
0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69,
@ -50,7 +58,7 @@ u_int8_t srs::SrsGenuineFMSKey[] = {
}; // 68 }; // 68
// 62bytes FP key which is used to sign the client packet. // 62bytes FP key which is used to sign the client packet.
u_int8_t srs::SrsGenuineFPKey[] = { u_int8_t SrsGenuineFPKey[] = {
0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20, 0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20,
0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C,
0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79, 0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79,
@ -61,9 +69,7 @@ u_int8_t srs::SrsGenuineFPKey[] = {
0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
}; // 62 }; // 62
#include <openssl/evp.h> int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest)
#include <openssl/hmac.h>
int srs::openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest)
{ {
HMAC_CTX ctx; HMAC_CTX ctx;
@ -83,7 +89,6 @@ int srs::openssl_HMACsha256(const void* data, int data_size, const void* key, in
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
#include <openssl/dh.h>
#define RFC2409_PRIME_1024 \ #define RFC2409_PRIME_1024 \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
@ -92,7 +97,7 @@ int srs::openssl_HMACsha256(const void* data, int data_size, const void* key, in
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
"FFFFFFFFFFFFFFFF" "FFFFFFFFFFFFFFFF"
int __openssl_generate_key( int __openssl_generate_key(
u_int8_t*& _private_key, u_int8_t*& _public_key, int32_t& size, u_int8_t* _private_key, u_int8_t* _public_key, int32_t& size,
DH*& pdh, int32_t& bits_count, u_int8_t*& shared_key, int32_t& shared_key_length, BIGNUM*& peer_public_key DH*& pdh, int32_t& bits_count, u_int8_t*& shared_key, int32_t& shared_key_length, BIGNUM*& peer_public_key
){ ){
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -195,7 +200,7 @@ int openssl_generate_key(char* _private_key, char* _public_key, int32_t size)
BIGNUM* peer_public_key = NULL; BIGNUM* peer_public_key = NULL;
ret = __openssl_generate_key( ret = __openssl_generate_key(
(u_int8_t*&)_private_key, (u_int8_t*&)_public_key, size, (u_int8_t*)_private_key, (u_int8_t*)_public_key, size,
pdh, bits_count, shared_key, shared_key_length, peer_public_key pdh, bits_count, shared_key, shared_key_length, peer_public_key
); );
@ -240,6 +245,7 @@ int srs_key_block_get_offset(key_block* key)
return offset % max_offset_size; return offset % max_offset_size;
} }
// create new key block data. // create new key block data.
// if created, user must free it by srs_key_block_free // if created, user must free it by srs_key_block_free
void srs_key_block_init(key_block* key) void srs_key_block_init(key_block* key)
@ -265,6 +271,7 @@ void srs_key_block_init(key_block* key)
srs_random_generate(key->random1, key->random1_size); srs_random_generate(key->random1, key->random1_size);
} }
} }
// parse key block from c1s1. // parse key block from c1s1.
// if created, user must free it by srs_key_block_free // if created, user must free it by srs_key_block_free
// @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764 // @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764
@ -302,6 +309,7 @@ int srs_key_block_parse(key_block* key, char* c1s1_key_bytes)
return ret; return ret;
} }
// free the block data create by // free the block data create by
// srs_key_block_init or srs_key_block_parse // srs_key_block_init or srs_key_block_parse
void srs_key_block_free(key_block* key) void srs_key_block_free(key_block* key)
@ -329,6 +337,7 @@ int srs_digest_block_get_offset(digest_block* digest)
return offset % max_offset_size; return offset % max_offset_size;
} }
// create new digest block data. // create new digest block data.
// if created, user must free it by srs_digest_block_free // if created, user must free it by srs_digest_block_free
void srs_digest_block_init(digest_block* digest) void srs_digest_block_init(digest_block* digest)
@ -354,6 +363,7 @@ void srs_digest_block_init(digest_block* digest)
srs_random_generate(digest->random1, digest->random1_size); srs_random_generate(digest->random1, digest->random1_size);
} }
} }
// parse digest block from c1s1. // parse digest block from c1s1.
// if created, user must free it by srs_digest_block_free // if created, user must free it by srs_digest_block_free
// @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764 // @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764
@ -390,6 +400,7 @@ int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes)
return ret; return ret;
} }
// free the block data create by // free the block data create by
// srs_digest_block_init or srs_digest_block_parse // srs_digest_block_init or srs_digest_block_parse
void srs_digest_block_free(digest_block* digest) void srs_digest_block_free(digest_block* digest)
@ -500,7 +511,7 @@ void srs_schema1_copy_to(char* bytes, bool with_digest,
* digest-data: 32bytes * digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2) * c1s1-part2: (1536-n-32)bytes (digest-part2)
*/ */
char* srs::srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest) char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest)
{ {
char* bytes = new char[1536 -32]; char* bytes = new char[1536 -32];
@ -515,7 +526,7 @@ char* srs::srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key,
* digest-data: 32bytes * digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2 and key) * c1s1-part2: (1536-n-32)bytes (digest-part2 and key)
*/ */
char* srs::srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key) char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key)
{ {
char* bytes = new char[1536 -32]; char* bytes = new char[1536 -32];
@ -527,11 +538,19 @@ char* srs::srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* d
/** /**
* compare the memory in bytes. * compare the memory in bytes.
*/ */
bool srs::srs_bytes_equals(void* pa, void* pb, int size) bool srs_bytes_equals(void* pa, void* pb, int size)
{ {
u_int8_t* a = (u_int8_t*)pa; u_int8_t* a = (u_int8_t*)pa;
u_int8_t* b = (u_int8_t*)pb; u_int8_t* b = (u_int8_t*)pb;
if (!a && !b) {
return true;
}
if (!a || !b) {
return false;
}
for(int i = 0; i < size; i++){ for(int i = 0; i < size; i++){
if(a[i] != b[i]){ if(a[i] != b[i]){
return false; return false;
@ -952,6 +971,7 @@ void c1s1::destroy_blocks()
srs_key_block_free(&block1.key); srs_key_block_free(&block1.key);
} }
} }
}
#endif #endif
@ -1144,13 +1164,10 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrs
c2s2 c2; c2s2 c2;
c2.parse(hs_bytes->c2); c2.parse(hs_bytes->c2);
srs_verbose("complex handshake read c2 success."); srs_verbose("complex handshake read c2 success.");
// verify c2 // verify c2
if ((ret = c2.c2_validate(&s1, is_valid)) != ERROR_SUCCESS || !is_valid) { // never verify c2, for ffmpeg will failed.
ret = ERROR_RTMP_HANDSHAKE; // it's ok for flash.
srs_trace("verify c2 failed. ret=%d", ret);
return ret;
}
srs_verbose("verify c2 success.");
srs_trace("comple handshake with client success"); srs_trace("comple handshake with client success");

View file

@ -97,6 +97,78 @@ namespace srs
int random1_size; int random1_size;
}; };
// the digest key generate size.
#define OpensslHashSize 512
extern u_int8_t SrsGenuineFMSKey[];
extern u_int8_t SrsGenuineFPKey[];
int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest);
int openssl_generate_key(char* _private_key, char* _public_key, int32_t size);
// calc the offset of key,
// the key->offset cannot be used as the offset of key.
int srs_key_block_get_offset(key_block* key);
// create new key block data.
// if created, user must free it by srs_key_block_free
void srs_key_block_init(key_block* key);
// parse key block from c1s1.
// if created, user must free it by srs_key_block_free
// @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764
int srs_key_block_parse(key_block* key, char* c1s1_key_bytes);
// free the block data create by
// srs_key_block_init or srs_key_block_parse
void srs_key_block_free(key_block* key);
// calc the offset of digest,
// the key->offset cannot be used as the offset of digest.
int srs_digest_block_get_offset(digest_block* digest);
// create new digest block data.
// if created, user must free it by srs_digest_block_free
void srs_digest_block_init(digest_block* digest);
// parse digest block from c1s1.
// if created, user must free it by srs_digest_block_free
// @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764
int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes);
// free the block data create by
// srs_digest_block_init or srs_digest_block_parse
void srs_digest_block_free(digest_block* digest);
/**
* copy whole c1s1 to bytes.
*/
void srs_schema0_copy_to(char* bytes, bool with_digest,
int32_t time, int32_t version, key_block* key, digest_block* digest);
void srs_schema1_copy_to(char* bytes, bool with_digest,
int32_t time, int32_t version, digest_block* digest, key_block* key);
/**
* c1s1 is splited by digest:
* c1s1-part1: n bytes (time, version, key and digest-part1).
* digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2)
* @return a new allocated bytes, user must free it.
*/
char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest);
/**
* c1s1 is splited by digest:
* c1s1-part1: n bytes (time, version and digest-part1).
* digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2 and key)
* @return a new allocated bytes, user must free it.
*/
char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key);
/**
* compare the memory in bytes.
*/
bool srs_bytes_equals(void* pa, void* pb, int size);
/** /**
* c1s1 schema0 * c1s1 schema0
* time: 4bytes * time: 4bytes
@ -236,41 +308,14 @@ namespace srs
*/ */
virtual int s2_validate(c1s1* c1, bool& is_valid); virtual int s2_validate(c1s1* c1, bool& is_valid);
}; };
/**
* compare the memory in bytes.
*/
bool srs_bytes_equals(void* pa, void* pb, int size);
/**
* c1s1 is splited by digest:
* c1s1-part1: n bytes (time, version, key and digest-part1).
* digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2)
* @return a new allocated bytes, user must free it.
*/
char* srs_bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest);
/**
* c1s1 is splited by digest:
* c1s1-part1: n bytes (time, version and digest-part1).
* digest-data: 32bytes
* c1s1-part2: (1536-n-32)bytes (digest-part2 and key)
* @return a new allocated bytes, user must free it.
*/
char* srs_bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key);
// the digest key generate size.
#define OpensslHashSize 512
extern u_int8_t SrsGenuineFMSKey[];
extern u_int8_t SrsGenuineFPKey[];
int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest);
} }
#endif #endif
/** /**
* try complex handshake, if failed, fallback to simple handshake. * simple handshake.
* user can try complex handshake first,
* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
*/ */
class SrsSimpleHandshake class SrsSimpleHandshake
{ {

View file

@ -36,6 +36,77 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext();
SrsConfig* _srs_config = NULL; SrsConfig* _srs_config = NULL;
SrsServer* _srs_server = NULL; SrsServer* _srs_server = NULL;
MockEmptyIO::MockEmptyIO()
{
}
MockEmptyIO::~MockEmptyIO()
{
}
bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/)
{
return true;
}
int MockEmptyIO::read_fully(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
return ERROR_SUCCESS;
}
int MockEmptyIO::write(const void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/)
{
return ERROR_SUCCESS;
}
void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/)
{
}
int64_t MockEmptyIO::get_recv_timeout()
{
return -1;
}
int64_t MockEmptyIO::get_recv_bytes()
{
return -1;
}
int MockEmptyIO::get_recv_kbps()
{
return 0;
}
void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/)
{
}
int64_t MockEmptyIO::get_send_timeout()
{
return 0;
}
int64_t MockEmptyIO::get_send_bytes()
{
return 0;
}
int MockEmptyIO::get_send_kbps()
{
return 0;
}
int MockEmptyIO::writev(const iovec */*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/)
{
return ERROR_SUCCESS;
}
int MockEmptyIO::read(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
return ERROR_SUCCESS;
}
// basic test and samples. // basic test and samples.
VOID TEST(SampleTest, FastSampleInt64Test) VOID TEST(SampleTest, FastSampleInt64Test)
{ {

View file

@ -34,4 +34,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// we add an empty macro for upp to show the smart tips. // we add an empty macro for upp to show the smart tips.
#define VOID #define VOID
#include <srs_protocol_io.hpp>
class MockEmptyIO : public ISrsProtocolReaderWriter
{
public:
MockEmptyIO();
virtual ~MockEmptyIO();
// for protocol
public:
virtual bool is_never_timeout(int64_t timeout_us);
// for handshake.
public:
virtual int read_fully(const void* buf, size_t size, ssize_t* nread);
virtual int write(const void* buf, size_t size, ssize_t* nwrite);
// for protocol
public:
virtual void set_recv_timeout(int64_t timeout_us);
virtual int64_t get_recv_timeout();
virtual int64_t get_recv_bytes();
virtual int get_recv_kbps();
// for protocol
public:
virtual void set_send_timeout(int64_t timeout_us);
virtual int64_t get_send_timeout();
virtual int64_t get_send_bytes();
virtual int get_send_kbps();
virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite);
// for protocol/amf0/msg-codec
public:
virtual int read(const void* buf, size_t size, ssize_t* nread);
};
#endif #endif

View file

@ -24,77 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_kernel_error.hpp> #include <srs_kernel_error.hpp>
#include <srs_core_autofree.hpp> #include <srs_core_autofree.hpp>
#include <srs_protocol_utility.hpp>
MockEmptyIO::MockEmptyIO()
{
}
MockEmptyIO::~MockEmptyIO()
{
}
bool MockEmptyIO::is_never_timeout(int64_t /*timeout_us*/)
{
return true;
}
int MockEmptyIO::read_fully(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
return ERROR_SUCCESS;
}
int MockEmptyIO::write(const void* /*buf*/, size_t /*size*/, ssize_t* /*nwrite*/)
{
return ERROR_SUCCESS;
}
void MockEmptyIO::set_recv_timeout(int64_t /*timeout_us*/)
{
}
int64_t MockEmptyIO::get_recv_timeout()
{
return -1;
}
int64_t MockEmptyIO::get_recv_bytes()
{
return -1;
}
int MockEmptyIO::get_recv_kbps()
{
return 0;
}
void MockEmptyIO::set_send_timeout(int64_t /*timeout_us*/)
{
}
int64_t MockEmptyIO::get_send_timeout()
{
return 0;
}
int64_t MockEmptyIO::get_send_bytes()
{
return 0;
}
int MockEmptyIO::get_send_kbps()
{
return 0;
}
int MockEmptyIO::writev(const iovec */*iov*/, int /*iov_size*/, ssize_t* /*nwrite*/)
{
return ERROR_SUCCESS;
}
int MockEmptyIO::read(const void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/)
{
return ERROR_SUCCESS;
}
// verify the sha256 // verify the sha256
VOID TEST(HandshakeTest, OpensslSha256) VOID TEST(HandshakeTest, OpensslSha256)
@ -124,6 +54,37 @@ VOID TEST(HandshakeTest, OpensslSha256)
EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32)); EXPECT_TRUE(srs_bytes_equals(digest, expect_digest, 32));
} }
// verify the dh key
VOID TEST(HandshakeTest, DHKey)
{
char pri_key[] = {
0x6e, 0x65, 0x69, 0x2d, 0x69, 0x2d, 0x69, 0x73,
0x6e, 0x69, 0x73, 0x6c, 0x65, 0x72, 0x69, 0x72,
0x76, 0x65, 0x72, 0x69, 0x77, 0x74, 0x2e, 0x6e,
0x72, 0x76, 0x72, 0x65, 0x72, 0x70, 0x72, 0x69,
0x69, 0x70, 0x72, 0x73, 0x6e, 0x65, 0x72, 0x72,
0x6e, 0x2d, 0x65, 0x74, 0x72, 0x6c, 0x69, 0x74,
0x69, 0x65, 0x40, 0x69, 0x69, 0x76, 0x77, 0x2d,
0x73, 0x65, 0x72, 0x72, 0x76, 0x73, 0x72, 0x2e,
0x2d, 0x76, 0x65, 0x31, 0x65, 0x6d, 0x6d, 0x73,
0x69, 0x73, 0x74, 0x2e, 0x74, 0x72, 0x65, 0x65,
0x72, 0x65, 0x2d, 0x74, 0x69, 0x31, 0x65, 0x2d,
0x6f, 0x77, 0x2e, 0x76, 0x77, 0x2d, 0x77, 0x72,
0x65, 0x65, 0x31, 0x74, 0x73, 0x70, 0x74, 0x6e,
0x72, 0x6e, 0x73, 0x6d, 0x2e, 0x69, 0x72, 0x2d,
0x65, 0x69, 0x77, 0x69, 0x76, 0x72, 0x77, 0x72,
0x32, 0x6e, 0x65, 0x6c, 0x2e, 0x2d, 0x6e, 0x69
};
char pub_key1[128];
openssl_generate_key(pri_key, pub_key1, 128);
char pub_key2[128];
openssl_generate_key(pri_key, pub_key2, 128);
EXPECT_FALSE(srs_bytes_equals(pub_key1, pub_key2, 128));
}
// flash will sendout a c0c1 encrypt by ssl. // flash will sendout a c0c1 encrypt by ssl.
VOID TEST(HandshakeTest, VerifyFPC0C1) VOID TEST(HandshakeTest, VerifyFPC0C1)
{ {
@ -260,3 +221,19 @@ VOID TEST(HandshakeTest, ComplexHandshake)
ASSERT_TRUE(is_valid); ASSERT_TRUE(is_valid);
} }
} }
VOID TEST(HandshakeTest, BytesEqual)
{
char a1[] = { 0x01 };
char b1[] = { 0x02 };
char a2[] = { 0x01, 0x02 };
char b2[] = { 0x02, 0x03 };
EXPECT_TRUE(srs_bytes_equals(NULL, NULL, 0));
EXPECT_FALSE(srs_bytes_equals(a1, NULL, 1));
EXPECT_FALSE(srs_bytes_equals(NULL, a1, 1));
EXPECT_FALSE(srs_bytes_equals(a1, b1, 1));
EXPECT_TRUE(srs_bytes_equals(a1, a1, 1));
EXPECT_TRUE(srs_bytes_equals(a1, a2, 1));
EXPECT_FALSE(srs_bytes_equals(a1, b2, 1));
}

View file

@ -29,39 +29,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include <srs_utest.hpp> #include <srs_utest.hpp>
#include <srs_protocol_io.hpp>
#include <srs_protocol_rtmp.hpp> #include <srs_protocol_rtmp.hpp>
#include <srs_protocol_handshake.hpp> #include <srs_protocol_handshake.hpp>
using namespace srs; using namespace srs;
class MockEmptyIO : public ISrsProtocolReaderWriter
{
public:
MockEmptyIO();
virtual ~MockEmptyIO();
// for protocol
public:
virtual bool is_never_timeout(int64_t timeout_us);
// for handshake.
public:
virtual int read_fully(const void* buf, size_t size, ssize_t* nread);
virtual int write(const void* buf, size_t size, ssize_t* nwrite);
// for protocol
public:
virtual void set_recv_timeout(int64_t timeout_us);
virtual int64_t get_recv_timeout();
virtual int64_t get_recv_bytes();
virtual int get_recv_kbps();
// for protocol
public:
virtual void set_send_timeout(int64_t timeout_us);
virtual int64_t get_send_timeout();
virtual int64_t get_send_bytes();
virtual int get_send_kbps();
virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite);
// for protocol/amf0/msg-codec
public:
virtual int read(const void* buf, size_t size, ssize_t* nread);
};
#endif #endif