| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 return certificate_; | 74 return certificate_; |
| 75 } | 75 } |
| 76 void SetupSrtp() { | 76 void SetupSrtp() { |
| 77 ASSERT(certificate_); | 77 ASSERT(certificate_); |
| 78 use_dtls_srtp_ = true; | 78 use_dtls_srtp_ = true; |
| 79 } | 79 } |
| 80 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { | 80 void SetupMaxProtocolVersion(rtc::SSLProtocolVersion version) { |
| 81 ASSERT(!transport_); | 81 ASSERT(!transport_); |
| 82 ssl_max_version_ = version; | 82 ssl_max_version_ = version; |
| 83 } | 83 } |
| 84 void SetupChannels(int count, cricket::IceRole role, int async_delay_ms = 0) { | 84 void SetupChannels(int count, cricket::IceRole role) { |
| 85 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( | 85 transport_.reset(new cricket::DtlsTransport<cricket::FakeTransport>( |
| 86 "dtls content name", nullptr, certificate_)); | 86 "dtls content name", nullptr, certificate_)); |
| 87 transport_->SetAsync(true); | 87 transport_->SetAsync(true); |
| 88 transport_->SetAsyncDelay(async_delay_ms); | |
| 89 transport_->SetIceRole(role); | 88 transport_->SetIceRole(role); |
| 90 transport_->SetIceTiebreaker( | 89 transport_->SetIceTiebreaker( |
| 91 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); | 90 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
| 92 | 91 |
| 93 for (int i = 0; i < count; ++i) { | 92 for (int i = 0; i < count; ++i) { |
| 94 cricket::DtlsTransportChannelWrapper* channel = | 93 cricket::DtlsTransportChannelWrapper* channel = |
| 95 static_cast<cricket::DtlsTransportChannelWrapper*>( | 94 static_cast<cricket::DtlsTransportChannelWrapper*>( |
| 96 transport_->CreateChannel(i)); | 95 transport_->CreateChannel(i)); |
| 97 ASSERT_TRUE(channel != NULL); | 96 ASSERT_TRUE(channel != NULL); |
| 98 channel->SetSslMaxProtocolVersion(ssl_max_version_); | 97 channel->SetSslMaxProtocolVersion(ssl_max_version_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 113 cricket::Transport* transport() { return transport_.get(); } | 112 cricket::Transport* transport() { return transport_.get(); } |
| 114 | 113 |
| 115 cricket::FakeTransportChannel* GetFakeChannel(int component) { | 114 cricket::FakeTransportChannel* GetFakeChannel(int component) { |
| 116 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); | 115 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); |
| 117 cricket::DtlsTransportChannelWrapper* wrapper = | 116 cricket::DtlsTransportChannelWrapper* wrapper = |
| 118 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); | 117 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); |
| 119 return (wrapper) ? | 118 return (wrapper) ? |
| 120 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; | 119 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; |
| 121 } | 120 } |
| 122 | 121 |
| 123 cricket::DtlsTransportChannelWrapper* GetDtlsChannel(int component) { | |
| 124 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); | |
| 125 return static_cast<cricket::DtlsTransportChannelWrapper*>(ch); | |
| 126 } | |
| 127 | |
| 128 // Offer DTLS if we have an identity; pass in a remote fingerprint only if | 122 // Offer DTLS if we have an identity; pass in a remote fingerprint only if |
| 129 // both sides support DTLS. | 123 // both sides support DTLS. |
| 130 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, | 124 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, |
| 131 ConnectionRole local_role, ConnectionRole remote_role, | 125 ConnectionRole local_role, ConnectionRole remote_role, |
| 132 int flags) { | 126 int flags) { |
| 133 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, | 127 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, |
| 134 local_role, remote_role, flags); | 128 local_role, remote_role, flags); |
| 135 } | 129 } |
| 136 | 130 |
| 137 void MaybeSetSrtpCryptoSuites() { | 131 void MaybeSetSrtpCryptoSuites() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 151 cricket::ContentAction action, | 145 cricket::ContentAction action, |
| 152 ConnectionRole role, | 146 ConnectionRole role, |
| 153 int flags) { | 147 int flags) { |
| 154 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when | 148 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
| 155 // content action is CA_ANSWER. | 149 // content action is CA_ANSWER. |
| 156 bool expect_success = | 150 bool expect_success = |
| 157 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); | 151 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
| 158 EXPECT_EQ(expect_success, | 152 EXPECT_EQ(expect_success, |
| 159 transport_->SetLocalTransportDescription( | 153 transport_->SetLocalTransportDescription( |
| 160 MakeTransportDescription(cert, role), action, nullptr)); | 154 MakeTransportDescription(cert, role), action, nullptr)); |
| 155 set_local_cert_ = (cert != nullptr); |
| 161 } | 156 } |
| 162 | 157 |
| 163 void SetRemoteTransportDescription( | 158 void SetRemoteTransportDescription( |
| 164 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, | 159 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
| 165 cricket::ContentAction action, | 160 cricket::ContentAction action, |
| 166 ConnectionRole role, | 161 ConnectionRole role, |
| 167 int flags) { | 162 int flags) { |
| 168 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when | 163 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
| 169 // content action is CA_ANSWER. | 164 // content action is CA_ANSWER. |
| 170 bool expect_success = | 165 bool expect_success = |
| 171 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); | 166 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
| 172 EXPECT_EQ(expect_success, | 167 EXPECT_EQ(expect_success, |
| 173 transport_->SetRemoteTransportDescription( | 168 transport_->SetRemoteTransportDescription( |
| 174 MakeTransportDescription(cert, role), action, nullptr)); | 169 MakeTransportDescription(cert, role), action, nullptr)); |
| 170 set_remote_cert_ = (cert != nullptr); |
| 175 } | 171 } |
| 176 | 172 |
| 177 // Allow any DTLS configuration to be specified (including invalid ones). | 173 // Allow any DTLS configuration to be specified (including invalid ones). |
| 178 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, | 174 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, |
| 179 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, | 175 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, |
| 180 cricket::ContentAction action, | 176 cricket::ContentAction action, |
| 181 ConnectionRole local_role, | 177 ConnectionRole local_role, |
| 182 ConnectionRole remote_role, | 178 ConnectionRole remote_role, |
| 183 int flags) { | 179 int flags) { |
| 184 if (!(flags & NF_REOFFER)) { | 180 if (!(flags & NF_REOFFER)) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 return false; | 222 return false; |
| 227 } | 223 } |
| 228 } | 224 } |
| 229 return true; | 225 return true; |
| 230 } | 226 } |
| 231 | 227 |
| 232 int received_dtls_client_hellos() const { | 228 int received_dtls_client_hellos() const { |
| 233 return received_dtls_client_hellos_; | 229 return received_dtls_client_hellos_; |
| 234 } | 230 } |
| 235 | 231 |
| 236 int received_dtls_server_hellos() const { | 232 bool negotiated_dtls() const { return set_local_cert_ && set_remote_cert_; } |
| 237 return received_dtls_server_hellos_; | |
| 238 } | |
| 239 | |
| 240 bool negotiated_dtls() const { | |
| 241 return transport_->local_description() && | |
| 242 transport_->local_description()->identity_fingerprint && | |
| 243 transport_->remote_description() && | |
| 244 transport_->remote_description()->identity_fingerprint; | |
| 245 } | |
| 246 | 233 |
| 247 void CheckRole(rtc::SSLRole role) { | 234 void CheckRole(rtc::SSLRole role) { |
| 248 if (role == rtc::SSL_CLIENT) { | 235 if (role == rtc::SSL_CLIENT) { |
| 249 ASSERT_EQ(0, received_dtls_client_hellos_); | 236 ASSERT_EQ(0, received_dtls_client_hellos_); |
| 250 ASSERT_GT(received_dtls_server_hellos_, 0); | 237 ASSERT_GT(received_dtls_server_hellos_, 0); |
| 251 } else { | 238 } else { |
| 252 ASSERT_GT(received_dtls_client_hellos_, 0); | 239 ASSERT_GT(received_dtls_client_hellos_, 0); |
| 253 ASSERT_EQ(0, received_dtls_server_hellos_); | 240 ASSERT_EQ(0, received_dtls_server_hellos_); |
| 254 } | 241 } |
| 255 } | 242 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 | 404 |
| 418 private: | 405 private: |
| 419 std::string name_; | 406 std::string name_; |
| 420 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 407 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
| 421 std::unique_ptr<cricket::FakeTransport> transport_; | 408 std::unique_ptr<cricket::FakeTransport> transport_; |
| 422 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 409 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
| 423 size_t packet_size_ = 0u; | 410 size_t packet_size_ = 0u; |
| 424 std::set<int> received_; | 411 std::set<int> received_; |
| 425 bool use_dtls_srtp_ = false; | 412 bool use_dtls_srtp_ = false; |
| 426 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 413 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
| 414 bool set_local_cert_ = false; |
| 415 bool set_remote_cert_ = false; |
| 427 int received_dtls_client_hellos_ = 0; | 416 int received_dtls_client_hellos_ = 0; |
| 428 int received_dtls_server_hellos_ = 0; | 417 int received_dtls_server_hellos_ = 0; |
| 429 rtc::SentPacket sent_packet_; | 418 rtc::SentPacket sent_packet_; |
| 430 }; | 419 }; |
| 431 | 420 |
| 432 // Base class for DtlsTransportChannelTest and DtlsEventOrderingTest, which | |
| 433 // inherit from different variants of testing::Test. | |
| 434 // | |
| 435 // Note that this test always uses a FakeClock, due to the |fake_clock_| member | 421 // Note that this test always uses a FakeClock, due to the |fake_clock_| member |
| 436 // variable. | 422 // variable. |
| 437 class DtlsTransportChannelTestBase { | 423 class DtlsTransportChannelTest : public testing::Test { |
| 438 public: | 424 public: |
| 439 DtlsTransportChannelTestBase() | 425 DtlsTransportChannelTest() |
| 440 : client1_("P1"), | 426 : client1_("P1"), |
| 441 client2_("P2"), | 427 client2_("P2"), |
| 442 channel_ct_(1), | 428 channel_ct_(1), |
| 443 use_dtls_(false), | 429 use_dtls_(false), |
| 444 use_dtls_srtp_(false), | 430 use_dtls_srtp_(false), |
| 445 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_12) {} | 431 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_12) {} |
| 446 | 432 |
| 447 void SetChannelCount(size_t channel_ct) { | 433 void SetChannelCount(size_t channel_ct) { |
| 448 channel_ct_ = static_cast<int>(channel_ct); | 434 channel_ct_ = static_cast<int>(channel_ct); |
| 449 } | 435 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | 488 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
| 503 rv = client1_.Connect(&client2_, false); | 489 rv = client1_.Connect(&client2_, false); |
| 504 client1_.SetRemoteTransportDescription( | 490 client1_.SetRemoteTransportDescription( |
| 505 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | 491 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
| 506 } | 492 } |
| 507 | 493 |
| 508 EXPECT_TRUE(rv); | 494 EXPECT_TRUE(rv); |
| 509 if (!rv) | 495 if (!rv) |
| 510 return false; | 496 return false; |
| 511 | 497 |
| 512 EXPECT_TRUE_SIMULATED_WAIT( | 498 EXPECT_TRUE_WAIT( |
| 513 client1_.all_channels_writable() && client2_.all_channels_writable(), | 499 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 514 kTimeout, fake_clock_); | 500 kTimeout); |
| 515 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) | 501 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
| 516 return false; | 502 return false; |
| 517 | 503 |
| 518 // Check that we used the right roles. | 504 // Check that we used the right roles. |
| 519 if (use_dtls_) { | 505 if (use_dtls_) { |
| 520 rtc::SSLRole client1_ssl_role = | 506 rtc::SSLRole client1_ssl_role = |
| 521 (client1_role == cricket::CONNECTIONROLE_ACTIVE || | 507 (client1_role == cricket::CONNECTIONROLE_ACTIVE || |
| 522 (client2_role == cricket::CONNECTIONROLE_PASSIVE && | 508 (client2_role == cricket::CONNECTIONROLE_PASSIVE && |
| 523 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? | 509 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? |
| 524 rtc::SSL_CLIENT : rtc::SSL_SERVER; | 510 rtc::SSL_CLIENT : rtc::SSL_SERVER; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 client2_role, client1_role, flags); | 581 client2_role, client1_role, flags); |
| 596 client1_.Negotiate(&client2_, cricket::CA_ANSWER, | 582 client1_.Negotiate(&client2_, cricket::CA_ANSWER, |
| 597 client1_role, client2_role, flags); | 583 client1_role, client2_role, flags); |
| 598 } | 584 } |
| 599 } | 585 } |
| 600 | 586 |
| 601 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { | 587 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { |
| 602 LOG(LS_INFO) << "Expect packets, size=" << size; | 588 LOG(LS_INFO) << "Expect packets, size=" << size; |
| 603 client2_.ExpectPackets(channel, size); | 589 client2_.ExpectPackets(channel, size); |
| 604 client1_.SendPackets(channel, size, count, srtp); | 590 client1_.SendPackets(channel, size, count, srtp); |
| 605 EXPECT_EQ_SIMULATED_WAIT(count, client2_.NumPacketsReceived(), kTimeout, | 591 EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), kTimeout); |
| 606 fake_clock_); | |
| 607 } | 592 } |
| 608 | 593 |
| 609 protected: | 594 protected: |
| 610 rtc::ScopedFakeClock fake_clock_; | 595 rtc::ScopedFakeClock fake_clock_; |
| 611 DtlsTestClient client1_; | 596 DtlsTestClient client1_; |
| 612 DtlsTestClient client2_; | 597 DtlsTestClient client2_; |
| 613 int channel_ct_; | 598 int channel_ct_; |
| 614 bool use_dtls_; | 599 bool use_dtls_; |
| 615 bool use_dtls_srtp_; | 600 bool use_dtls_srtp_; |
| 616 rtc::SSLProtocolVersion ssl_expected_version_; | 601 rtc::SSLProtocolVersion ssl_expected_version_; |
| 617 }; | 602 }; |
| 618 | 603 |
| 619 class DtlsTransportChannelTest : public DtlsTransportChannelTestBase, | |
| 620 public ::testing::Test {}; | |
| 621 | |
| 622 // Test that transport negotiation of ICE, no DTLS works properly. | 604 // Test that transport negotiation of ICE, no DTLS works properly. |
| 623 TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) { | 605 TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) { |
| 624 Negotiate(); | 606 Negotiate(); |
| 625 cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0); | 607 cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0); |
| 626 cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0); | 608 cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0); |
| 627 ASSERT_TRUE(channel1 != NULL); | 609 ASSERT_TRUE(channel1 != NULL); |
| 628 ASSERT_TRUE(channel2 != NULL); | 610 ASSERT_TRUE(channel2 != NULL); |
| 629 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); | 611 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); |
| 630 EXPECT_EQ(1U, channel1->IceTiebreaker()); | 612 EXPECT_EQ(1U, channel1->IceTiebreaker()); |
| 631 EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag()); | 613 EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag()); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 MAYBE_SKIP_TEST(HaveDtlsSrtp); | 877 MAYBE_SKIP_TEST(HaveDtlsSrtp); |
| 896 SetChannelCount(2); | 878 SetChannelCount(2); |
| 897 PrepareDtls(true, true, rtc::KT_DEFAULT); | 879 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 898 PrepareDtlsSrtp(true, true); | 880 PrepareDtlsSrtp(true, true); |
| 899 Negotiate(); | 881 Negotiate(); |
| 900 | 882 |
| 901 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, | 883 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, |
| 902 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); | 884 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); |
| 903 bool rv = client1_.Connect(&client2_, false); | 885 bool rv = client1_.Connect(&client2_, false); |
| 904 EXPECT_TRUE(rv); | 886 EXPECT_TRUE(rv); |
| 905 EXPECT_TRUE_SIMULATED_WAIT( | 887 EXPECT_TRUE_WAIT( |
| 906 client1_.all_channels_writable() && client2_.all_channels_writable(), | 888 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 907 kTimeout, fake_clock_); | 889 kTimeout); |
| 908 | 890 |
| 909 TestTransfer(0, 1000, 100, true); | 891 TestTransfer(0, 1000, 100, true); |
| 910 TestTransfer(1, 1000, 100, true); | 892 TestTransfer(1, 1000, 100, true); |
| 911 } | 893 } |
| 912 | 894 |
| 913 // Test Certificates state after negotiation but before connection. | 895 // Test Certificates state after negotiation but before connection. |
| 914 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { | 896 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { |
| 915 MAYBE_SKIP_TEST(HaveDtls); | 897 MAYBE_SKIP_TEST(HaveDtls); |
| 916 PrepareDtls(true, true, rtc::KT_DEFAULT); | 898 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 917 Negotiate(); | 899 Negotiate(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 ASSERT_TRUE(remote_cert1); | 934 ASSERT_TRUE(remote_cert1); |
| 953 ASSERT_EQ(remote_cert1->ToPEMString(), | 935 ASSERT_EQ(remote_cert1->ToPEMString(), |
| 954 certificate2->ssl_certificate().ToPEMString()); | 936 certificate2->ssl_certificate().ToPEMString()); |
| 955 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = | 937 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = |
| 956 client2_.transport()->GetRemoteSSLCertificate(); | 938 client2_.transport()->GetRemoteSSLCertificate(); |
| 957 ASSERT_TRUE(remote_cert2); | 939 ASSERT_TRUE(remote_cert2); |
| 958 ASSERT_EQ(remote_cert2->ToPEMString(), | 940 ASSERT_EQ(remote_cert2->ToPEMString(), |
| 959 certificate1->ssl_certificate().ToPEMString()); | 941 certificate1->ssl_certificate().ToPEMString()); |
| 960 } | 942 } |
| 961 | 943 |
| 944 // Test that DTLS completes promptly if a ClientHello is received before the |
| 945 // transport channel is writable (allowing a ServerHello to be sent). |
| 946 TEST_F(DtlsTransportChannelTest, TestReceiveClientHelloBeforeWritable) { |
| 947 MAYBE_SKIP_TEST(HaveDtls); |
| 948 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 949 // Exchange transport descriptions. |
| 950 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); |
| 951 |
| 952 // Make client2_ writable, but not client1_. |
| 953 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
| 954 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); |
| 955 |
| 956 // Expect a DTLS ClientHello to be sent even while client1_ isn't writable. |
| 957 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
| 958 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
| 959 |
| 960 // Now make client1_ writable and expect the handshake to complete |
| 961 // without client2_ needing to retransmit the ClientHello. |
| 962 EXPECT_TRUE(client1_.Connect(&client2_, true)); |
| 963 EXPECT_TRUE_WAIT( |
| 964 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 965 kTimeout); |
| 966 EXPECT_EQ(1, client1_.received_dtls_client_hellos()); |
| 967 } |
| 968 |
| 969 // Test that DTLS completes promptly if a ClientHello is received before the |
| 970 // transport channel has a remote fingerprint (allowing a ServerHello to be |
| 971 // sent). |
| 972 TEST_F(DtlsTransportChannelTest, |
| 973 TestReceiveClientHelloBeforeRemoteFingerprint) { |
| 974 MAYBE_SKIP_TEST(HaveDtls); |
| 975 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 976 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING); |
| 977 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED); |
| 978 |
| 979 // Make client2_ writable and give it local/remote certs, but don't yet give |
| 980 // client1_ a remote fingerprint. |
| 981 client1_.transport()->SetLocalTransportDescription( |
| 982 MakeTransportDescription(client1_.certificate(), |
| 983 cricket::CONNECTIONROLE_ACTPASS), |
| 984 cricket::CA_OFFER, nullptr); |
| 985 client2_.Negotiate(&client1_, cricket::CA_ANSWER, |
| 986 cricket::CONNECTIONROLE_ACTIVE, |
| 987 cricket::CONNECTIONROLE_ACTPASS, 0); |
| 988 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
| 989 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); |
| 990 |
| 991 // Expect a DTLS ClientHello to be sent even while client1_ doesn't have a |
| 992 // remote fingerprint. |
| 993 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
| 994 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
| 995 |
| 996 // Now make give client1_ its remote fingerprint and make it writable, and |
| 997 // expect the handshake to complete without client2_ needing to retransmit |
| 998 // the ClientHello. |
| 999 client1_.transport()->SetRemoteTransportDescription( |
| 1000 MakeTransportDescription(client2_.certificate(), |
| 1001 cricket::CONNECTIONROLE_ACTIVE), |
| 1002 cricket::CA_ANSWER, nullptr); |
| 1003 EXPECT_TRUE(client1_.Connect(&client2_, true)); |
| 1004 EXPECT_TRUE_WAIT( |
| 1005 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 1006 kTimeout); |
| 1007 EXPECT_EQ(1, client1_.received_dtls_client_hellos()); |
| 1008 } |
| 1009 |
| 962 // Test that packets are retransmitted according to the expected schedule. | 1010 // Test that packets are retransmitted according to the expected schedule. |
| 963 // Each time a timeout occurs, the retransmission timer should be doubled up to | 1011 // Each time a timeout occurs, the retransmission timer should be doubled up to |
| 964 // 60 seconds. The timer defaults to 1 second, but for WebRTC we should be | 1012 // 60 seconds. The timer defaults to 1 second, but for WebRTC we should be |
| 965 // initializing it to 50ms. | 1013 // initializing it to 50ms. |
| 966 TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) { | 1014 TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) { |
| 967 MAYBE_SKIP_TEST(HaveDtls); | 1015 MAYBE_SKIP_TEST(HaveDtls); |
| 968 // We can only change the retransmission schedule with a recently-added | 1016 // We can only change the retransmission schedule with a recently-added |
| 969 // BoringSSL API. Skip the test if not built with BoringSSL. | 1017 // BoringSSL API. Skip the test if not built with BoringSSL. |
| 970 MAYBE_SKIP_TEST(IsBoringSsl); | 1018 MAYBE_SKIP_TEST(IsBoringSsl); |
| 971 | 1019 |
| 972 PrepareDtls(true, true, rtc::KT_DEFAULT); | 1020 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 973 // Exchange transport descriptions. | 1021 // Exchange transport descriptions. |
| 974 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); | 1022 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); |
| 975 | 1023 |
| 976 // Make client2_ writable, but not client1_. | 1024 // Make client2_ writable, but not client1_. |
| 977 // This means client1_ will send DTLS client hellos but get no response. | 1025 // This means client1_ will send DTLS client hellos but get no response. |
| 978 EXPECT_TRUE(client2_.Connect(&client1_, true)); | 1026 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
| 979 EXPECT_TRUE_SIMULATED_WAIT(client2_.all_raw_channels_writable(), kTimeout, | 1027 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); |
| 980 fake_clock_); | |
| 981 | 1028 |
| 982 // Wait for the first client hello to be sent. | 1029 // Wait for the first client hello to be sent. |
| 983 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); | 1030 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
| 984 EXPECT_FALSE(client1_.all_raw_channels_writable()); | 1031 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
| 985 | 1032 |
| 986 static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600, | 1033 static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600, |
| 987 3200, 6400, 12800, 25600, 51200, 60000}; | 1034 3200, 6400, 12800, 25600, 51200, 60000}; |
| 988 | 1035 |
| 989 int expected_hellos = 1; | 1036 int expected_hellos = 1; |
| 990 for (size_t i = 0; | 1037 for (size_t i = 0; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1005 // Test that a DTLS connection can be made even if the underlying transport | 1052 // Test that a DTLS connection can be made even if the underlying transport |
| 1006 // is connected before DTLS fingerprints/roles have been negotiated. | 1053 // is connected before DTLS fingerprints/roles have been negotiated. |
| 1007 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { | 1054 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { |
| 1008 MAYBE_SKIP_TEST(HaveDtls); | 1055 MAYBE_SKIP_TEST(HaveDtls); |
| 1009 PrepareDtls(true, true, rtc::KT_DEFAULT); | 1056 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 1010 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, | 1057 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, |
| 1011 cricket::CONNECTIONROLE_ACTIVE, | 1058 cricket::CONNECTIONROLE_ACTIVE, |
| 1012 CONNECT_BEFORE_NEGOTIATE)); | 1059 CONNECT_BEFORE_NEGOTIATE)); |
| 1013 TestTransfer(0, 1000, 100, false); | 1060 TestTransfer(0, 1000, 100, false); |
| 1014 } | 1061 } |
| 1015 | |
| 1016 // The following events can occur in many different orders: | |
| 1017 // 1. Caller receives remote fingerprint. | |
| 1018 // 2. Caller is writable. | |
| 1019 // 3. Caller receives ClientHello. | |
| 1020 // 4. DTLS handshake finishes. | |
| 1021 // | |
| 1022 // The tests below cover all causally consistent permutations of these events; | |
| 1023 // the caller must be writable and receive a ClientHello before the handshake | |
| 1024 // finishes, but otherwise any ordering is possible. | |
| 1025 // | |
| 1026 // For each permutation, the test verifies that a connection is established and | |
| 1027 // fingerprint verified without any DTLS packet needing to be retransmitted. | |
| 1028 // | |
| 1029 // Each permutation is also tested with a valid and invalid fingerprint, | |
| 1030 // ensuring that the handshake fails with an invalid fingerprint. | |
| 1031 enum DtlsTransportEvent { | |
| 1032 CALLER_RECEIVES_FINGERPRINT, | |
| 1033 CALLER_WRITABLE, | |
| 1034 CALLER_RECEIVES_CLIENTHELLO, | |
| 1035 HANDSHAKE_FINISHES | |
| 1036 }; | |
| 1037 | |
| 1038 class DtlsEventOrderingTest | |
| 1039 : public DtlsTransportChannelTestBase, | |
| 1040 public ::testing::TestWithParam< | |
| 1041 ::testing::tuple<std::vector<DtlsTransportEvent>, bool>> { | |
| 1042 protected: | |
| 1043 // If |valid_fingerprint| is false, the caller will receive a fingerprint | |
| 1044 // that doesn't match the callee's certificate, so the handshake should fail. | |
| 1045 void TestEventOrdering(const std::vector<DtlsTransportEvent>& events, | |
| 1046 bool valid_fingerprint) { | |
| 1047 // Pre-setup: Set local certificate on both caller and callee, and | |
| 1048 // remote fingerprint on callee, but neither is writable and the caller | |
| 1049 // doesn't have the callee's fingerprint. | |
| 1050 PrepareDtls(true, true, rtc::KT_DEFAULT); | |
| 1051 // Simulate packets being sent and arriving asynchronously. | |
| 1052 // Otherwise the entire DTLS handshake would occur in one clock tick, and | |
| 1053 // we couldn't inject method calls in the middle of it. | |
| 1054 int simulated_delay_ms = 10; | |
| 1055 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING, | |
| 1056 simulated_delay_ms); | |
| 1057 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED, | |
| 1058 simulated_delay_ms); | |
| 1059 client1_.SetLocalTransportDescription(client1_.certificate(), | |
| 1060 cricket::CA_OFFER, | |
| 1061 cricket::CONNECTIONROLE_ACTPASS, 0); | |
| 1062 client2_.Negotiate(&client1_, cricket::CA_ANSWER, | |
| 1063 cricket::CONNECTIONROLE_ACTIVE, | |
| 1064 cricket::CONNECTIONROLE_ACTPASS, 0); | |
| 1065 | |
| 1066 for (DtlsTransportEvent e : events) { | |
| 1067 switch (e) { | |
| 1068 case CALLER_RECEIVES_FINGERPRINT: | |
| 1069 if (valid_fingerprint) { | |
| 1070 client1_.SetRemoteTransportDescription( | |
| 1071 client2_.certificate(), cricket::CA_ANSWER, | |
| 1072 cricket::CONNECTIONROLE_ACTIVE, 0); | |
| 1073 } else { | |
| 1074 // Create a fingerprint with a correct algorithm but an invalid | |
| 1075 // digest. | |
| 1076 cricket::TransportDescription remote_desc = | |
| 1077 MakeTransportDescription(client2_.certificate(), | |
| 1078 cricket::CONNECTIONROLE_ACTIVE); | |
| 1079 ++(remote_desc.identity_fingerprint->digest[0]); | |
| 1080 // Even if certificate verification fails inside this method, | |
| 1081 // it should return true as long as the fingerprint was formatted | |
| 1082 // correctly. | |
| 1083 EXPECT_TRUE(client1_.transport()->SetRemoteTransportDescription( | |
| 1084 remote_desc, cricket::CA_ANSWER, nullptr)); | |
| 1085 } | |
| 1086 break; | |
| 1087 case CALLER_WRITABLE: | |
| 1088 EXPECT_TRUE(client1_.Connect(&client2_, true)); | |
| 1089 EXPECT_TRUE_SIMULATED_WAIT(client1_.all_raw_channels_writable(), | |
| 1090 kTimeout, fake_clock_); | |
| 1091 break; | |
| 1092 case CALLER_RECEIVES_CLIENTHELLO: | |
| 1093 // Sanity check that a ClientHello hasn't already been received. | |
| 1094 EXPECT_EQ(0, client1_.received_dtls_client_hellos()); | |
| 1095 // Making client2_ writable will cause it to send the ClientHello. | |
| 1096 EXPECT_TRUE(client2_.Connect(&client1_, true)); | |
| 1097 EXPECT_TRUE_SIMULATED_WAIT(client2_.all_raw_channels_writable(), | |
| 1098 kTimeout, fake_clock_); | |
| 1099 EXPECT_EQ_SIMULATED_WAIT(1, client1_.received_dtls_client_hellos(), | |
| 1100 kTimeout, fake_clock_); | |
| 1101 break; | |
| 1102 case HANDSHAKE_FINISHES: | |
| 1103 // Sanity check that the handshake hasn't already finished. | |
| 1104 EXPECT_FALSE(client1_.GetDtlsChannel(0)->IsDtlsConnected() || | |
| 1105 client1_.GetDtlsChannel(0)->dtls_state() == | |
| 1106 cricket::DTLS_TRANSPORT_FAILED); | |
| 1107 EXPECT_TRUE_SIMULATED_WAIT( | |
| 1108 client1_.GetDtlsChannel(0)->IsDtlsConnected() || | |
| 1109 client1_.GetDtlsChannel(0)->dtls_state() == | |
| 1110 cricket::DTLS_TRANSPORT_FAILED, | |
| 1111 kTimeout, fake_clock_); | |
| 1112 break; | |
| 1113 } | |
| 1114 } | |
| 1115 | |
| 1116 cricket::DtlsTransportState expected_final_state = | |
| 1117 valid_fingerprint ? cricket::DTLS_TRANSPORT_CONNECTED | |
| 1118 : cricket::DTLS_TRANSPORT_FAILED; | |
| 1119 EXPECT_EQ_SIMULATED_WAIT(expected_final_state, | |
| 1120 client1_.GetDtlsChannel(0)->dtls_state(), kTimeout, | |
| 1121 fake_clock_); | |
| 1122 EXPECT_EQ_SIMULATED_WAIT(expected_final_state, | |
| 1123 client2_.GetDtlsChannel(0)->dtls_state(), kTimeout, | |
| 1124 fake_clock_); | |
| 1125 | |
| 1126 // Channel should be writable iff there was a valid fingerprint. | |
| 1127 EXPECT_EQ(valid_fingerprint, client1_.GetDtlsChannel(0)->writable()); | |
| 1128 EXPECT_EQ(valid_fingerprint, client2_.GetDtlsChannel(0)->writable()); | |
| 1129 | |
| 1130 // Check that no hello needed to be retransmitted. | |
| 1131 EXPECT_EQ(1, client1_.received_dtls_client_hellos()); | |
| 1132 EXPECT_EQ(1, client2_.received_dtls_server_hellos()); | |
| 1133 | |
| 1134 if (valid_fingerprint) { | |
| 1135 TestTransfer(0, 1000, 100, false); | |
| 1136 } | |
| 1137 } | |
| 1138 }; | |
| 1139 | |
| 1140 TEST_P(DtlsEventOrderingTest, TestEventOrdering) { | |
| 1141 MAYBE_SKIP_TEST(HaveDtls); | |
| 1142 TestEventOrdering(::testing::get<0>(GetParam()), | |
| 1143 ::testing::get<1>(GetParam())); | |
| 1144 } | |
| 1145 | |
| 1146 INSTANTIATE_TEST_CASE_P( | |
| 1147 TestEventOrdering, | |
| 1148 DtlsEventOrderingTest, | |
| 1149 ::testing::Combine( | |
| 1150 ::testing::Values( | |
| 1151 std::vector<DtlsTransportEvent>{ | |
| 1152 CALLER_RECEIVES_FINGERPRINT, CALLER_WRITABLE, | |
| 1153 CALLER_RECEIVES_CLIENTHELLO, HANDSHAKE_FINISHES}, | |
| 1154 std::vector<DtlsTransportEvent>{ | |
| 1155 CALLER_WRITABLE, CALLER_RECEIVES_FINGERPRINT, | |
| 1156 CALLER_RECEIVES_CLIENTHELLO, HANDSHAKE_FINISHES}, | |
| 1157 std::vector<DtlsTransportEvent>{ | |
| 1158 CALLER_WRITABLE, CALLER_RECEIVES_CLIENTHELLO, | |
| 1159 CALLER_RECEIVES_FINGERPRINT, HANDSHAKE_FINISHES}, | |
| 1160 std::vector<DtlsTransportEvent>{ | |
| 1161 CALLER_WRITABLE, CALLER_RECEIVES_CLIENTHELLO, | |
| 1162 HANDSHAKE_FINISHES, CALLER_RECEIVES_FINGERPRINT}, | |
| 1163 std::vector<DtlsTransportEvent>{ | |
| 1164 CALLER_RECEIVES_FINGERPRINT, CALLER_RECEIVES_CLIENTHELLO, | |
| 1165 CALLER_WRITABLE, HANDSHAKE_FINISHES}, | |
| 1166 std::vector<DtlsTransportEvent>{ | |
| 1167 CALLER_RECEIVES_CLIENTHELLO, CALLER_RECEIVES_FINGERPRINT, | |
| 1168 CALLER_WRITABLE, HANDSHAKE_FINISHES}, | |
| 1169 std::vector<DtlsTransportEvent>{ | |
| 1170 CALLER_RECEIVES_CLIENTHELLO, CALLER_WRITABLE, | |
| 1171 CALLER_RECEIVES_FINGERPRINT, HANDSHAKE_FINISHES}, | |
| 1172 std::vector<DtlsTransportEvent>{CALLER_RECEIVES_CLIENTHELLO, | |
| 1173 CALLER_WRITABLE, HANDSHAKE_FINISHES, | |
| 1174 CALLER_RECEIVES_FINGERPRINT}), | |
| 1175 ::testing::Bool())); | |
| OLD | NEW |