| 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 15 matching lines...) Expand all Loading... |
| 26 if (!(rtc::SSLStreamAdapter::feature())) { \ | 26 if (!(rtc::SSLStreamAdapter::feature())) { \ |
| 27 LOG(LS_INFO) << "Feature disabled... skipping"; \ | 27 LOG(LS_INFO) << "Feature disabled... skipping"; \ |
| 28 return; \ | 28 return; \ |
| 29 } | 29 } |
| 30 | 30 |
| 31 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; | 31 static const char kIceUfrag1[] = "TESTICEUFRAG0001"; |
| 32 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; | 32 static const char kIcePwd1[] = "TESTICEPWD00000000000001"; |
| 33 static const size_t kPacketNumOffset = 8; | 33 static const size_t kPacketNumOffset = 8; |
| 34 static const size_t kPacketHeaderLen = 12; | 34 static const size_t kPacketHeaderLen = 12; |
| 35 static const int kFakePacketId = 0x1234; | 35 static const int kFakePacketId = 0x1234; |
| 36 static const int kTimeout = 10000; |
| 36 | 37 |
| 37 static bool IsRtpLeadByte(uint8_t b) { | 38 static bool IsRtpLeadByte(uint8_t b) { |
| 38 return ((b & 0xC0) == 0x80); | 39 return ((b & 0xC0) == 0x80); |
| 39 } | 40 } |
| 40 | 41 |
| 42 cricket::TransportDescription MakeTransportDescription( |
| 43 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
| 44 cricket::ConnectionRole role) { |
| 45 rtc::scoped_ptr<rtc::SSLFingerprint> fingerprint; |
| 46 if (cert) { |
| 47 std::string digest_algorithm; |
| 48 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm); |
| 49 fingerprint.reset( |
| 50 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); |
| 51 } |
| 52 return cricket::TransportDescription(std::vector<std::string>(), kIceUfrag1, |
| 53 kIcePwd1, cricket::ICEMODE_FULL, role, |
| 54 fingerprint.get()); |
| 55 } |
| 56 |
| 41 using cricket::ConnectionRole; | 57 using cricket::ConnectionRole; |
| 42 | 58 |
| 43 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; | 59 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; |
| 44 | 60 |
| 45 class DtlsTestClient : public sigslot::has_slots<> { | 61 class DtlsTestClient : public sigslot::has_slots<> { |
| 46 public: | 62 public: |
| 47 DtlsTestClient(const std::string& name) | 63 DtlsTestClient(const std::string& name) : name_(name) {} |
| 48 : name_(name), | |
| 49 packet_size_(0), | |
| 50 use_dtls_srtp_(false), | |
| 51 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12), | |
| 52 negotiated_dtls_(false), | |
| 53 received_dtls_client_hello_(false), | |
| 54 received_dtls_server_hello_(false) {} | |
| 55 void CreateCertificate(rtc::KeyType key_type) { | 64 void CreateCertificate(rtc::KeyType key_type) { |
| 56 certificate_ = | 65 certificate_ = |
| 57 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( | 66 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>( |
| 58 rtc::SSLIdentity::Generate(name_, key_type))); | 67 rtc::SSLIdentity::Generate(name_, key_type))); |
| 59 } | 68 } |
| 60 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate() { | 69 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate() { |
| 61 return certificate_; | 70 return certificate_; |
| 62 } | 71 } |
| 63 void SetupSrtp() { | 72 void SetupSrtp() { |
| 64 ASSERT(certificate_); | 73 ASSERT(certificate_); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 remote_desc, cricket::CA_ANSWER, NULL)); | 187 remote_desc, cricket::CA_ANSWER, NULL)); |
| 179 } else { | 188 } else { |
| 180 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | 189 ASSERT_TRUE(transport_->SetRemoteTransportDescription( |
| 181 remote_desc, cricket::CA_OFFER, NULL)); | 190 remote_desc, cricket::CA_OFFER, NULL)); |
| 182 ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription( | 191 ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription( |
| 183 local_desc, cricket::CA_ANSWER, NULL)); | 192 local_desc, cricket::CA_ANSWER, NULL)); |
| 184 } | 193 } |
| 185 negotiated_dtls_ = (local_cert && remote_cert); | 194 negotiated_dtls_ = (local_cert && remote_cert); |
| 186 } | 195 } |
| 187 | 196 |
| 188 bool Connect(DtlsTestClient* peer) { | 197 bool Connect(DtlsTestClient* peer, bool asymmetric) { |
| 189 transport_->ConnectChannels(); | 198 transport_->SetDestination(peer->transport_.get(), asymmetric); |
| 190 transport_->SetDestination(peer->transport_.get()); | |
| 191 return true; | 199 return true; |
| 192 } | 200 } |
| 193 | 201 |
| 194 bool all_channels_writable() const { | 202 bool all_channels_writable() const { |
| 195 if (channels_.empty()) { | 203 if (channels_.empty()) { |
| 196 return false; | 204 return false; |
| 197 } | 205 } |
| 198 for (cricket::DtlsTransportChannelWrapper* channel : channels_) { | 206 for (cricket::DtlsTransportChannelWrapper* channel : channels_) { |
| 199 if (!channel->writable()) { | 207 if (!channel->writable()) { |
| 200 return false; | 208 return false; |
| 201 } | 209 } |
| 202 } | 210 } |
| 203 return true; | 211 return true; |
| 204 } | 212 } |
| 205 | 213 |
| 214 bool all_raw_channels_writable() const { |
| 215 if (channels_.empty()) { |
| 216 return false; |
| 217 } |
| 218 for (cricket::DtlsTransportChannelWrapper* channel : channels_) { |
| 219 if (!channel->channel()->writable()) { |
| 220 return false; |
| 221 } |
| 222 } |
| 223 return true; |
| 224 } |
| 225 |
| 226 int received_dtls_client_hellos() const { |
| 227 return received_dtls_client_hellos_; |
| 228 } |
| 229 |
| 206 void CheckRole(rtc::SSLRole role) { | 230 void CheckRole(rtc::SSLRole role) { |
| 207 if (role == rtc::SSL_CLIENT) { | 231 if (role == rtc::SSL_CLIENT) { |
| 208 ASSERT_FALSE(received_dtls_client_hello_); | 232 ASSERT_EQ(0, received_dtls_client_hellos_); |
| 209 ASSERT_TRUE(received_dtls_server_hello_); | 233 ASSERT_GT(received_dtls_server_hellos_, 0); |
| 210 } else { | 234 } else { |
| 211 ASSERT_TRUE(received_dtls_client_hello_); | 235 ASSERT_GT(received_dtls_client_hellos_, 0); |
| 212 ASSERT_FALSE(received_dtls_server_hello_); | 236 ASSERT_EQ(0, received_dtls_server_hellos_); |
| 213 } | 237 } |
| 214 } | 238 } |
| 215 | 239 |
| 216 void CheckSrtp(int expected_crypto_suite) { | 240 void CheckSrtp(int expected_crypto_suite) { |
| 217 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | 241 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = |
| 218 channels_.begin(); it != channels_.end(); ++it) { | 242 channels_.begin(); it != channels_.end(); ++it) { |
| 219 int crypto_suite; | 243 int crypto_suite; |
| 220 | 244 |
| 221 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); | 245 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); |
| 222 if (negotiated_dtls_ && expected_crypto_suite) { | 246 if (negotiated_dtls_ && expected_crypto_suite) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // Hook into the raw packet stream to make sure DTLS packets are encrypted. | 375 // Hook into the raw packet stream to make sure DTLS packets are encrypted. |
| 352 void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel, | 376 void OnFakeTransportChannelReadPacket(cricket::TransportChannel* channel, |
| 353 const char* data, size_t size, | 377 const char* data, size_t size, |
| 354 const rtc::PacketTime& time, | 378 const rtc::PacketTime& time, |
| 355 int flags) { | 379 int flags) { |
| 356 // Flags shouldn't be set on the underlying TransportChannel packets. | 380 // Flags shouldn't be set on the underlying TransportChannel packets. |
| 357 ASSERT_EQ(0, flags); | 381 ASSERT_EQ(0, flags); |
| 358 | 382 |
| 359 // Look at the handshake packets to see what role we played. | 383 // Look at the handshake packets to see what role we played. |
| 360 // Check that non-handshake packets are DTLS data or SRTP bypass. | 384 // Check that non-handshake packets are DTLS data or SRTP bypass. |
| 361 if (negotiated_dtls_) { | 385 if (data[0] == 22 && size > 17) { |
| 362 if (data[0] == 22 && size > 17) { | 386 if (data[13] == 1) { |
| 363 if (data[13] == 1) { | 387 ++received_dtls_client_hellos_; |
| 364 received_dtls_client_hello_ = true; | 388 } else if (data[13] == 2) { |
| 365 } else if (data[13] == 2) { | 389 ++received_dtls_server_hellos_; |
| 366 received_dtls_server_hello_ = true; | 390 } |
| 367 } | 391 } else if (negotiated_dtls_ && !(data[0] >= 20 && data[0] <= 22)) { |
| 368 } else if (!(data[0] >= 20 && data[0] <= 22)) { | 392 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); |
| 369 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); | 393 if (data[0] == 23) { |
| 370 if (data[0] == 23) { | 394 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); |
| 371 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); | 395 } else if (IsRtpLeadByte(data[0])) { |
| 372 } else if (IsRtpLeadByte(data[0])) { | 396 ASSERT_TRUE(VerifyPacket(data, size, NULL)); |
| 373 ASSERT_TRUE(VerifyPacket(data, size, NULL)); | |
| 374 } | |
| 375 } | 397 } |
| 376 } | 398 } |
| 377 } | 399 } |
| 378 | 400 |
| 379 private: | 401 private: |
| 380 std::string name_; | 402 std::string name_; |
| 381 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 403 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
| 382 std::unique_ptr<cricket::FakeTransport> transport_; | 404 std::unique_ptr<cricket::FakeTransport> transport_; |
| 383 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 405 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
| 384 size_t packet_size_; | 406 size_t packet_size_ = 0u; |
| 385 std::set<int> received_; | 407 std::set<int> received_; |
| 386 bool use_dtls_srtp_; | 408 bool use_dtls_srtp_ = false; |
| 387 rtc::SSLProtocolVersion ssl_max_version_; | 409 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
| 388 bool negotiated_dtls_; | 410 bool negotiated_dtls_ = false; |
| 389 bool received_dtls_client_hello_; | 411 int received_dtls_client_hellos_ = 0; |
| 390 bool received_dtls_server_hello_; | 412 int received_dtls_server_hellos_ = 0; |
| 391 rtc::SentPacket sent_packet_; | 413 rtc::SentPacket sent_packet_; |
| 392 }; | 414 }; |
| 393 | 415 |
| 394 | 416 |
| 395 class DtlsTransportChannelTest : public testing::Test { | 417 class DtlsTransportChannelTest : public testing::Test { |
| 396 public: | 418 public: |
| 397 DtlsTransportChannelTest() | 419 DtlsTransportChannelTest() |
| 398 : client1_("P1"), | 420 : client1_("P1"), |
| 399 client2_("P2"), | 421 client2_("P2"), |
| 400 channel_ct_(1), | 422 channel_ct_(1), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 430 if (c2) | 452 if (c2) |
| 431 client2_.SetupSrtp(); | 453 client2_.SetupSrtp(); |
| 432 | 454 |
| 433 if (c1 && c2) | 455 if (c1 && c2) |
| 434 use_dtls_srtp_ = true; | 456 use_dtls_srtp_ = true; |
| 435 } | 457 } |
| 436 | 458 |
| 437 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { | 459 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { |
| 438 Negotiate(client1_role, client2_role); | 460 Negotiate(client1_role, client2_role); |
| 439 | 461 |
| 440 bool rv = client1_.Connect(&client2_); | 462 bool rv = client1_.Connect(&client2_, false); |
| 441 EXPECT_TRUE(rv); | 463 EXPECT_TRUE(rv); |
| 442 if (!rv) | 464 if (!rv) |
| 443 return false; | 465 return false; |
| 444 | 466 |
| 445 EXPECT_TRUE_WAIT( | 467 EXPECT_TRUE_WAIT( |
| 446 client1_.all_channels_writable() && client2_.all_channels_writable(), | 468 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 447 10000); | 469 kTimeout); |
| 448 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) | 470 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
| 449 return false; | 471 return false; |
| 450 | 472 |
| 451 // Check that we used the right roles. | 473 // Check that we used the right roles. |
| 452 if (use_dtls_) { | 474 if (use_dtls_) { |
| 453 rtc::SSLRole client1_ssl_role = | 475 rtc::SSLRole client1_ssl_role = |
| 454 (client1_role == cricket::CONNECTIONROLE_ACTIVE || | 476 (client1_role == cricket::CONNECTIONROLE_ACTIVE || |
| 455 (client2_role == cricket::CONNECTIONROLE_PASSIVE && | 477 (client2_role == cricket::CONNECTIONROLE_PASSIVE && |
| 456 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? | 478 client1_role == cricket::CONNECTIONROLE_ACTPASS)) ? |
| 457 rtc::SSL_CLIENT : rtc::SSL_SERVER; | 479 rtc::SSL_CLIENT : rtc::SSL_SERVER; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 client2_role, client1_role, flags); | 550 client2_role, client1_role, flags); |
| 529 client1_.Negotiate(&client2_, cricket::CA_ANSWER, | 551 client1_.Negotiate(&client2_, cricket::CA_ANSWER, |
| 530 client1_role, client2_role, flags); | 552 client1_role, client2_role, flags); |
| 531 } | 553 } |
| 532 } | 554 } |
| 533 | 555 |
| 534 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { | 556 void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) { |
| 535 LOG(LS_INFO) << "Expect packets, size=" << size; | 557 LOG(LS_INFO) << "Expect packets, size=" << size; |
| 536 client2_.ExpectPackets(channel, size); | 558 client2_.ExpectPackets(channel, size); |
| 537 client1_.SendPackets(channel, size, count, srtp); | 559 client1_.SendPackets(channel, size, count, srtp); |
| 538 EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), 10000); | 560 EXPECT_EQ_WAIT(count, client2_.NumPacketsReceived(), kTimeout); |
| 539 } | 561 } |
| 540 | 562 |
| 541 protected: | 563 protected: |
| 542 DtlsTestClient client1_; | 564 DtlsTestClient client1_; |
| 543 DtlsTestClient client2_; | 565 DtlsTestClient client2_; |
| 544 int channel_ct_; | 566 int channel_ct_; |
| 545 bool use_dtls_; | 567 bool use_dtls_; |
| 546 bool use_dtls_srtp_; | 568 bool use_dtls_srtp_; |
| 547 rtc::SSLProtocolVersion ssl_expected_version_; | 569 rtc::SSLProtocolVersion ssl_expected_version_; |
| 548 }; | 570 }; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 // in the first negotiation. | 843 // in the first negotiation. |
| 822 TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) { | 844 TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) { |
| 823 MAYBE_SKIP_TEST(HaveDtlsSrtp); | 845 MAYBE_SKIP_TEST(HaveDtlsSrtp); |
| 824 SetChannelCount(2); | 846 SetChannelCount(2); |
| 825 PrepareDtls(true, true, rtc::KT_DEFAULT); | 847 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 826 PrepareDtlsSrtp(true, true); | 848 PrepareDtlsSrtp(true, true); |
| 827 Negotiate(); | 849 Negotiate(); |
| 828 | 850 |
| 829 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, | 851 Renegotiate(&client1_, cricket::CONNECTIONROLE_ACTPASS, |
| 830 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); | 852 cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER); |
| 831 bool rv = client1_.Connect(&client2_); | 853 bool rv = client1_.Connect(&client2_, false); |
| 832 EXPECT_TRUE(rv); | 854 EXPECT_TRUE(rv); |
| 833 EXPECT_TRUE_WAIT( | 855 EXPECT_TRUE_WAIT( |
| 834 client1_.all_channels_writable() && client2_.all_channels_writable(), | 856 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 835 10000); | 857 kTimeout); |
| 836 | 858 |
| 837 TestTransfer(0, 1000, 100, true); | 859 TestTransfer(0, 1000, 100, true); |
| 838 TestTransfer(1, 1000, 100, true); | 860 TestTransfer(1, 1000, 100, true); |
| 839 } | 861 } |
| 840 | 862 |
| 841 // Test Certificates state after negotiation but before connection. | 863 // Test Certificates state after negotiation but before connection. |
| 842 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { | 864 TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) { |
| 843 MAYBE_SKIP_TEST(HaveDtls); | 865 MAYBE_SKIP_TEST(HaveDtls); |
| 844 PrepareDtls(true, true, rtc::KT_DEFAULT); | 866 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 845 Negotiate(); | 867 Negotiate(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 client1_.transport()->GetRemoteSSLCertificate(); | 901 client1_.transport()->GetRemoteSSLCertificate(); |
| 880 ASSERT_TRUE(remote_cert1); | 902 ASSERT_TRUE(remote_cert1); |
| 881 ASSERT_EQ(remote_cert1->ToPEMString(), | 903 ASSERT_EQ(remote_cert1->ToPEMString(), |
| 882 certificate2->ssl_certificate().ToPEMString()); | 904 certificate2->ssl_certificate().ToPEMString()); |
| 883 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = | 905 std::unique_ptr<rtc::SSLCertificate> remote_cert2 = |
| 884 client2_.transport()->GetRemoteSSLCertificate(); | 906 client2_.transport()->GetRemoteSSLCertificate(); |
| 885 ASSERT_TRUE(remote_cert2); | 907 ASSERT_TRUE(remote_cert2); |
| 886 ASSERT_EQ(remote_cert2->ToPEMString(), | 908 ASSERT_EQ(remote_cert2->ToPEMString(), |
| 887 certificate1->ssl_certificate().ToPEMString()); | 909 certificate1->ssl_certificate().ToPEMString()); |
| 888 } | 910 } |
| 911 |
| 912 // Test that DTLS completes promptly if a ClientHello is received before the |
| 913 // transport channel is writable (allowing a ServerHello to be sent). |
| 914 TEST_F(DtlsTransportChannelTest, TestReceiveClientHelloBeforeWritable) { |
| 915 MAYBE_SKIP_TEST(HaveDtls); |
| 916 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 917 // Exchange transport descriptions. |
| 918 Negotiate(cricket::CONNECTIONROLE_ACTPASS, cricket::CONNECTIONROLE_ACTIVE); |
| 919 |
| 920 // Make client2_ writable, but not client1_. |
| 921 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
| 922 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); |
| 923 |
| 924 // Expect a DTLS ClientHello to be sent even while client1_ isn't writable. |
| 925 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
| 926 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
| 927 |
| 928 // Now make client1_ writable and expect the handshake to complete |
| 929 // without client2_ needing to retransmit the ClientHello. |
| 930 EXPECT_TRUE(client1_.Connect(&client2_, true)); |
| 931 EXPECT_TRUE_WAIT( |
| 932 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 933 kTimeout); |
| 934 EXPECT_EQ(1, client1_.received_dtls_client_hellos()); |
| 935 } |
| 936 |
| 937 // Test that DTLS completes promptly if a ClientHello is received before the |
| 938 // transport channel has a remote fingerprint (allowing a ServerHello to be |
| 939 // sent). |
| 940 TEST_F(DtlsTransportChannelTest, |
| 941 TestReceiveClientHelloBeforeRemoteFingerprint) { |
| 942 MAYBE_SKIP_TEST(HaveDtls); |
| 943 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 944 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING); |
| 945 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED); |
| 946 |
| 947 // Make client2_ writable and give it local/remote certs, but don't yet give |
| 948 // client1_ a remote fingerprint. |
| 949 client1_.transport()->SetLocalTransportDescription( |
| 950 MakeTransportDescription(client1_.certificate(), |
| 951 cricket::CONNECTIONROLE_ACTPASS), |
| 952 cricket::CA_OFFER, nullptr); |
| 953 client2_.Negotiate(&client1_, cricket::CA_ANSWER, |
| 954 cricket::CONNECTIONROLE_ACTIVE, |
| 955 cricket::CONNECTIONROLE_ACTPASS, 0); |
| 956 EXPECT_TRUE(client2_.Connect(&client1_, true)); |
| 957 EXPECT_TRUE_WAIT(client2_.all_raw_channels_writable(), kTimeout); |
| 958 |
| 959 // Expect a DTLS ClientHello to be sent even while client1_ doesn't have a |
| 960 // remote fingerprint. |
| 961 EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout); |
| 962 EXPECT_FALSE(client1_.all_raw_channels_writable()); |
| 963 |
| 964 // Now make give client1_ its remote fingerprint and make it writable, and |
| 965 // expect the handshake to complete without client2_ needing to retransmit |
| 966 // the ClientHello. |
| 967 client1_.transport()->SetRemoteTransportDescription( |
| 968 MakeTransportDescription(client2_.certificate(), |
| 969 cricket::CONNECTIONROLE_ACTIVE), |
| 970 cricket::CA_ANSWER, nullptr); |
| 971 EXPECT_TRUE(client1_.Connect(&client2_, true)); |
| 972 EXPECT_TRUE_WAIT( |
| 973 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 974 kTimeout); |
| 975 EXPECT_EQ(1, client1_.received_dtls_client_hellos()); |
| 976 } |
| OLD | NEW |