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 |