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) { | 84 void SetupChannels(int count, cricket::IceRole role, int async_delay_ms = 0) { |
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); |
88 transport_->SetIceRole(role); | 89 transport_->SetIceRole(role); |
89 transport_->SetIceTiebreaker( | 90 transport_->SetIceTiebreaker( |
90 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); | 91 (role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
91 | 92 |
92 for (int i = 0; i < count; ++i) { | 93 for (int i = 0; i < count; ++i) { |
93 cricket::DtlsTransportChannelWrapper* channel = | 94 cricket::DtlsTransportChannelWrapper* channel = |
94 static_cast<cricket::DtlsTransportChannelWrapper*>( | 95 static_cast<cricket::DtlsTransportChannelWrapper*>( |
95 transport_->CreateChannel(i)); | 96 transport_->CreateChannel(i)); |
96 ASSERT_TRUE(channel != NULL); | 97 ASSERT_TRUE(channel != NULL); |
97 channel->SetSslMaxProtocolVersion(ssl_max_version_); | 98 channel->SetSslMaxProtocolVersion(ssl_max_version_); |
(...skipping 14 matching lines...) Expand all Loading... |
112 cricket::Transport* transport() { return transport_.get(); } | 113 cricket::Transport* transport() { return transport_.get(); } |
113 | 114 |
114 cricket::FakeTransportChannel* GetFakeChannel(int component) { | 115 cricket::FakeTransportChannel* GetFakeChannel(int component) { |
115 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); | 116 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); |
116 cricket::DtlsTransportChannelWrapper* wrapper = | 117 cricket::DtlsTransportChannelWrapper* wrapper = |
117 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); | 118 static_cast<cricket::DtlsTransportChannelWrapper*>(ch); |
118 return (wrapper) ? | 119 return (wrapper) ? |
119 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; | 120 static_cast<cricket::FakeTransportChannel*>(wrapper->channel()) : NULL; |
120 } | 121 } |
121 | 122 |
| 123 cricket::DtlsTransportChannelWrapper* GetDtlsChannel(int component) { |
| 124 cricket::TransportChannelImpl* ch = transport_->GetChannel(component); |
| 125 return static_cast<cricket::DtlsTransportChannelWrapper*>(ch); |
| 126 } |
| 127 |
122 // Offer DTLS if we have an identity; pass in a remote fingerprint only if | 128 // Offer DTLS if we have an identity; pass in a remote fingerprint only if |
123 // both sides support DTLS. | 129 // both sides support DTLS. |
124 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, | 130 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, |
125 ConnectionRole local_role, ConnectionRole remote_role, | 131 ConnectionRole local_role, ConnectionRole remote_role, |
126 int flags) { | 132 int flags) { |
127 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, | 133 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, |
128 local_role, remote_role, flags); | 134 local_role, remote_role, flags); |
129 } | 135 } |
130 | 136 |
131 void MaybeSetSrtpCryptoSuites() { | 137 void MaybeSetSrtpCryptoSuites() { |
(...skipping 13 matching lines...) Expand all Loading... |
145 cricket::ContentAction action, | 151 cricket::ContentAction action, |
146 ConnectionRole role, | 152 ConnectionRole role, |
147 int flags) { | 153 int flags) { |
148 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when | 154 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
149 // content action is CA_ANSWER. | 155 // content action is CA_ANSWER. |
150 bool expect_success = | 156 bool expect_success = |
151 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); | 157 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
152 EXPECT_EQ(expect_success, | 158 EXPECT_EQ(expect_success, |
153 transport_->SetLocalTransportDescription( | 159 transport_->SetLocalTransportDescription( |
154 MakeTransportDescription(cert, role), action, nullptr)); | 160 MakeTransportDescription(cert, role), action, nullptr)); |
155 set_local_cert_ = (cert != nullptr); | |
156 } | 161 } |
157 | 162 |
158 void SetRemoteTransportDescription( | 163 void SetRemoteTransportDescription( |
159 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, | 164 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
160 cricket::ContentAction action, | 165 cricket::ContentAction action, |
161 ConnectionRole role, | 166 ConnectionRole role, |
162 int flags) { | 167 int flags) { |
163 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when | 168 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
164 // content action is CA_ANSWER. | 169 // content action is CA_ANSWER. |
165 bool expect_success = | 170 bool expect_success = |
166 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); | 171 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
167 EXPECT_EQ(expect_success, | 172 EXPECT_EQ(expect_success, |
168 transport_->SetRemoteTransportDescription( | 173 transport_->SetRemoteTransportDescription( |
169 MakeTransportDescription(cert, role), action, nullptr)); | 174 MakeTransportDescription(cert, role), action, nullptr)); |
170 set_remote_cert_ = (cert != nullptr); | |
171 } | 175 } |
172 | 176 |
173 // Allow any DTLS configuration to be specified (including invalid ones). | 177 // Allow any DTLS configuration to be specified (including invalid ones). |
174 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, | 178 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, |
175 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, | 179 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, |
176 cricket::ContentAction action, | 180 cricket::ContentAction action, |
177 ConnectionRole local_role, | 181 ConnectionRole local_role, |
178 ConnectionRole remote_role, | 182 ConnectionRole remote_role, |
179 int flags) { | 183 int flags) { |
180 if (!(flags & NF_REOFFER)) { | 184 if (!(flags & NF_REOFFER)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 return false; | 226 return false; |
223 } | 227 } |
224 } | 228 } |
225 return true; | 229 return true; |
226 } | 230 } |
227 | 231 |
228 int received_dtls_client_hellos() const { | 232 int received_dtls_client_hellos() const { |
229 return received_dtls_client_hellos_; | 233 return received_dtls_client_hellos_; |
230 } | 234 } |
231 | 235 |
232 bool negotiated_dtls() const { return set_local_cert_ && set_remote_cert_; } | 236 int received_dtls_server_hellos() const { |
| 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 } |
233 | 246 |
234 void CheckRole(rtc::SSLRole role) { | 247 void CheckRole(rtc::SSLRole role) { |
235 if (role == rtc::SSL_CLIENT) { | 248 if (role == rtc::SSL_CLIENT) { |
236 ASSERT_EQ(0, received_dtls_client_hellos_); | 249 ASSERT_EQ(0, received_dtls_client_hellos_); |
237 ASSERT_GT(received_dtls_server_hellos_, 0); | 250 ASSERT_GT(received_dtls_server_hellos_, 0); |
238 } else { | 251 } else { |
239 ASSERT_GT(received_dtls_client_hellos_, 0); | 252 ASSERT_GT(received_dtls_client_hellos_, 0); |
240 ASSERT_EQ(0, received_dtls_server_hellos_); | 253 ASSERT_EQ(0, received_dtls_server_hellos_); |
241 } | 254 } |
242 } | 255 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 | 417 |
405 private: | 418 private: |
406 std::string name_; | 419 std::string name_; |
407 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 420 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
408 std::unique_ptr<cricket::FakeTransport> transport_; | 421 std::unique_ptr<cricket::FakeTransport> transport_; |
409 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 422 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
410 size_t packet_size_ = 0u; | 423 size_t packet_size_ = 0u; |
411 std::set<int> received_; | 424 std::set<int> received_; |
412 bool use_dtls_srtp_ = false; | 425 bool use_dtls_srtp_ = false; |
413 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 426 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
414 bool set_local_cert_ = false; | |
415 bool set_remote_cert_ = false; | |
416 int received_dtls_client_hellos_ = 0; | 427 int received_dtls_client_hellos_ = 0; |
417 int received_dtls_server_hellos_ = 0; | 428 int received_dtls_server_hellos_ = 0; |
418 rtc::SentPacket sent_packet_; | 429 rtc::SentPacket sent_packet_; |
419 }; | 430 }; |
420 | 431 |
| 432 // Base class for DtlsTransportChannelTest and DtlsEventOrderingTest, which |
| 433 // inherit from different variants of testing::Test. |
| 434 // |
421 // Note that this test always uses a FakeClock, due to the |fake_clock_| member | 435 // Note that this test always uses a FakeClock, due to the |fake_clock_| member |
422 // variable. | 436 // variable. |
423 class DtlsTransportChannelTest : public testing::Test { | 437 class DtlsTransportChannelTestBase { |
424 public: | 438 public: |
425 DtlsTransportChannelTest() | 439 DtlsTransportChannelTestBase() |
426 : client1_("P1"), | 440 : client1_("P1"), |
427 client2_("P2"), | 441 client2_("P2"), |
428 channel_ct_(1), | 442 channel_ct_(1), |
429 use_dtls_(false), | 443 use_dtls_(false), |
430 use_dtls_srtp_(false), | 444 use_dtls_srtp_(false), |
431 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_12) {} | 445 ssl_expected_version_(rtc::SSL_PROTOCOL_DTLS_12) {} |
432 | 446 |
433 void SetChannelCount(size_t channel_ct) { | 447 void SetChannelCount(size_t channel_ct) { |
434 channel_ct_ = static_cast<int>(channel_ct); | 448 channel_ct_ = static_cast<int>(channel_ct); |
435 } | 449 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | 502 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
489 rv = client1_.Connect(&client2_, false); | 503 rv = client1_.Connect(&client2_, false); |
490 client1_.SetRemoteTransportDescription( | 504 client1_.SetRemoteTransportDescription( |
491 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | 505 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
492 } | 506 } |
493 | 507 |
494 EXPECT_TRUE(rv); | 508 EXPECT_TRUE(rv); |
495 if (!rv) | 509 if (!rv) |
496 return false; | 510 return false; |
497 | 511 |
498 EXPECT_TRUE_WAIT( | 512 EXPECT_TRUE_SIMULATED_WAIT( |
499 client1_.all_channels_writable() && client2_.all_channels_writable(), | 513 client1_.all_channels_writable() && client2_.all_channels_writable(), |
500 kTimeout); | 514 kTimeout, fake_clock_); |
501 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) | 515 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
502 return false; | 516 return false; |
503 | 517 |
504 // Check that we used the right roles. | 518 // Check that we used the right roles. |
505 if (use_dtls_) { | 519 if (use_dtls_) { |
506 rtc::SSLRole client1_ssl_role = | 520 rtc::SSLRole client1_ssl_role = |
507 (client1_role == cricket::CONNECTIONROLE_ACTIVE || | 521 (client1_role == cricket::CONNECTIONROLE_ACTIVE || |
508 (client2_role == cricket::CONNECTIONROLE_PASSIVE && | 522 (client2_role == cricket::CONNECTIONROLE_PASSIVE && |
509 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? | 523 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? |
510 rtc::SSL_CLIENT : rtc::SSL_SERVER; | 524 rtc::SSL_CLIENT : rtc::SSL_SERVER; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 client2_role, client1_role, flags); | 595 client2_role, client1_role, flags); |
582 client1_.Negotiate(&client2_, cricket::CA_ANSWER, | 596 client1_.Negotiate(&client2_, cricket::CA_ANSWER, |
583 client1_role, client2_role, flags); | 597 client1_role, client2_role, flags); |
584 } | 598 } |
585 } | 599 } |
586 | 600 |
587 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { | 601 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { |
588 LOG(LS_INFO) << "Expect packets, size=" << size; | 602 LOG(LS_INFO) << "Expect packets, size=" << size; |
589 client2_.ExpectPackets(channel, size); | 603 client2_.ExpectPackets(channel, size); |
590 client1_.SendPackets(channel, size, count, srtp); | 604 client1_.SendPackets(channel, size, count, srtp); |
591 EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), kTimeout); | 605 EXPECT_EQ_SIMULATED_WAIT(count, client2_.NumPacketsReceived(), kTimeout, |
| 606 fake_clock_); |
592 } | 607 } |
593 | 608 |
594 protected: | 609 protected: |
595 rtc::ScopedFakeClock fake_clock_; | 610 rtc::ScopedFakeClock fake_clock_; |
596 DtlsTestClient client1_; | 611 DtlsTestClient client1_; |
597 DtlsTestClient client2_; | 612 DtlsTestClient client2_; |
598 int channel_ct_; | 613 int channel_ct_; |
599 bool use_dtls_; | 614 bool use_dtls_; |
600 bool use_dtls_srtp_; | 615 bool use_dtls_srtp_; |
601 rtc::SSLProtocolVersion ssl_expected_version_; | 616 rtc::SSLProtocolVersion ssl_expected_version_; |
602 }; | 617 }; |
603 | 618 |
| 619 class DtlsTransportChannelTest : public DtlsTransportChannelTestBase, |
| 620 public ::testing::Test {}; |
| 621 |
604 // Test that transport negotiation of ICE, no DTLS works properly. | 622 // Test that transport negotiation of ICE, no DTLS works properly. |
605 TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) { | 623 TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) { |
606 Negotiate(); | 624 Negotiate(); |
607 cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0); | 625 cricket::FakeTransportChannel* channel1 = client1_.GetFakeChannel(0); |
608 cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0); | 626 cricket::FakeTransportChannel* channel2 = client2_.GetFakeChannel(0); |
609 ASSERT_TRUE(channel1 != NULL); | 627 ASSERT_TRUE(channel1 != NULL); |
610 ASSERT_TRUE(channel2 != NULL); | 628 ASSERT_TRUE(channel2 != NULL); |
611 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); | 629 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole()); |
612 EXPECT_EQ(1U, channel1->IceTiebreaker()); | 630 EXPECT_EQ(1U, channel1->IceTiebreaker()); |
613 EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag()); | 631 EXPECT_EQ(kIceUfrag1, channel1->ice_ufrag()); |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 MAYBE_SKIP_TEST(HaveDtlsSrtp); | 895 MAYBE_SKIP_TEST(HaveDtlsSrtp); |
878 SetChannelCount(2); | 896 SetChannelCount(2); |
879 PrepareDtls(true, true, rtc::KT_DEFAULT); | 897 PrepareDtls(true, true, rtc::KT_DEFAULT); |
880 PrepareDtlsSrtp(true, true); | 898 PrepareDtlsSrtp(true, true); |
881 Negotiate(); | 899 Negotiate(); |
882 | 900 |
883 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, | 901 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, |
884 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); | 902 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); |
885 bool rv = client1_.Connect(&client2_, false); | 903 bool rv = client1_.Connect(&client2_, false); |
886 EXPECT_TRUE(rv); | 904 EXPECT_TRUE(rv); |
887 EXPECT_TRUE_WAIT( | 905 EXPECT_TRUE_SIMULATED_WAIT( |
888 client1_.all_channels_writable() && client2_.all_channels_writable(), | 906 client1_.all_channels_writable() && client2_.all_channels_writable(), |
889 kTimeout); | 907 kTimeout, fake_clock_); |
890 | 908 |
891 TestTransfer(0, 1000, 100, true); | 909 TestTransfer(0, 1000, 100, true); |
892 TestTransfer(1, 1000, 100, true); | 910 TestTransfer(1, 1000, 100, true); |
893 } | 911 } |
894 | 912 |
895 // Test Certificates state after negotiation but before connection. | 913 // Test Certificates state after negotiation but before connection. |
896 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { | 914 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { |
897 MAYBE_SKIP_TEST(HaveDtls); | 915 MAYBE_SKIP_TEST(HaveDtls); |
898 PrepareDtls(true, true, rtc::KT_DEFAULT); | 916 PrepareDtls(true, true, rtc::KT_DEFAULT); |
899 Negotiate(); | 917 Negotiate(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
934 ASSERT_TRUE(remote_cert1); | 952 ASSERT_TRUE(remote_cert1); |
935 ASSERT_EQ(remote_cert1->ToPEMString(), | 953 ASSERT_EQ(remote_cert1->ToPEMString(), |
936 certificate2->ssl_certificate().ToPEMString()); | 954 certificate2->ssl_certificate().ToPEMString()); |
937 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = | 955 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = |
938 client2_.transport()->GetRemoteSSLCertificate(); | 956 client2_.transport()->GetRemoteSSLCertificate(); |
939 ASSERT_TRUE(remote_cert2); | 957 ASSERT_TRUE(remote_cert2); |
940 ASSERT_EQ(remote_cert2->ToPEMString(), | 958 ASSERT_EQ(remote_cert2->ToPEMString(), |
941 certificate1->ssl_certificate().ToPEMString()); | 959 certificate1->ssl_certificate().ToPEMString()); |
942 } | 960 } |
943 | 961 |
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 | |
1010 // Test that packets are retransmitted according to the expected schedule. | 962 // Test that packets are retransmitted according to the expected schedule. |
1011 // Each time a timeout occurs, the retransmission timer should be doubled up to | 963 // Each time a timeout occurs, the retransmission timer should be doubled up to |
1012 // 60 seconds. The timer defaults to 1 second, but for WebRTC we should be | 964 // 60 seconds. The timer defaults to 1 second, but for WebRTC we should be |
1013 // initializing it to 50ms. | 965 // initializing it to 50ms. |
1014 TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) { | 966 TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) { |
1015 MAYBE_SKIP_TEST(HaveDtls); | 967 MAYBE_SKIP_TEST(HaveDtls); |
1016 // We can only change the retransmission schedule with a recently-added | 968 // We can only change the retransmission schedule with a recently-added |
1017 // BoringSSL API. Skip the test if not built with BoringSSL. | 969 // BoringSSL API. Skip the test if not built with BoringSSL. |
1018 MAYBE_SKIP_TEST(IsBoringSsl); | 970 MAYBE_SKIP_TEST(IsBoringSsl); |
1019 | 971 |
1020 PrepareDtls(true, true, rtc::KT_DEFAULT); | 972 PrepareDtls(true, true, rtc::KT_DEFAULT); |
1021 // Exchange transport descriptions. | 973 // Exchange transport descriptions. |
1022 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); | 974 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); |
1023 | 975 |
1024 // Make client2_ writable, but not client1_. | 976 // Make client2_ writable, but not client1_. |
1025 // This means client1_ will send DTLS client hellos but get no response. | 977 // This means client1_ will send DTLS client hellos but get no response. |
1026 EXPECT_TRUE(client2_.Connect(&client1_, true)); | 978 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
1027 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); | 979 EXPECT_TRUE_SIMULATED_WAIT(client2_.all_raw_channels_writable(), kTimeout, |
| 980 fake_clock_); |
1028 | 981 |
1029 // Wait for the first client hello to be sent. | 982 // Wait for the first client hello to be sent. |
1030 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); | 983 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
1031 EXPECT_FALSE(client1_.all_raw_channels_writable()); | 984 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
1032 | 985 |
1033 static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600, | 986 static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600, |
1034 3200, 6400, 12800, 25600, 51200, 60000}; | 987 3200, 6400, 12800, 25600, 51200, 60000}; |
1035 | 988 |
1036 int expected_hellos = 1; | 989 int expected_hellos = 1; |
1037 for (size_t i = 0; | 990 for (size_t i = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
1052 // Test that a DTLS connection can be made even if the underlying transport | 1005 // Test that a DTLS connection can be made even if the underlying transport |
1053 // is connected before DTLS fingerprints/roles have been negotiated. | 1006 // is connected before DTLS fingerprints/roles have been negotiated. |
1054 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { | 1007 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { |
1055 MAYBE_SKIP_TEST(HaveDtls); | 1008 MAYBE_SKIP_TEST(HaveDtls); |
1056 PrepareDtls(true, true, rtc::KT_DEFAULT); | 1009 PrepareDtls(true, true, rtc::KT_DEFAULT); |
1057 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, | 1010 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, |
1058 cricket::CONNECTIONROLE_ACTIVE, | 1011 cricket::CONNECTIONROLE_ACTIVE, |
1059 CONNECT_BEFORE_NEGOTIATE)); | 1012 CONNECT_BEFORE_NEGOTIATE)); |
1060 TestTransfer(0, 1000, 100, false); | 1013 TestTransfer(0, 1000, 100, false); |
1061 } | 1014 } |
| 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 valid and invalid fingerprints, |
| 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 |