| 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 27 matching lines...) Expand all Loading... |
| 38 static bool IsRtpLeadByte(uint8_t b) { | 38 static bool IsRtpLeadByte(uint8_t b) { |
| 39 return ((b & 0xC0) == 0x80); | 39 return ((b & 0xC0) == 0x80); |
| 40 } | 40 } |
| 41 | 41 |
| 42 cricket::TransportDescription MakeTransportDescription( | 42 cricket::TransportDescription MakeTransportDescription( |
| 43 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, | 43 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
| 44 cricket::ConnectionRole role) { | 44 cricket::ConnectionRole role) { |
| 45 std::unique_ptr<rtc::SSLFingerprint> fingerprint; | 45 std::unique_ptr<rtc::SSLFingerprint> fingerprint; |
| 46 if (cert) { | 46 if (cert) { |
| 47 std::string digest_algorithm; | 47 std::string digest_algorithm; |
| 48 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm); | 48 EXPECT_TRUE( |
| 49 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm)); |
| 50 EXPECT_FALSE(digest_algorithm.empty()); |
| 49 fingerprint.reset( | 51 fingerprint.reset( |
| 50 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); | 52 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); |
| 53 EXPECT_TRUE(fingerprint.get() != NULL); |
| 54 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); |
| 51 } | 55 } |
| 52 return cricket::TransportDescription(std::vector<std::string>(), kIceUfrag1, | 56 return cricket::TransportDescription(std::vector<std::string>(), kIceUfrag1, |
| 53 kIcePwd1, cricket::ICEMODE_FULL, role, | 57 kIcePwd1, cricket::ICEMODE_FULL, role, |
| 54 fingerprint.get()); | 58 fingerprint.get()); |
| 55 } | 59 } |
| 56 | 60 |
| 57 using cricket::ConnectionRole; | 61 using cricket::ConnectionRole; |
| 58 | 62 |
| 59 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; | 63 enum Flags { NF_REOFFER = 0x1, NF_EXPECT_FAILURE = 0x2 }; |
| 60 | 64 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 121 |
| 118 // 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 |
| 119 // both sides support DTLS. | 123 // both sides support DTLS. |
| 120 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, | 124 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, |
| 121 ConnectionRole local_role, ConnectionRole remote_role, | 125 ConnectionRole local_role, ConnectionRole remote_role, |
| 122 int flags) { | 126 int flags) { |
| 123 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, | 127 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, |
| 124 local_role, remote_role, flags); | 128 local_role, remote_role, flags); |
| 125 } | 129 } |
| 126 | 130 |
| 131 void MaybeSetSrtpCryptoSuites() { |
| 132 if (!use_dtls_srtp_) { |
| 133 return; |
| 134 } |
| 135 std::vector<int> ciphers; |
| 136 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80); |
| 137 // SRTP ciphers will be set only in the beginning. |
| 138 for (cricket::DtlsTransportChannelWrapper* channel : channels_) { |
| 139 EXPECT_TRUE(channel->SetSrtpCryptoSuites(ciphers)); |
| 140 } |
| 141 } |
| 142 |
| 143 void SetLocalTransportDescription( |
| 144 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
| 145 cricket::ContentAction action, |
| 146 ConnectionRole role, |
| 147 int flags) { |
| 148 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
| 149 // content action is CA_ANSWER. |
| 150 bool expect_success = |
| 151 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
| 152 EXPECT_EQ(expect_success, |
| 153 transport_->SetLocalTransportDescription( |
| 154 MakeTransportDescription(cert, role), action, nullptr)); |
| 155 set_local_cert_ = (cert != nullptr); |
| 156 } |
| 157 |
| 158 void SetRemoteTransportDescription( |
| 159 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, |
| 160 cricket::ContentAction action, |
| 161 ConnectionRole role, |
| 162 int flags) { |
| 163 // If |NF_EXPECT_FAILURE| is set, expect SRTD or SLTD to fail when |
| 164 // content action is CA_ANSWER. |
| 165 bool expect_success = |
| 166 !((action == cricket::CA_ANSWER) && (flags & NF_EXPECT_FAILURE)); |
| 167 EXPECT_EQ(expect_success, |
| 168 transport_->SetRemoteTransportDescription( |
| 169 MakeTransportDescription(cert, role), action, nullptr)); |
| 170 set_remote_cert_ = (cert != nullptr); |
| 171 } |
| 172 |
| 127 // Allow any DTLS configuration to be specified (including invalid ones). | 173 // Allow any DTLS configuration to be specified (including invalid ones). |
| 128 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, | 174 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, |
| 129 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, | 175 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, |
| 130 cricket::ContentAction action, | 176 cricket::ContentAction action, |
| 131 ConnectionRole local_role, | 177 ConnectionRole local_role, |
| 132 ConnectionRole remote_role, | 178 ConnectionRole remote_role, |
| 133 int flags) { | 179 int flags) { |
| 134 std::unique_ptr<rtc::SSLFingerprint> local_fingerprint; | 180 if (!(flags & NF_REOFFER)) { |
| 135 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint; | 181 // SRTP ciphers will be set only in the beginning. |
| 136 if (local_cert) { | 182 MaybeSetSrtpCryptoSuites(); |
| 137 std::string digest_algorithm; | |
| 138 ASSERT_TRUE(local_cert->ssl_certificate().GetSignatureDigestAlgorithm( | |
| 139 &digest_algorithm)); | |
| 140 ASSERT_FALSE(digest_algorithm.empty()); | |
| 141 local_fingerprint.reset(rtc::SSLFingerprint::Create( | |
| 142 digest_algorithm, local_cert->identity())); | |
| 143 ASSERT_TRUE(local_fingerprint.get() != NULL); | |
| 144 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
| 145 } | 183 } |
| 146 if (remote_cert) { | 184 if (action == cricket::CA_OFFER) { |
| 147 std::string digest_algorithm; | 185 SetLocalTransportDescription(local_cert, cricket::CA_OFFER, local_role, |
| 148 ASSERT_TRUE(remote_cert->ssl_certificate().GetSignatureDigestAlgorithm( | 186 flags); |
| 149 &digest_algorithm)); | 187 SetRemoteTransportDescription(remote_cert, cricket::CA_ANSWER, |
| 150 ASSERT_FALSE(digest_algorithm.empty()); | 188 remote_role, flags); |
| 151 remote_fingerprint.reset(rtc::SSLFingerprint::Create( | 189 } else { |
| 152 digest_algorithm, remote_cert->identity())); | 190 SetRemoteTransportDescription(remote_cert, cricket::CA_OFFER, remote_role, |
| 153 ASSERT_TRUE(remote_fingerprint.get() != NULL); | 191 flags); |
| 154 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | 192 // If remote if the offerer and has no DTLS support, answer will be |
| 193 // without any fingerprint. |
| 194 SetLocalTransportDescription(remote_cert ? local_cert : nullptr, |
| 195 cricket::CA_ANSWER, local_role, flags); |
| 155 } | 196 } |
| 156 | |
| 157 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) { | |
| 158 // SRTP ciphers will be set only in the beginning. | |
| 159 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | |
| 160 channels_.begin(); it != channels_.end(); ++it) { | |
| 161 std::vector<int> ciphers; | |
| 162 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80); | |
| 163 ASSERT_TRUE((*it)->SetSrtpCryptoSuites(ciphers)); | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 cricket::TransportDescription local_desc( | |
| 168 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
| 169 local_role, | |
| 170 // If remote if the offerer and has no DTLS support, answer will be | |
| 171 // without any fingerprint. | |
| 172 (action == cricket::CA_ANSWER && !remote_cert) | |
| 173 ? nullptr | |
| 174 : local_fingerprint.get()); | |
| 175 | |
| 176 cricket::TransportDescription remote_desc( | |
| 177 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
| 178 remote_role, remote_fingerprint.get()); | |
| 179 | |
| 180 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true; | |
| 181 // If |expect_success| is false, expect SRTD or SLTD to fail when | |
| 182 // content action is CA_ANSWER. | |
| 183 if (action == cricket::CA_OFFER) { | |
| 184 ASSERT_TRUE(transport_->SetLocalTransportDescription( | |
| 185 local_desc, cricket::CA_OFFER, NULL)); | |
| 186 ASSERT_EQ(expect_success, transport_->SetRemoteTransportDescription( | |
| 187 remote_desc, cricket::CA_ANSWER, NULL)); | |
| 188 } else { | |
| 189 ASSERT_TRUE(transport_->SetRemoteTransportDescription( | |
| 190 remote_desc, cricket::CA_OFFER, NULL)); | |
| 191 ASSERT_EQ(expect_success, transport_->SetLocalTransportDescription( | |
| 192 local_desc, cricket::CA_ANSWER, NULL)); | |
| 193 } | |
| 194 negotiated_dtls_ = (local_cert && remote_cert); | |
| 195 } | 197 } |
| 196 | 198 |
| 197 bool Connect(DtlsTestClient* peer, bool asymmetric) { | 199 bool Connect(DtlsTestClient* peer, bool asymmetric) { |
| 198 transport_->SetDestination(peer->transport_.get(), asymmetric); | 200 transport_->SetDestination(peer->transport_.get(), asymmetric); |
| 199 return true; | 201 return true; |
| 200 } | 202 } |
| 201 | 203 |
| 202 bool all_channels_writable() const { | 204 bool all_channels_writable() const { |
| 203 if (channels_.empty()) { | 205 if (channels_.empty()) { |
| 204 return false; | 206 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 220 return false; | 222 return false; |
| 221 } | 223 } |
| 222 } | 224 } |
| 223 return true; | 225 return true; |
| 224 } | 226 } |
| 225 | 227 |
| 226 int received_dtls_client_hellos() const { | 228 int received_dtls_client_hellos() const { |
| 227 return received_dtls_client_hellos_; | 229 return received_dtls_client_hellos_; |
| 228 } | 230 } |
| 229 | 231 |
| 232 bool negotiated_dtls() const { return set_local_cert_ && set_remote_cert_; } |
| 233 |
| 230 void CheckRole(rtc::SSLRole role) { | 234 void CheckRole(rtc::SSLRole role) { |
| 231 if (role == rtc::SSL_CLIENT) { | 235 if (role == rtc::SSL_CLIENT) { |
| 232 ASSERT_EQ(0, received_dtls_client_hellos_); | 236 ASSERT_EQ(0, received_dtls_client_hellos_); |
| 233 ASSERT_GT(received_dtls_server_hellos_, 0); | 237 ASSERT_GT(received_dtls_server_hellos_, 0); |
| 234 } else { | 238 } else { |
| 235 ASSERT_GT(received_dtls_client_hellos_, 0); | 239 ASSERT_GT(received_dtls_client_hellos_, 0); |
| 236 ASSERT_EQ(0, received_dtls_server_hellos_); | 240 ASSERT_EQ(0, received_dtls_server_hellos_); |
| 237 } | 241 } |
| 238 } | 242 } |
| 239 | 243 |
| 240 void CheckSrtp(int expected_crypto_suite) { | 244 void CheckSrtp(int expected_crypto_suite) { |
| 241 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | 245 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = |
| 242 channels_.begin(); it != channels_.end(); ++it) { | 246 channels_.begin(); it != channels_.end(); ++it) { |
| 243 int crypto_suite; | 247 int crypto_suite; |
| 244 | 248 |
| 245 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); | 249 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); |
| 246 if (negotiated_dtls_ && expected_crypto_suite) { | 250 if (negotiated_dtls() && expected_crypto_suite) { |
| 247 ASSERT_TRUE(rv); | 251 ASSERT_TRUE(rv); |
| 248 | 252 |
| 249 ASSERT_EQ(crypto_suite, expected_crypto_suite); | 253 ASSERT_EQ(crypto_suite, expected_crypto_suite); |
| 250 } else { | 254 } else { |
| 251 ASSERT_FALSE(rv); | 255 ASSERT_FALSE(rv); |
| 252 } | 256 } |
| 253 } | 257 } |
| 254 } | 258 } |
| 255 | 259 |
| 256 void CheckSsl() { | 260 void CheckSsl() { |
| 257 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | 261 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = |
| 258 channels_.begin(); it != channels_.end(); ++it) { | 262 channels_.begin(); it != channels_.end(); ++it) { |
| 259 int cipher; | 263 int cipher; |
| 260 | 264 |
| 261 bool rv = (*it)->GetSslCipherSuite(&cipher); | 265 bool rv = (*it)->GetSslCipherSuite(&cipher); |
| 262 if (negotiated_dtls_) { | 266 if (negotiated_dtls()) { |
| 263 ASSERT_TRUE(rv); | 267 ASSERT_TRUE(rv); |
| 264 | 268 |
| 265 EXPECT_TRUE( | 269 EXPECT_TRUE( |
| 266 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT)); | 270 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT)); |
| 267 } else { | 271 } else { |
| 268 ASSERT_FALSE(rv); | 272 ASSERT_FALSE(rv); |
| 269 } | 273 } |
| 270 } | 274 } |
| 271 } | 275 } |
| 272 | 276 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 ASSERT_EQ(0, flags); | 385 ASSERT_EQ(0, flags); |
| 382 | 386 |
| 383 // Look at the handshake packets to see what role we played. | 387 // Look at the handshake packets to see what role we played. |
| 384 // Check that non-handshake packets are DTLS data or SRTP bypass. | 388 // Check that non-handshake packets are DTLS data or SRTP bypass. |
| 385 if (data[0] == 22 && size > 17) { | 389 if (data[0] == 22 && size > 17) { |
| 386 if (data[13] == 1) { | 390 if (data[13] == 1) { |
| 387 ++received_dtls_client_hellos_; | 391 ++received_dtls_client_hellos_; |
| 388 } else if (data[13] == 2) { | 392 } else if (data[13] == 2) { |
| 389 ++received_dtls_server_hellos_; | 393 ++received_dtls_server_hellos_; |
| 390 } | 394 } |
| 391 } else if (negotiated_dtls_ && !(data[0] >= 20 && data[0] <= 22)) { | 395 } else if (negotiated_dtls() && !(data[0] >= 20 && data[0] <= 22)) { |
| 392 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); | 396 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); |
| 393 if (data[0] == 23) { | 397 if (data[0] == 23) { |
| 394 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); | 398 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); |
| 395 } else if (IsRtpLeadByte(data[0])) { | 399 } else if (IsRtpLeadByte(data[0])) { |
| 396 ASSERT_TRUE(VerifyPacket(data, size, NULL)); | 400 ASSERT_TRUE(VerifyPacket(data, size, NULL)); |
| 397 } | 401 } |
| 398 } | 402 } |
| 399 } | 403 } |
| 400 | 404 |
| 401 private: | 405 private: |
| 402 std::string name_; | 406 std::string name_; |
| 403 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 407 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
| 404 std::unique_ptr<cricket::FakeTransport> transport_; | 408 std::unique_ptr<cricket::FakeTransport> transport_; |
| 405 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 409 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
| 406 size_t packet_size_ = 0u; | 410 size_t packet_size_ = 0u; |
| 407 std::set<int> received_; | 411 std::set<int> received_; |
| 408 bool use_dtls_srtp_ = false; | 412 bool use_dtls_srtp_ = false; |
| 409 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 413 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
| 410 bool negotiated_dtls_ = false; | 414 bool set_local_cert_ = false; |
| 415 bool set_remote_cert_ = false; |
| 411 int received_dtls_client_hellos_ = 0; | 416 int received_dtls_client_hellos_ = 0; |
| 412 int received_dtls_server_hellos_ = 0; | 417 int received_dtls_server_hellos_ = 0; |
| 413 rtc::SentPacket sent_packet_; | 418 rtc::SentPacket sent_packet_; |
| 414 }; | 419 }; |
| 415 | 420 |
| 416 // 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 |
| 417 // variable. | 422 // variable. |
| 418 class DtlsTransportChannelTest : public testing::Test { | 423 class DtlsTransportChannelTest : public testing::Test { |
| 419 public: | 424 public: |
| 420 DtlsTransportChannelTest() | 425 DtlsTransportChannelTest() |
| (...skipping 29 matching lines...) Expand all Loading... |
| 450 | 455 |
| 451 if (c1) | 456 if (c1) |
| 452 client1_.SetupSrtp(); | 457 client1_.SetupSrtp(); |
| 453 if (c2) | 458 if (c2) |
| 454 client2_.SetupSrtp(); | 459 client2_.SetupSrtp(); |
| 455 | 460 |
| 456 if (c1 && c2) | 461 if (c1 && c2) |
| 457 use_dtls_srtp_ = true; | 462 use_dtls_srtp_ = true; |
| 458 } | 463 } |
| 459 | 464 |
| 460 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { | 465 // Negotiate local/remote fingerprint before or after the underlying |
| 461 Negotiate(client1_role, client2_role); | 466 // tranpsort is connected? |
| 467 enum NegotiateOrdering { NEGOTIATE_BEFORE_CONNECT, CONNECT_BEFORE_NEGOTIATE }; |
| 468 bool Connect(ConnectionRole client1_role, |
| 469 ConnectionRole client2_role, |
| 470 NegotiateOrdering ordering = NEGOTIATE_BEFORE_CONNECT) { |
| 471 bool rv; |
| 472 if (ordering == NEGOTIATE_BEFORE_CONNECT) { |
| 473 Negotiate(client1_role, client2_role); |
| 474 rv = client1_.Connect(&client2_, false); |
| 475 } else { |
| 476 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING); |
| 477 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED); |
| 478 client1_.MaybeSetSrtpCryptoSuites(); |
| 479 client2_.MaybeSetSrtpCryptoSuites(); |
| 480 // This is equivalent to an offer being processed on both sides, but an |
| 481 // answer not yet being received on the initiating side. So the |
| 482 // connection will be made before negotiation has finished on both sides. |
| 483 client1_.SetLocalTransportDescription(client1_.certificate(), |
| 484 cricket::CA_OFFER, client1_role, 0); |
| 485 client2_.SetRemoteTransportDescription( |
| 486 client1_.certificate(), cricket::CA_OFFER, client1_role, 0); |
| 487 client2_.SetLocalTransportDescription( |
| 488 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
| 489 rv = client1_.Connect(&client2_, false); |
| 490 client1_.SetRemoteTransportDescription( |
| 491 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); |
| 492 } |
| 462 | 493 |
| 463 bool rv = client1_.Connect(&client2_, false); | |
| 464 EXPECT_TRUE(rv); | 494 EXPECT_TRUE(rv); |
| 465 if (!rv) | 495 if (!rv) |
| 466 return false; | 496 return false; |
| 467 | 497 |
| 468 EXPECT_TRUE_WAIT( | 498 EXPECT_TRUE_WAIT( |
| 469 client1_.all_channels_writable() && client2_.all_channels_writable(), | 499 client1_.all_channels_writable() && client2_.all_channels_writable(), |
| 470 kTimeout); | 500 kTimeout); |
| 471 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) | 501 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
| 472 return false; | 502 return false; |
| 473 | 503 |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 // millisecond before the expected time and verify that no unexpected | 1041 // millisecond before the expected time and verify that no unexpected |
| 1012 // retransmissions were sent. Then advance it the final millisecond and | 1042 // retransmissions were sent. Then advance it the final millisecond and |
| 1013 // verify that the expected retransmission was sent. | 1043 // verify that the expected retransmission was sent. |
| 1014 fake_clock_.AdvanceTime( | 1044 fake_clock_.AdvanceTime( |
| 1015 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1)); | 1045 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1)); |
| 1016 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos()); | 1046 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos()); |
| 1017 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); | 1047 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); |
| 1018 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos()); | 1048 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos()); |
| 1019 } | 1049 } |
| 1020 } | 1050 } |
| 1051 |
| 1052 // Test that a DTLS connection can be made even if the underlying transport |
| 1053 // is connected before DTLS fingerprints/roles have been negotiated. |
| 1054 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { |
| 1055 MAYBE_SKIP_TEST(HaveDtls); |
| 1056 PrepareDtls(true, true, rtc::KT_DEFAULT); |
| 1057 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, |
| 1058 cricket::CONNECTIONROLE_ACTIVE, |
| 1059 CONNECT_BEFORE_NEGOTIATE)); |
| 1060 TestTransfer(0, 1000, 100, false); |
| 1061 } |
| OLD | NEW |