mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
RTC: Remove DTLS utest, cover by regression test
This commit is contained in:
parent
a300d1fc54
commit
ea1f32526a
1 changed files with 0 additions and 613 deletions
|
@ -563,619 +563,6 @@ VOID TEST(KernelRTCTest, StringDumpHexTest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern SSL_CTX* srs_build_dtls_ctx(SrsDtlsVersion version, std::string role);
|
|
||||||
|
|
||||||
class MockDtls
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SSL_CTX* dtls_ctx;
|
|
||||||
SSL* dtls;
|
|
||||||
BIO* bio_in;
|
|
||||||
BIO* bio_out;
|
|
||||||
ISrsDtlsCallback* callback_;
|
|
||||||
bool handshake_done_for_us;
|
|
||||||
SrsDtlsRole role_;
|
|
||||||
SrsDtlsVersion version_;
|
|
||||||
public:
|
|
||||||
MockDtls(ISrsDtlsCallback* callback);
|
|
||||||
virtual ~MockDtls();
|
|
||||||
srs_error_t initialize(std::string role, std::string version);
|
|
||||||
srs_error_t start_active_handshake();
|
|
||||||
srs_error_t on_dtls(char* data, int nb_data);
|
|
||||||
srs_error_t do_handshake();
|
|
||||||
};
|
|
||||||
|
|
||||||
MockDtls::MockDtls(ISrsDtlsCallback* callback)
|
|
||||||
{
|
|
||||||
dtls_ctx = NULL;
|
|
||||||
dtls = NULL;
|
|
||||||
|
|
||||||
callback_ = callback;
|
|
||||||
handshake_done_for_us = false;
|
|
||||||
|
|
||||||
role_ = SrsDtlsRoleServer;
|
|
||||||
version_ = SrsDtlsVersionAuto;
|
|
||||||
}
|
|
||||||
|
|
||||||
MockDtls::~MockDtls()
|
|
||||||
{
|
|
||||||
if (dtls_ctx) {
|
|
||||||
SSL_CTX_free(dtls_ctx);
|
|
||||||
dtls_ctx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dtls) {
|
|
||||||
SSL_free(dtls);
|
|
||||||
dtls = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtls::initialize(std::string role, std::string version)
|
|
||||||
{
|
|
||||||
role_ = SrsDtlsRoleServer;
|
|
||||||
if (role == "active") {
|
|
||||||
role_ = SrsDtlsRoleClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version == "dtls1.0") {
|
|
||||||
version_ = SrsDtlsVersion1_0;
|
|
||||||
} else if (version == "dtls1.2") {
|
|
||||||
version_ = SrsDtlsVersion1_2;
|
|
||||||
} else {
|
|
||||||
version_ = SrsDtlsVersionAuto;
|
|
||||||
}
|
|
||||||
|
|
||||||
dtls_ctx = srs_build_dtls_ctx(version_, role);
|
|
||||||
dtls = SSL_new(dtls_ctx);
|
|
||||||
srs_assert(dtls);
|
|
||||||
|
|
||||||
if (role_ == SrsDtlsRoleClient) {
|
|
||||||
SSL_set_connect_state(dtls);
|
|
||||||
SSL_set_max_send_fragment(dtls, kRtpPacketSize);
|
|
||||||
} else {
|
|
||||||
SSL_set_accept_state(dtls);
|
|
||||||
}
|
|
||||||
|
|
||||||
bio_in = BIO_new(BIO_s_mem());
|
|
||||||
srs_assert(bio_in);
|
|
||||||
|
|
||||||
bio_out = BIO_new(BIO_s_mem());
|
|
||||||
srs_assert(bio_out);
|
|
||||||
|
|
||||||
SSL_set_bio(dtls, bio_in, bio_out);
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtls::start_active_handshake()
|
|
||||||
{
|
|
||||||
if (role_ == SrsDtlsRoleClient) {
|
|
||||||
return do_handshake();
|
|
||||||
}
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtls::on_dtls(char* data, int nb_data)
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
srs_assert(BIO_reset(bio_in) == 1);
|
|
||||||
srs_assert(BIO_reset(bio_out) == 1);
|
|
||||||
srs_assert(BIO_write(bio_in, data, nb_data) > 0);
|
|
||||||
|
|
||||||
if ((err = do_handshake()) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "do handshake");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (BIO_ctrl_pending(bio_in) > 0) {
|
|
||||||
char buf[8092];
|
|
||||||
int nb = SSL_read(dtls, buf, sizeof(buf));
|
|
||||||
if (nb <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = callback_->on_dtls_application_data(buf, nb)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "on DTLS data, size=%u", nb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtls::do_handshake()
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
int r0 = SSL_do_handshake(dtls);
|
|
||||||
int r1 = SSL_get_error(dtls, r0);
|
|
||||||
if (r0 < 0 && (r1 != SSL_ERROR_NONE && r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE)) {
|
|
||||||
return srs_error_new(ERROR_RTC_DTLS, "handshake r0=%d, r1=%d", r0, r1);
|
|
||||||
}
|
|
||||||
if (r1 == SSL_ERROR_NONE) {
|
|
||||||
handshake_done_for_us = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* data = NULL;
|
|
||||||
int size = BIO_get_mem_data(bio_out, &data);
|
|
||||||
|
|
||||||
if (size > 0 && (err = callback_->write_dtls_data(data, size)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "dtls send size=%u", size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handshake_done_for_us) {
|
|
||||||
return callback_->on_dtls_handshake_done();
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
class MockDtlsCallback : virtual public ISrsDtlsCallback, virtual public ISrsCoroutineHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SrsDtls* peer;
|
|
||||||
MockDtls* peer2;
|
|
||||||
SrsCoroutine* trd;
|
|
||||||
srs_error_t r0;
|
|
||||||
bool done;
|
|
||||||
std::vector<SrsSample> samples;
|
|
||||||
public:
|
|
||||||
int nn_client_hello_lost;
|
|
||||||
int nn_server_hello_lost;
|
|
||||||
int nn_certificate_lost;
|
|
||||||
int nn_new_session_lost;
|
|
||||||
int nn_change_cipher_lost;
|
|
||||||
public:
|
|
||||||
// client -> server
|
|
||||||
int nn_client_hello;
|
|
||||||
// server -> client
|
|
||||||
int nn_server_hello;
|
|
||||||
// client -> server
|
|
||||||
int nn_certificate;
|
|
||||||
// server -> client
|
|
||||||
int nn_new_session;
|
|
||||||
int nn_change_cipher;
|
|
||||||
public:
|
|
||||||
MockDtlsCallback();
|
|
||||||
virtual ~MockDtlsCallback();
|
|
||||||
virtual srs_error_t on_dtls_handshake_done();
|
|
||||||
virtual srs_error_t on_dtls_application_data(const char* data, const int len);
|
|
||||||
virtual srs_error_t write_dtls_data(void* data, int size);
|
|
||||||
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
|
|
||||||
virtual srs_error_t cycle();
|
|
||||||
};
|
|
||||||
|
|
||||||
MockDtlsCallback::MockDtlsCallback()
|
|
||||||
{
|
|
||||||
peer = NULL;
|
|
||||||
peer2 = NULL;
|
|
||||||
r0 = srs_success;
|
|
||||||
done = false;
|
|
||||||
trd = new SrsSTCoroutine("mock", this);
|
|
||||||
srs_assert(trd->start() == srs_success);
|
|
||||||
|
|
||||||
nn_client_hello_lost = 0;
|
|
||||||
nn_server_hello_lost = 0;
|
|
||||||
nn_certificate_lost = 0;
|
|
||||||
nn_new_session_lost = 0;
|
|
||||||
nn_change_cipher_lost = 0;
|
|
||||||
|
|
||||||
nn_client_hello = 0;
|
|
||||||
nn_server_hello = 0;
|
|
||||||
nn_certificate = 0;
|
|
||||||
nn_new_session = 0;
|
|
||||||
nn_change_cipher = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MockDtlsCallback::~MockDtlsCallback()
|
|
||||||
{
|
|
||||||
srs_freep(trd);
|
|
||||||
srs_freep(r0);
|
|
||||||
for (vector<SrsSample>::iterator it = samples.begin(); it != samples.end(); ++it) {
|
|
||||||
delete[] it->bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtlsCallback::on_dtls_handshake_done()
|
|
||||||
{
|
|
||||||
done = true;
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtlsCallback::on_dtls_application_data(const char* data, const int len)
|
|
||||||
{
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtlsCallback::write_dtls_data(void* data, int size)
|
|
||||||
{
|
|
||||||
int nn_lost = 0;
|
|
||||||
if (true) {
|
|
||||||
uint8_t content_type = 0;
|
|
||||||
if (size >= 1) {
|
|
||||||
content_type = (uint8_t)((uint8_t*)data)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t handshake_type = 0;
|
|
||||||
if (size >= 14) {
|
|
||||||
handshake_type = (uint8_t)((uint8_t*)data)[13];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content_type == 22) {
|
|
||||||
if (handshake_type == 1) {
|
|
||||||
nn_lost = nn_client_hello_lost--;
|
|
||||||
nn_client_hello++;
|
|
||||||
} else if (handshake_type == 2) {
|
|
||||||
nn_lost = nn_server_hello_lost--;
|
|
||||||
nn_server_hello++;
|
|
||||||
} else if (handshake_type == 11) {
|
|
||||||
nn_lost = nn_certificate_lost--;
|
|
||||||
nn_certificate++;
|
|
||||||
} else if (handshake_type == 4) {
|
|
||||||
nn_lost = nn_new_session_lost--;
|
|
||||||
nn_new_session++;
|
|
||||||
}
|
|
||||||
} else if (content_type == 20) {
|
|
||||||
nn_lost = nn_change_cipher_lost--;
|
|
||||||
nn_change_cipher++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simulate to drop packet.
|
|
||||||
if (nn_lost > 0) {
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send out it.
|
|
||||||
char* cp = new char[size];
|
|
||||||
memcpy(cp, data, size);
|
|
||||||
|
|
||||||
samples.push_back(SrsSample((char*)cp, size));
|
|
||||||
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtlsCallback::on_dtls_alert(std::string type, std::string desc)
|
|
||||||
{
|
|
||||||
return srs_success;
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_error_t MockDtlsCallback::cycle()
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
while (err == srs_success) {
|
|
||||||
if ((err = trd->pull()) != srs_success) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (samples.empty()) {
|
|
||||||
srs_usleep(0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SrsSample p = samples.at(0);
|
|
||||||
samples.erase(samples.begin());
|
|
||||||
|
|
||||||
if (peer) {
|
|
||||||
err = peer->on_dtls((char*)p.bytes, p.size);
|
|
||||||
} else if (peer2) {
|
|
||||||
err = peer2->on_dtls((char*)p.bytes, p.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_freepa(p.bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy it for utest to check it.
|
|
||||||
r0 = srs_error_copy(err);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for mock io to done, try to switch to coroutine many times.
|
|
||||||
void mock_wait_dtls_io_done(SrsDtlsImpl* client_impl, int count = 100, int interval = 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (client_impl) {
|
|
||||||
dynamic_cast<SrsDtlsClientImpl*>(client_impl)->reset_timer_ = true;
|
|
||||||
}
|
|
||||||
srs_usleep(interval * SRS_UTIME_MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To avoid the crash when peer or peer2 is freed before io.
|
|
||||||
class MockBridgeDtlsIO
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
MockDtlsCallback* io_;
|
|
||||||
public:
|
|
||||||
MockBridgeDtlsIO(MockDtlsCallback* io, SrsDtls* peer, MockDtls* peer2) {
|
|
||||||
io_ = io;
|
|
||||||
io->peer = peer;
|
|
||||||
io->peer2 = peer2;
|
|
||||||
}
|
|
||||||
virtual ~MockBridgeDtlsIO() {
|
|
||||||
io_->peer = NULL;
|
|
||||||
io_->peer2 = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VOID TEST(KernelRTCTest, DTLSClientARQTest)
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
// No ARQ, check the number of packets.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
cio.peer = &server; sio.peer = &client;
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(1, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(1, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(1, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(1, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientHello lost, client retransmit the ClientHello.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, &server, NULL); MockBridgeDtlsIO b1(&sio, &client, NULL);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
// Lost 2 packets, total packets should be 3.
|
|
||||||
// Note that only one server hello.
|
|
||||||
cio.nn_client_hello_lost = 1;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(2, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(1, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(1, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(1, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Certificate lost, client retransmit the Certificate.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, &server, NULL); MockBridgeDtlsIO b1(&sio, &client, NULL);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
// Lost 2 packets, total packets should be 3.
|
|
||||||
// Note that only one server NewSessionTicket.
|
|
||||||
cio.nn_certificate_lost = 1;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(1, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(2, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(2, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(0, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelRTCTest, DTLSServerARQTest)
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
// No ARQ, check the number of packets.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
cio.peer = &server; sio.peer = &client;
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(1, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(1, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(1, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(1, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServerHello lost, client retransmit the ClientHello.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, &server, NULL); MockBridgeDtlsIO b1(&sio, &client, NULL);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
// Lost 2 packets, total packets should be 3.
|
|
||||||
sio.nn_server_hello_lost = 1;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(2, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(2, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(1, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(1, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSessionTicket lost, client retransmit the Certificate.
|
|
||||||
if (true) {
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, &server, NULL); MockBridgeDtlsIO b1(&sio, &client, NULL);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", "dtls1.0"));
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", "dtls1.0"));
|
|
||||||
|
|
||||||
// Lost 2 packets, total packets should be 3.
|
|
||||||
sio.nn_new_session_lost = 1;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake());
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
EXPECT_TRUE(sio.r0 == srs_success);
|
|
||||||
EXPECT_TRUE(cio.r0 == srs_success);
|
|
||||||
|
|
||||||
EXPECT_TRUE(cio.done);
|
|
||||||
EXPECT_TRUE(sio.done);
|
|
||||||
|
|
||||||
EXPECT_EQ(1, cio.nn_client_hello);
|
|
||||||
EXPECT_EQ(1, sio.nn_server_hello);
|
|
||||||
EXPECT_EQ(2, cio.nn_certificate);
|
|
||||||
EXPECT_EQ(2, sio.nn_new_session);
|
|
||||||
EXPECT_EQ(0, sio.nn_change_cipher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DTLSFlowCase
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
|
|
||||||
string ClientVersion;
|
|
||||||
string ServerVersion;
|
|
||||||
|
|
||||||
bool ClientDone;
|
|
||||||
bool ServerDone;
|
|
||||||
|
|
||||||
bool ClientError;
|
|
||||||
bool ServerError;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& operator<< (std::ostream& stream, const DTLSFlowCase& c)
|
|
||||||
{
|
|
||||||
stream << "Case #" << c.id
|
|
||||||
<< ", client(" << c.ClientVersion << ",done=" << c.ClientDone << ",err=" << c.ClientError << ")"
|
|
||||||
<< ", server(" << c.ServerVersion << ",done=" << c.ServerDone << ",err=" << c.ServerError << ")";
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelRTCTest, DTLSClientFlowTest)
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
DTLSFlowCase cases[] = {
|
|
||||||
// OK, Client, Server: DTLS v1.0
|
|
||||||
{0, "dtls1.0", "dtls1.0", true, true, false, false},
|
|
||||||
// OK, Client, Server: DTLS v1.2
|
|
||||||
{1, "dtls1.2", "dtls1.2", true, true, false, false},
|
|
||||||
// OK, Client: DTLS v1.0, Server: DTLS auto(v1.0 or v1.2).
|
|
||||||
{2, "dtls1.0", "auto", true, true, false, false},
|
|
||||||
// OK, Client: DTLS v1.2, Server: DTLS auto(v1.0 or v1.2).
|
|
||||||
{3, "dtls1.2", "auto", true, true, false, false},
|
|
||||||
// OK, Client: DTLS auto(v1.0 or v1.2), Server: DTLS v1.0
|
|
||||||
{4, "auto", "dtls1.0", true, true, false, false},
|
|
||||||
// OK, Client: DTLS auto(v1.0 or v1.2), Server: DTLS v1.0
|
|
||||||
{5, "auto", "dtls1.2", true, true, false, false},
|
|
||||||
// OK?, Client: DTLS v1.0, Server: DTLS v1.2
|
|
||||||
{6, "dtls1.0", "dtls1.2", true, true, false, false},
|
|
||||||
// OK?, Client: DTLS v1.2, Server: DTLS v1.0
|
|
||||||
{7, "dtls1.2", "dtls1.0", true, true, false, false},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)(sizeof(cases) / sizeof(DTLSFlowCase)); i++) {
|
|
||||||
DTLSFlowCase c = cases[i];
|
|
||||||
|
|
||||||
MockDtlsCallback cio; SrsDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; MockDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, NULL, &server); MockBridgeDtlsIO b1(&sio, &client, NULL);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", c.ClientVersion)) << c;
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", c.ServerVersion)) << c;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake()) << c;
|
|
||||||
mock_wait_dtls_io_done(client.impl, 15, 5);
|
|
||||||
|
|
||||||
// Note that the cio error is generated from server, vice versa.
|
|
||||||
EXPECT_EQ(c.ClientDone, cio.done) << c;
|
|
||||||
EXPECT_EQ(c.ServerDone, sio.done) << c;
|
|
||||||
|
|
||||||
EXPECT_EQ(c.ClientError, sio.r0 != srs_success) << c;
|
|
||||||
EXPECT_EQ(c.ServerError, cio.r0 != srs_success) << c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelRTCTest, DTLSServerFlowTest)
|
|
||||||
{
|
|
||||||
srs_error_t err = srs_success;
|
|
||||||
|
|
||||||
DTLSFlowCase cases[] = {
|
|
||||||
// OK, Client, Server: DTLS v1.0
|
|
||||||
{0, "dtls1.0", "dtls1.0", true, true, false, false},
|
|
||||||
// OK, Client, Server: DTLS v1.2
|
|
||||||
{1, "dtls1.2", "dtls1.2", true, true, false, false},
|
|
||||||
// OK, Client: DTLS v1.0, Server: DTLS auto(v1.0 or v1.2).
|
|
||||||
{2, "dtls1.0", "auto", true, true, false, false},
|
|
||||||
// OK, Client: DTLS v1.2, Server: DTLS auto(v1.0 or v1.2).
|
|
||||||
{3, "dtls1.2", "auto", true, true, false, false},
|
|
||||||
// OK, Client: DTLS auto(v1.0 or v1.2), Server: DTLS v1.0
|
|
||||||
{4, "auto", "dtls1.0", true, true, false, false},
|
|
||||||
// OK, Client: DTLS auto(v1.0 or v1.2), Server: DTLS v1.0
|
|
||||||
{5, "auto", "dtls1.2", true, true, false, false},
|
|
||||||
// OK?, Client: DTLS v1.0, Server: DTLS v1.2
|
|
||||||
{6, "dtls1.0", "dtls1.2", true, true, false, false},
|
|
||||||
// OK?, Client: DTLS v1.2, Server: DTLS v1.0
|
|
||||||
{7, "dtls1.2", "dtls1.0", true, true, false, false},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)(sizeof(cases) / sizeof(DTLSFlowCase)); i++) {
|
|
||||||
DTLSFlowCase c = cases[i];
|
|
||||||
|
|
||||||
MockDtlsCallback cio; MockDtls client(&cio);
|
|
||||||
MockDtlsCallback sio; SrsDtls server(&sio);
|
|
||||||
MockBridgeDtlsIO b0(&cio, &server, NULL); MockBridgeDtlsIO b1(&sio, NULL, &client);
|
|
||||||
HELPER_EXPECT_SUCCESS(client.initialize("active", c.ClientVersion)) << c;
|
|
||||||
HELPER_EXPECT_SUCCESS(server.initialize("passive", c.ServerVersion)) << c;
|
|
||||||
|
|
||||||
HELPER_EXPECT_SUCCESS(client.start_active_handshake()) << c;
|
|
||||||
mock_wait_dtls_io_done(NULL, 15, 5);
|
|
||||||
|
|
||||||
// Note that the cio error is generated from server, vice versa.
|
|
||||||
EXPECT_EQ(c.ClientDone, cio.done) << c;
|
|
||||||
EXPECT_EQ(c.ServerDone, sio.done) << c;
|
|
||||||
|
|
||||||
EXPECT_EQ(c.ClientError, sio.r0 != srs_success) << c;
|
|
||||||
EXPECT_EQ(c.ServerError, cio.r0 != srs_success) << c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID TEST(KernelRTCTest, SequenceCompare)
|
VOID TEST(KernelRTCTest, SequenceCompare)
|
||||||
{
|
{
|
||||||
if (true) {
|
if (true) {
|
||||||
|
|
Loading…
Reference in a new issue