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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 | 117 |
118 // Offer DTLS if we have an identity; pass in a remote fingerprint only if | 118 // Offer DTLS if we have an identity; pass in a remote fingerprint only if |
119 // both sides support DTLS. | 119 // both sides support DTLS. |
120 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, | 120 void Negotiate(DtlsTestClient* peer, cricket::ContentAction action, |
121 ConnectionRole local_role, ConnectionRole remote_role, | 121 ConnectionRole local_role, ConnectionRole remote_role, |
122 int flags) { | 122 int flags) { |
123 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, | 123 Negotiate(certificate_, certificate_ ? peer->certificate_ : nullptr, action, |
124 local_role, remote_role, flags); | 124 local_role, remote_role, flags); |
125 } | 125 } |
126 | 126 |
127 std::unique_ptr<rtc::SSLFingerprint> MakeFingerprintFromCertificate( | |
128 const rtc::scoped_refptr<rtc::RTCCertificate>& cert) { | |
129 std::unique_ptr<rtc::SSLFingerprint> fingerprint; | |
130 if (cert) { | |
pthatcher1
2016/07/13 00:04:19
Maybe have it be early return?
if (!cert) {
ret
Taylor Brandstetter
2016/07/13 16:17:41
Done.
| |
131 std::string digest_algorithm; | |
132 EXPECT_TRUE(cert->ssl_certificate().GetSignatureDigestAlgorithm( | |
133 &digest_algorithm)); | |
134 EXPECT_FALSE(digest_algorithm.empty()); | |
135 fingerprint.reset( | |
136 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); | |
137 EXPECT_TRUE(fingerprint.get() != NULL); | |
138 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
139 } | |
140 return fingerprint; | |
141 } | |
142 | |
143 void SetLocalTransportDescription( | |
144 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, | |
145 cricket::ContentAction action, | |
146 ConnectionRole role, | |
147 int flags) { | |
148 auto fingerprint = MakeFingerprintFromCertificate(cert); | |
149 cricket::TransportDescription local_desc( | |
150 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
151 role, fingerprint.get()); | |
152 | |
153 if (action == cricket::CA_OFFER) { | |
154 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) { | |
155 // SRTP ciphers will be set only in the beginning. | |
156 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | |
157 channels_.begin(); | |
158 it != channels_.end(); ++it) { | |
pthatcher1
2016/07/13 00:04:19
c++11 style for loop?
Taylor Brandstetter
2016/07/13 16:17:41
Done.
| |
159 std::vector<int> ciphers; | |
160 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80); | |
161 EXPECT_TRUE((*it)->SetSrtpCryptoSuites(ciphers)); | |
162 } | |
163 } | |
164 | |
165 EXPECT_TRUE(transport_->SetLocalTransportDescription(local_desc, action, | |
166 nullptr)); | |
167 } else { | |
168 // If |expect_success| is false, expect SRTD or SLTD to fail when | |
169 // content action is CA_ANSWER. | |
170 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true; | |
171 EXPECT_EQ(expect_success, transport_->SetLocalTransportDescription( | |
172 local_desc, action, nullptr)); | |
173 } | |
174 set_local_cert_ = (cert != nullptr); | |
pthatcher1
2016/07/13 00:04:20
Would has_local_cert_ be a better name?
Taylor Brandstetter
2016/07/13 16:17:41
The method is called SetLocalTransportDescription
Taylor Brandstetter
2016/07/13 16:20:16
Oh I misread your comment. I thought you were aski
| |
175 } | |
176 | |
177 void SetRemoteTransportDescription( | |
178 const rtc::scoped_refptr<rtc::RTCCertificate>& cert, | |
179 cricket::ContentAction action, | |
180 ConnectionRole role, | |
181 int flags) { | |
182 auto fingerprint = MakeFingerprintFromCertificate(cert); | |
183 cricket::TransportDescription remote_desc( | |
184 std::vector<std::string>(), kIceUfrag1, kIcePwd1, cricket::ICEMODE_FULL, | |
185 role, fingerprint.get()); | |
186 | |
187 if (action == cricket::CA_OFFER) { | |
188 if (use_dtls_srtp_ && !(flags & NF_REOFFER)) { | |
189 // SRTP ciphers will be set only in the beginning. | |
190 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | |
191 channels_.begin(); | |
192 it != channels_.end(); ++it) { | |
193 std::vector<int> ciphers; | |
194 ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80); | |
195 EXPECT_TRUE((*it)->SetSrtpCryptoSuites(ciphers)); | |
196 } | |
197 } | |
pthatcher1
2016/07/13 00:04:19
It seems like a MakeTransportDescription(action, c
Taylor Brandstetter
2016/07/13 16:17:41
Setting the ciphers you mean? I'll make a separate
| |
198 | |
199 EXPECT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, action, | |
200 nullptr)); | |
201 } else { | |
202 // If |expect_success| is false, expect SRTD or SLTD to fail when | |
203 // content action is CA_ANSWER. | |
204 bool expect_success = (flags & NF_EXPECT_FAILURE) ? false : true; | |
205 EXPECT_EQ(expect_success, transport_->SetRemoteTransportDescription( | |
206 remote_desc, action, nullptr)); | |
207 } | |
208 set_remote_cert_ = (cert != nullptr); | |
209 } | |
210 | |
127 // Allow any DTLS configuration to be specified (including invalid ones). | 211 // Allow any DTLS configuration to be specified (including invalid ones). |
128 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, | 212 void Negotiate(const rtc::scoped_refptr<rtc::RTCCertificate>& local_cert, |
129 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, | 213 const rtc::scoped_refptr<rtc::RTCCertificate>& remote_cert, |
130 cricket::ContentAction action, | 214 cricket::ContentAction action, |
131 ConnectionRole local_role, | 215 ConnectionRole local_role, |
132 ConnectionRole remote_role, | 216 ConnectionRole remote_role, |
133 int flags) { | 217 int flags) { |
134 std::unique_ptr<rtc::SSLFingerprint> local_fingerprint; | 218 if (action == cricket::CA_OFFER) { |
135 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint; | 219 SetLocalTransportDescription(local_cert, cricket::CA_OFFER, local_role, |
136 if (local_cert) { | 220 flags); |
137 std::string digest_algorithm; | 221 SetRemoteTransportDescription(remote_cert, cricket::CA_ANSWER, |
138 ASSERT_TRUE(local_cert->ssl_certificate().GetSignatureDigestAlgorithm( | 222 remote_role, flags); |
139 &digest_algorithm)); | 223 } else { |
140 ASSERT_FALSE(digest_algorithm.empty()); | 224 SetRemoteTransportDescription(remote_cert, cricket::CA_OFFER, remote_role, |
141 local_fingerprint.reset(rtc::SSLFingerprint::Create( | 225 flags); |
142 digest_algorithm, local_cert->identity())); | 226 // If remote if the offerer and has no DTLS support, answer will be |
143 ASSERT_TRUE(local_fingerprint.get() != NULL); | 227 // without any fingerprint. |
144 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | 228 SetLocalTransportDescription(remote_cert ? local_cert : nullptr, |
229 cricket::CA_ANSWER, local_role, flags); | |
145 } | 230 } |
146 if (remote_cert) { | |
147 std::string digest_algorithm; | |
148 ASSERT_TRUE(remote_cert->ssl_certificate().GetSignatureDigestAlgorithm( | |
149 &digest_algorithm)); | |
150 ASSERT_FALSE(digest_algorithm.empty()); | |
151 remote_fingerprint.reset(rtc::SSLFingerprint::Create( | |
152 digest_algorithm, remote_cert->identity())); | |
153 ASSERT_TRUE(remote_fingerprint.get() != NULL); | |
154 EXPECT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
155 } | |
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 } | 231 } |
196 | 232 |
197 bool Connect(DtlsTestClient* peer, bool asymmetric) { | 233 bool Connect(DtlsTestClient* peer, bool asymmetric) { |
198 transport_->SetDestination(peer->transport_.get(), asymmetric); | 234 transport_->SetDestination(peer->transport_.get(), asymmetric); |
199 return true; | 235 return true; |
200 } | 236 } |
201 | 237 |
202 bool all_channels_writable() const { | 238 bool all_channels_writable() const { |
203 if (channels_.empty()) { | 239 if (channels_.empty()) { |
204 return false; | 240 return false; |
(...skipping 15 matching lines...) Expand all Loading... | |
220 return false; | 256 return false; |
221 } | 257 } |
222 } | 258 } |
223 return true; | 259 return true; |
224 } | 260 } |
225 | 261 |
226 int received_dtls_client_hellos() const { | 262 int received_dtls_client_hellos() const { |
227 return received_dtls_client_hellos_; | 263 return received_dtls_client_hellos_; |
228 } | 264 } |
229 | 265 |
266 bool negotiated_dtls() const { return set_local_cert_ && set_remote_cert_; } | |
267 | |
230 void CheckRole(rtc::SSLRole role) { | 268 void CheckRole(rtc::SSLRole role) { |
231 if (role == rtc::SSL_CLIENT) { | 269 if (role == rtc::SSL_CLIENT) { |
232 ASSERT_EQ(0, received_dtls_client_hellos_); | 270 ASSERT_EQ(0, received_dtls_client_hellos_); |
233 ASSERT_GT(received_dtls_server_hellos_, 0); | 271 ASSERT_GT(received_dtls_server_hellos_, 0); |
234 } else { | 272 } else { |
235 ASSERT_GT(received_dtls_client_hellos_, 0); | 273 ASSERT_GT(received_dtls_client_hellos_, 0); |
236 ASSERT_EQ(0, received_dtls_server_hellos_); | 274 ASSERT_EQ(0, received_dtls_server_hellos_); |
237 } | 275 } |
238 } | 276 } |
239 | 277 |
240 void CheckSrtp(int expected_crypto_suite) { | 278 void CheckSrtp(int expected_crypto_suite) { |
241 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | 279 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = |
242 channels_.begin(); it != channels_.end(); ++it) { | 280 channels_.begin(); it != channels_.end(); ++it) { |
243 int crypto_suite; | 281 int crypto_suite; |
244 | 282 |
245 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); | 283 bool rv = (*it)->GetSrtpCryptoSuite(&crypto_suite); |
246 if (negotiated_dtls_ && expected_crypto_suite) { | 284 if (negotiated_dtls() && expected_crypto_suite) { |
247 ASSERT_TRUE(rv); | 285 ASSERT_TRUE(rv); |
248 | 286 |
249 ASSERT_EQ(crypto_suite, expected_crypto_suite); | 287 ASSERT_EQ(crypto_suite, expected_crypto_suite); |
250 } else { | 288 } else { |
251 ASSERT_FALSE(rv); | 289 ASSERT_FALSE(rv); |
252 } | 290 } |
253 } | 291 } |
254 } | 292 } |
255 | 293 |
256 void CheckSsl() { | 294 void CheckSsl() { |
257 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = | 295 for (std::vector<cricket::DtlsTransportChannelWrapper*>::iterator it = |
258 channels_.begin(); it != channels_.end(); ++it) { | 296 channels_.begin(); it != channels_.end(); ++it) { |
259 int cipher; | 297 int cipher; |
260 | 298 |
261 bool rv = (*it)->GetSslCipherSuite(&cipher); | 299 bool rv = (*it)->GetSslCipherSuite(&cipher); |
262 if (negotiated_dtls_) { | 300 if (negotiated_dtls()) { |
263 ASSERT_TRUE(rv); | 301 ASSERT_TRUE(rv); |
264 | 302 |
265 EXPECT_TRUE( | 303 EXPECT_TRUE( |
266 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT)); | 304 rtc::SSLStreamAdapter::IsAcceptableCipher(cipher, rtc::KT_DEFAULT)); |
267 } else { | 305 } else { |
268 ASSERT_FALSE(rv); | 306 ASSERT_FALSE(rv); |
269 } | 307 } |
270 } | 308 } |
271 } | 309 } |
272 | 310 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 ASSERT_EQ(0, flags); | 419 ASSERT_EQ(0, flags); |
382 | 420 |
383 // Look at the handshake packets to see what role we played. | 421 // Look at the handshake packets to see what role we played. |
384 // Check that non-handshake packets are DTLS data or SRTP bypass. | 422 // Check that non-handshake packets are DTLS data or SRTP bypass. |
385 if (data[0] == 22 && size > 17) { | 423 if (data[0] == 22 && size > 17) { |
386 if (data[13] == 1) { | 424 if (data[13] == 1) { |
387 ++received_dtls_client_hellos_; | 425 ++received_dtls_client_hellos_; |
388 } else if (data[13] == 2) { | 426 } else if (data[13] == 2) { |
389 ++received_dtls_server_hellos_; | 427 ++received_dtls_server_hellos_; |
390 } | 428 } |
391 } else if (negotiated_dtls_ && !(data[0] >= 20 && data[0] <= 22)) { | 429 } else if (negotiated_dtls() && !(data[0] >= 20 && data[0] <= 22)) { |
392 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); | 430 ASSERT_TRUE(data[0] == 23 || IsRtpLeadByte(data[0])); |
393 if (data[0] == 23) { | 431 if (data[0] == 23) { |
394 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); | 432 ASSERT_TRUE(VerifyEncryptedPacket(data, size)); |
395 } else if (IsRtpLeadByte(data[0])) { | 433 } else if (IsRtpLeadByte(data[0])) { |
396 ASSERT_TRUE(VerifyPacket(data, size, NULL)); | 434 ASSERT_TRUE(VerifyPacket(data, size, NULL)); |
397 } | 435 } |
398 } | 436 } |
399 } | 437 } |
400 | 438 |
401 private: | 439 private: |
402 std::string name_; | 440 std::string name_; |
403 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 441 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
404 std::unique_ptr<cricket::FakeTransport> transport_; | 442 std::unique_ptr<cricket::FakeTransport> transport_; |
405 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; | 443 std::vector<cricket::DtlsTransportChannelWrapper*> channels_; |
406 size_t packet_size_ = 0u; | 444 size_t packet_size_ = 0u; |
407 std::set<int> received_; | 445 std::set<int> received_; |
408 bool use_dtls_srtp_ = false; | 446 bool use_dtls_srtp_ = false; |
409 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 447 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
410 bool negotiated_dtls_ = false; | 448 bool set_local_cert_ = false; |
449 bool set_remote_cert_ = false; | |
411 int received_dtls_client_hellos_ = 0; | 450 int received_dtls_client_hellos_ = 0; |
412 int received_dtls_server_hellos_ = 0; | 451 int received_dtls_server_hellos_ = 0; |
413 rtc::SentPacket sent_packet_; | 452 rtc::SentPacket sent_packet_; |
414 }; | 453 }; |
415 | 454 |
416 // Note that this test always uses a FakeClock, due to the |fake_clock_| member | 455 // Note that this test always uses a FakeClock, due to the |fake_clock_| member |
417 // variable. | 456 // variable. |
418 class DtlsTransportChannelTest : public testing::Test { | 457 class DtlsTransportChannelTest : public testing::Test { |
419 public: | 458 public: |
420 DtlsTransportChannelTest() | 459 DtlsTransportChannelTest() |
(...skipping 29 matching lines...) Expand all Loading... | |
450 | 489 |
451 if (c1) | 490 if (c1) |
452 client1_.SetupSrtp(); | 491 client1_.SetupSrtp(); |
453 if (c2) | 492 if (c2) |
454 client2_.SetupSrtp(); | 493 client2_.SetupSrtp(); |
455 | 494 |
456 if (c1 && c2) | 495 if (c1 && c2) |
457 use_dtls_srtp_ = true; | 496 use_dtls_srtp_ = true; |
458 } | 497 } |
459 | 498 |
460 bool Connect(ConnectionRole client1_role, ConnectionRole client2_role) { | 499 // Negotiate local/remote fingerprint before or after the underlying |
461 Negotiate(client1_role, client2_role); | 500 // tranpsort is connected? |
501 enum NegotiateOrdering { NEGOTIATE_BEFORE_CONNECT, CONNECT_BEFORE_NEGOTIATE }; | |
502 bool Connect(ConnectionRole client1_role, | |
503 ConnectionRole client2_role, | |
504 NegotiateOrdering ordering = NEGOTIATE_BEFORE_CONNECT) { | |
505 bool rv; | |
506 if (ordering == NEGOTIATE_BEFORE_CONNECT) { | |
507 Negotiate(client1_role, client2_role); | |
508 rv = client1_.Connect(&client2_, false); | |
509 } else { | |
510 client1_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLING); | |
511 client2_.SetupChannels(channel_ct_, cricket::ICEROLE_CONTROLLED); | |
512 // This is equivalent to an offer being processed on both sides, but an | |
513 // answer not yet being received on the initiating side. So the | |
514 // connection will be made before negotiation has finished on both sides. | |
515 client1_.SetLocalTransportDescription(client1_.certificate(), | |
516 cricket::CA_OFFER, client1_role, 0); | |
517 client2_.SetRemoteTransportDescription( | |
518 client1_.certificate(), cricket::CA_OFFER, client1_role, 0); | |
519 client2_.SetLocalTransportDescription( | |
520 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | |
521 rv = client1_.Connect(&client2_, false); | |
522 client1_.SetRemoteTransportDescription( | |
523 client2_.certificate(), cricket::CA_ANSWER, client2_role, 0); | |
524 } | |
462 | 525 |
463 bool rv = client1_.Connect(&client2_, false); | |
464 EXPECT_TRUE(rv); | 526 EXPECT_TRUE(rv); |
465 if (!rv) | 527 if (!rv) |
466 return false; | 528 return false; |
467 | 529 |
468 EXPECT_TRUE_WAIT( | 530 EXPECT_TRUE_WAIT( |
469 client1_.all_channels_writable() && client2_.all_channels_writable(), | 531 client1_.all_channels_writable() && client2_.all_channels_writable(), |
470 kTimeout); | 532 kTimeout); |
471 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) | 533 if (!client1_.all_channels_writable() || !client2_.all_channels_writable()) |
472 return false; | 534 return false; |
473 | 535 |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 // millisecond before the expected time and verify that no unexpected | 1073 // millisecond before the expected time and verify that no unexpected |
1012 // retransmissions were sent. Then advance it the final millisecond and | 1074 // retransmissions were sent. Then advance it the final millisecond and |
1013 // verify that the expected retransmission was sent. | 1075 // verify that the expected retransmission was sent. |
1014 fake_clock_.AdvanceTime( | 1076 fake_clock_.AdvanceTime( |
1015 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1)); | 1077 rtc::TimeDelta::FromMilliseconds(timeout_schedule_ms[i] - 1)); |
1016 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos()); | 1078 EXPECT_EQ(expected_hellos, client1_.received_dtls_client_hellos()); |
1017 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); | 1079 fake_clock_.AdvanceTime(rtc::TimeDelta::FromMilliseconds(1)); |
1018 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos()); | 1080 EXPECT_EQ(++expected_hellos, client1_.received_dtls_client_hellos()); |
1019 } | 1081 } |
1020 } | 1082 } |
1083 | |
1084 // Test that a DTLS connection can be made even if the underlying transport | |
1085 // is connected before DTLS fingerprints/roles have been negotiated. | |
1086 TEST_F(DtlsTransportChannelTest, TestConnectBeforeNegotiate) { | |
1087 MAYBE_SKIP_TEST(HaveDtls); | |
1088 PrepareDtls(true, true, rtc::KT_DEFAULT); | |
1089 ASSERT_TRUE(Connect(cricket::CONNECTIONROLE_ACTPASS, | |
1090 cricket::CONNECTIONROLE_ACTIVE, | |
1091 CONNECT_BEFORE_NEGOTIATE)); | |
1092 TestTransfer(0, 1000, 100, false); | |
1093 } | |
OLD | NEW |