For #1042, cover RTMP handshake protocol.

pull/1568/head
winlin 5 years ago
parent 7bd7e1ccca
commit f51f1efe42

@ -145,6 +145,7 @@ For previous versions, please read:
## V3 changes
* v3.0, 2019-12-11, For [#1042][bug #1042], cover RTMP handshake protocol.
* v3.0, 2019-12-11, Fix [#1229][bug #1229], fix the security risk in logger. 3.0.69
* v3.0, 2019-12-11, For [#1229][bug #1229], fix the security risk in HDS. 3.0.69
* v3.0, 2019-12-05, Fix [#1506][bug #1501], support directly turn FLV timestamp to TS DTS. 3.0.68
@ -1513,6 +1514,7 @@ Winlin
[bug #1093]: https://github.com/ossrs/srs/issues/1093
[bug #1501]: https://github.com/ossrs/srs/issues/1501
[bug #1229]: https://github.com/ossrs/srs/issues/1229
[bug #1042]: https://github.com/ossrs/srs/issues/1042
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
[exo #828]: https://github.com/google/ExoPlayer/pull/828

@ -1671,7 +1671,7 @@ void SrsHandshakeBytes::dispose()
srs_freepa(c2);
}
srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReadWriter* io)
srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReader* io)
{
srs_error_t err = srs_success;
@ -1709,7 +1709,7 @@ srs_error_t SrsHandshakeBytes::read_c0c1(ISrsProtocolReadWriter* io)
return err;
}
srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReadWriter* io)
srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReader* io)
{
srs_error_t err = srs_success;
@ -1727,7 +1727,7 @@ srs_error_t SrsHandshakeBytes::read_s0s1s2(ISrsProtocolReadWriter* io)
return err;
}
srs_error_t SrsHandshakeBytes::read_c2(ISrsProtocolReadWriter* io)
srs_error_t SrsHandshakeBytes::read_c2(ISrsProtocolReader* io)
{
srs_error_t err = srs_success;

@ -49,6 +49,7 @@ class SrsChunkStream;
class SrsSharedPtrMessage;
class SrsProtocol;
class ISrsProtocolReader;
class ISrsProtocolReadWriter;
class SrsCreateStreamPacket;
class SrsFMLEStartPacket;
@ -514,9 +515,9 @@ public:
public:
virtual void dispose();
public:
virtual srs_error_t read_c0c1(ISrsProtocolReadWriter* io);
virtual srs_error_t read_s0s1s2(ISrsProtocolReadWriter* io);
virtual srs_error_t read_c2(ISrsProtocolReadWriter* io);
virtual srs_error_t read_c0c1(ISrsProtocolReader* io);
virtual srs_error_t read_s0s1s2(ISrsProtocolReader* io);
virtual srs_error_t read_c2(ISrsProtocolReader* io);
virtual srs_error_t create_c0c1();
virtual srs_error_t create_s0s1s2(const char* c1 = NULL);
virtual srs_error_t create_c2();

@ -52,6 +52,10 @@ extern srs_utime_t _srs_tmp_timeout;
#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err)
#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err)
// For init array data.
#define HELPER_ARRAY_INIT(buf, sz, val) \
for (int i = 0; i < (int)sz; i++) (buf)[i]=val
// the asserts of gtest:
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2

@ -64,14 +64,11 @@ VOID TEST(CoreMacroseTest, Check)
#endif
}
#define _ARRAY_INIT(buf, sz, val) \
for (int i = 0; i < (int)sz; i++) buf[i]=val
VOID TEST(CoreLogger, CheckVsnprintf)
{
if (true) {
char buf[1024];
_ARRAY_INIT(buf, sizeof(buf), 0xf);
HELPER_ARRAY_INIT(buf, sizeof(buf), 0xf);
// Return the number of characters printed.
EXPECT_EQ(6, sprintf(buf, "%s", "Hello!"));
@ -83,7 +80,7 @@ VOID TEST(CoreLogger, CheckVsnprintf)
if (true) {
char buf[1024];
_ARRAY_INIT(buf, sizeof(buf), 0xf);
HELPER_ARRAY_INIT(buf, sizeof(buf), 0xf);
// Return the number of characters that would have been printed if the size were unlimited.
EXPECT_EQ(6, snprintf(buf, 3, "%s", "Hello!"));

@ -108,6 +108,22 @@ MockBufferIO* MockBufferIO::append(string data)
return this;
}
MockBufferIO* MockBufferIO::append(uint8_t* data, int size)
{
in_buffer.append((char*)data, size);
return this;
}
int MockBufferIO::in_length()
{
return in_buffer.length();
}
int MockBufferIO::out_length()
{
return out_buffer.length();
}
srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
{
if (in_err != srs_success) {

@ -88,6 +88,9 @@ public:
virtual ~MockBufferIO();
public:
virtual MockBufferIO* append(std::string data);
virtual MockBufferIO* append(uint8_t* data, int size);
virtual int in_length();
virtual int out_length();
// for handshake.
public:
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);

@ -1265,3 +1265,188 @@ VOID TEST(ProtoStackTest, RecvMessage4)
}
}
VOID TEST(ProtoStackTest, HandshakeC0C1)
{
srs_error_t err;
// Fail for empty io.
if (true) {
MockBufferIO io;
SrsHandshakeBytes hs;
HELPER_EXPECT_FAILED(hs.read_c0c1(&io));
}
// It's normal c0c1, so it should be ok.
if (true) {
uint8_t buf[1537];
HELPER_ARRAY_INIT(buf, 1537, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c0c1(&io));
}
// It's extended c0c1 prefixed with ip, which should be ok.
if (true) {
uint8_t buf[1537 + 7] = {
0xF3, 0x00, 0x04,
0x01, 0x02, 0x03, 0x04,
};
HELPER_ARRAY_INIT(buf+7, 1537, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c0c1(&io));
EXPECT_EQ(0x01020304, hs.proxy_real_ip);
}
// It seems a normal c0c1, but it's extended, so it fail.
if (true) {
uint8_t buf[1537] = {
0xF3, 0x04, 0x01,
0x01, 0x02, 0x03, 0x04,
};
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_FAILED(hs.read_c0c1(&io));
}
// For extended c0c1, it fail for not enough bytes.
if (true) {
uint8_t buf[7 + 1537 - 1] = {
0xF3, 0x00, 0x04,
0x01, 0x02, 0x03, 0x04,
};
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_FAILED(hs.read_c0c1(&io));
}
// Ignore when c0c1 exists.
if (true) {
uint8_t buf[1537];
HELPER_ARRAY_INIT(buf, 1537, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c0c1(&io));
io.append(buf, sizeof(buf));
HELPER_EXPECT_SUCCESS(hs.read_c0c1(&io));
EXPECT_EQ(1537, io.in_length());
}
}
VOID TEST(ProtoStackTest, HandshakeS0S1S2)
{
srs_error_t err;
// It should be ok for normal s0s1s2.
if (true) {
uint8_t buf[3073];
HELPER_ARRAY_INIT(buf, 3073, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_s0s1s2(&io));
}
// Fail for not enough data.
if (true) {
uint8_t buf[3073-1];
HELPER_ARRAY_INIT(buf, 3073-1, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_FAILED(hs.read_s0s1s2(&io));
}
// Ignore for s0s1s2 exists.
if (true) {
uint8_t buf[3073];
HELPER_ARRAY_INIT(buf, 3073, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_s0s1s2(&io));
io.append(buf, sizeof(buf));
HELPER_EXPECT_SUCCESS(hs.read_s0s1s2(&io));
EXPECT_EQ(3073, io.in_length());
}
}
VOID TEST(ProtoStackTest, HandshakeC2)
{
srs_error_t err;
// It should be ok for normal c2.
if (true) {
uint8_t buf[1536];
HELPER_ARRAY_INIT(buf, 1536, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c2(&io));
}
// Fail for not enough bytes.
if (true) {
uint8_t buf[1536-1];
HELPER_ARRAY_INIT(buf, 1536-1, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_FAILED(hs.read_c2(&io));
}
// Ignore when c2 exists.
if (true) {
uint8_t buf[1536];
HELPER_ARRAY_INIT(buf, 1536, 0x00);
MockBufferIO io;
io.append(buf, sizeof(buf));
SrsHandshakeBytes hs;
HELPER_EXPECT_SUCCESS(hs.read_c2(&io));
io.append(buf, sizeof(buf));
HELPER_EXPECT_SUCCESS(hs.read_c2(&io));
EXPECT_EQ(1536, io.in_buffer.length());
}
}
VOID TEST(ProtoStackTest, ServerInfo)
{
SrsServerInfo si;
EXPECT_EQ(0, si.pid);
EXPECT_EQ(0, si.cid);
EXPECT_EQ(0, si.major);
EXPECT_EQ(0, si.minor);
EXPECT_EQ(0, si.revision);
EXPECT_EQ(0, si.build);
}

Loading…
Cancel
Save