OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| 3 * |
| 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 |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/p2p/quic/quictransportchannel.h" |
| 12 |
| 13 #include <set> |
| 14 #include <string> |
| 15 #include <vector> |
| 16 |
| 17 #include "webrtc/base/common.h" |
| 18 #include "webrtc/base/gunit.h" |
| 19 #include "webrtc/base/scoped_ptr.h" |
| 20 #include "webrtc/base/sslidentity.h" |
| 21 #include "webrtc/p2p/base/faketransportcontroller.h" |
| 22 |
| 23 using cricket::ConnectionRole; |
| 24 using cricket::IceRole; |
| 25 using cricket::QuicTransportChannel; |
| 26 using cricket::TransportChannel; |
| 27 using cricket::TransportDescription; |
| 28 |
| 29 // Timeout in milliseconds for asynchronous operations in unit tests. |
| 30 const int kTimeoutMs = 1000; |
| 31 |
| 32 // Export keying material parameters. |
| 33 const char kExporterLabel[] = "label"; |
| 34 const uint8_t kExporterContext[] = "context"; |
| 35 const size_t kExporterContextLength = sizeof(kExporterContext); |
| 36 const size_t kOutputKeyLength = 20; |
| 37 |
| 38 // Indicates channel has no write error. |
| 39 const int kNoWriteError = 0; |
| 40 |
| 41 // ICE parameters. |
| 42 const char kIceUfrag[] = "TESTICEUFRAG0001"; |
| 43 const char kIcePwd[] = "TESTICEPWD00000000000001"; |
| 44 |
| 45 // QUIC packet parameters. |
| 46 const net::IPAddressNumber kIpAddress(net::kIPv4AddressSize, 0); |
| 47 const net::IPEndPoint kIpEndpoint(kIpAddress, 0); |
| 48 |
| 49 // Packet number offset for making test packets. |
| 50 const size_t kPacketNumOffset = 8; |
| 51 |
| 52 // Detects incoming RTP packets. |
| 53 bool IsRtpLeadByte(uint8_t b) { |
| 54 return (b & 0xC0) == 0x80; |
| 55 } |
| 56 // Detects incoming QUIC packets. |
| 57 bool IsQuicLeadByte(uint8_t b) { |
| 58 return (b & 0x80) == 0; |
| 59 } |
| 60 |
| 61 // Maps SSL role to ICE connection role. The peer with a client role is assumed |
| 62 // to be the one who initiates the connection. |
| 63 ConnectionRole SslRoleToConnectionRole(rtc::SSLRole ssl_role) { |
| 64 return (ssl_role == rtc::SSL_CLIENT) ? cricket::CONNECTIONROLE_ACTIVE |
| 65 : cricket::CONNECTIONROLE_PASSIVE; |
| 66 } |
| 67 |
| 68 // Allows cricket::FakeTransportChannel to simulate write blocked |
| 69 // and write error states. |
| 70 // TODO(mikescarlett): Consider adding this functionality to |
| 71 // cricket::FakeTransportChannel. |
| 72 class FakeTransportChannel : public cricket::FakeTransportChannel { |
| 73 public: |
| 74 FakeTransportChannel(const std::string& name, int component) |
| 75 : cricket::FakeTransportChannel(name, component), error_(kNoWriteError) {} |
| 76 int GetError() override { return error_; } |
| 77 void SetError(int error) { error_ = error; } |
| 78 int SendPacket(const char* data, |
| 79 size_t len, |
| 80 const rtc::PacketOptions& options, |
| 81 int flags) override { |
| 82 if (error_ == kNoWriteError) { |
| 83 return cricket::FakeTransportChannel::SendPacket(data, len, options, |
| 84 flags); |
| 85 } |
| 86 return -1; |
| 87 } |
| 88 |
| 89 private: |
| 90 int error_; |
| 91 }; |
| 92 |
| 93 // Peer who establishes a handshake using a QuicTransportChannel, which wraps |
| 94 // a FakeTransportChannel to simulate network connectivity and ICE negotiation. |
| 95 class QuicTestPeer : public sigslot::has_slots<> { |
| 96 public: |
| 97 explicit QuicTestPeer(const std::string& name) |
| 98 : name_(name), |
| 99 bytes_sent_(0), |
| 100 fake_channel_(name_, 0), |
| 101 quic_channel_(&fake_channel_) { |
| 102 quic_channel_.SignalReadPacket.connect( |
| 103 this, &QuicTestPeer::OnTransportChannelReadPacket); |
| 104 fake_channel_.SetAsync(true); |
| 105 } |
| 106 |
| 107 // Connects |fake_channel_| to that of the other peer. |
| 108 void Connect(QuicTestPeer* peer) { |
| 109 fake_channel_.Connect(); |
| 110 peer->fake_channel_.Connect(); |
| 111 fake_channel_.SetDestination(&peer->fake_channel_); |
| 112 } |
| 113 |
| 114 // Disconnects |fake_channel_|. |
| 115 void Disconnect() { fake_channel_.SetDestination(nullptr); } |
| 116 |
| 117 // Simulates the fingerprint exchange and ICE parameter negotiation |
| 118 // which is done before QUIC handshake is started. |
| 119 void NegotiateBeforeQuic(QuicTestPeer* peer, |
| 120 IceRole ice_role, |
| 121 rtc::SSLRole local_ssl_role, |
| 122 rtc::SSLRole remote_ssl_role) { |
| 123 rtc::scoped_refptr<rtc::RTCCertificate> local_cert = |
| 124 quic_channel()->GetLocalCertificate(); |
| 125 rtc::scoped_refptr<rtc::RTCCertificate> remote_cert = |
| 126 local_cert ? peer->quic_channel()->GetLocalCertificate() : nullptr; |
| 127 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint; |
| 128 rtc::scoped_ptr<rtc::SSLFingerprint> remote_fingerprint; |
| 129 if (local_cert) { |
| 130 local_fingerprint.reset(CreateFingerprint(local_cert.get())); |
| 131 ASSERT_NE(local_fingerprint, nullptr); |
| 132 } |
| 133 if (remote_cert) { |
| 134 remote_fingerprint.reset(CreateFingerprint(remote_cert.get())); |
| 135 ASSERT_NE(remote_fingerprint, nullptr); |
| 136 } |
| 137 SetIceCredentials(ice_role, local_fingerprint.get(), |
| 138 remote_fingerprint.get(), local_ssl_role, |
| 139 remote_ssl_role); |
| 140 quic_channel_.SetSslRole(local_ssl_role); |
| 141 if (remote_fingerprint) { |
| 142 quic_channel_.SetRemoteFingerprint( |
| 143 remote_fingerprint->algorithm, |
| 144 reinterpret_cast<const uint8_t*>(remote_fingerprint->digest.data()), |
| 145 remote_fingerprint->digest.size()); |
| 146 } |
| 147 } |
| 148 |
| 149 // Generates ICE credentials and passes them to |quic_channel_|. |
| 150 void SetIceCredentials(IceRole ice_role, |
| 151 rtc::SSLFingerprint* local_fingerprint, |
| 152 rtc::SSLFingerprint* remote_fingerprint, |
| 153 rtc::SSLRole local_ssl_role, |
| 154 rtc::SSLRole remote_ssl_role) { |
| 155 quic_channel_.SetIceRole(ice_role); |
| 156 quic_channel_.SetIceTiebreaker( |
| 157 (ice_role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
| 158 |
| 159 ConnectionRole local_connection_role = |
| 160 SslRoleToConnectionRole(local_ssl_role); |
| 161 ConnectionRole remote_connection_role = |
| 162 SslRoleToConnectionRole(remote_ssl_role); |
| 163 |
| 164 TransportDescription local_desc(std::vector<std::string>(), kIceUfrag, |
| 165 kIcePwd, cricket::ICEMODE_FULL, |
| 166 local_connection_role, local_fingerprint); |
| 167 TransportDescription remote_desc( |
| 168 std::vector<std::string>(), kIceUfrag, kIcePwd, cricket::ICEMODE_FULL, |
| 169 remote_connection_role, remote_fingerprint); |
| 170 |
| 171 quic_channel_.SetIceCredentials(local_desc.ice_ufrag, local_desc.ice_pwd); |
| 172 quic_channel_.SetRemoteIceCredentials(remote_desc.ice_ufrag, |
| 173 remote_desc.ice_pwd); |
| 174 } |
| 175 |
| 176 // Sets certificate for |quic_channel_|. |
| 177 void SetLocalCertificate(rtc::KeyType key_type) { |
| 178 quic_channel_.SetLocalCertificate( |
| 179 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( |
| 180 rtc::SSLIdentity::Generate(name_, key_type)))); |
| 181 } |
| 182 |
| 183 // Creates fingerprint from certificate. |
| 184 rtc::SSLFingerprint* CreateFingerprint(rtc::RTCCertificate* cert) { |
| 185 std::string digest_algorithm; |
| 186 bool get_digest_algorithm = |
| 187 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm); |
| 188 if (!get_digest_algorithm || digest_algorithm.empty()) { |
| 189 return nullptr; |
| 190 } |
| 191 scoped_ptr<rtc::SSLFingerprint> fingerprint( |
| 192 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); |
| 193 if (digest_algorithm != rtc::DIGEST_SHA_256) { |
| 194 return nullptr; |
| 195 } |
| 196 return fingerprint.release(); |
| 197 } |
| 198 |
| 199 // Send packets to the other peer via |quic_channel_|. |
| 200 void SendPackets(const size_t kSize, |
| 201 size_t count, |
| 202 bool srtp, |
| 203 bool expect_success) { |
| 204 ASSERT_GT(kSize, kPacketNumOffset); |
| 205 char packet[kSize]; |
| 206 for (size_t sent = 0; sent < count; ++sent) { |
| 207 // Fill the packet with a known value and a sequence number to check |
| 208 // against, and make sure that it doesn't look like QUIC. |
| 209 memset(&packet, sent & 0xff, kSize); |
| 210 packet[0] = (srtp) ? 0x80 : 0x00; |
| 211 rtc::SetBE32(&packet + kPacketNumOffset, static_cast<uint32_t>(sent)); |
| 212 // Only set the bypass flag if we've activated QUIC. |
| 213 int flags = srtp ? cricket::PF_SRTP_BYPASS : 0; |
| 214 rtc::PacketOptions packet_options; |
| 215 int rv = |
| 216 quic_channel_.SendPacket(&packet[0], kSize, packet_options, flags); |
| 217 if (rv > 0) { |
| 218 ASSERT_TRUE(expect_success); |
| 219 ASSERT_EQ(kSize, static_cast<size_t>(rv)); |
| 220 bytes_sent_ += rv; |
| 221 } else { |
| 222 ASSERT_FALSE(expect_success); |
| 223 ASSERT_EQ(-1, rv); |
| 224 } |
| 225 } |
| 226 } |
| 227 |
| 228 // Sends a non-SRTP packet with the PF_SRTP_BYPASS flag. |
| 229 int SendInvalidSrtpPacket(size_t channel, size_t size) { |
| 230 rtc::scoped_ptr<char[]> packet(new char[size]); |
| 231 // Fill the packet with 0 to form an invalid SRTP packet. |
| 232 memset(packet.get(), 0, size); |
| 233 |
| 234 rtc::PacketOptions packet_options; |
| 235 return quic_channel_.SendPacket(packet.get(), size, packet_options, |
| 236 cricket::PF_SRTP_BYPASS); |
| 237 } |
| 238 |
| 239 net::WriteResult WriteQuicPacket(std::string packet) { |
| 240 return quic_channel_.WritePacket(packet.data(), packet.size(), kIpAddress, |
| 241 kIpEndpoint); |
| 242 } |
| 243 |
| 244 bool handshake_confirmed() const { |
| 245 return quic_channel_.quic_state() == cricket::QUIC_TRANSPORT_CONNECTED; |
| 246 } |
| 247 |
| 248 void ClearPackets() { received_.clear(); } |
| 249 |
| 250 void SetWriteError(int error) { fake_channel_.SetError(error); } |
| 251 |
| 252 size_t num_packets_received() const { return received_.size(); } |
| 253 |
| 254 size_t bytes_sent() const { return bytes_sent_; } |
| 255 |
| 256 FakeTransportChannel* fake_channel() { return &fake_channel_; } |
| 257 |
| 258 QuicTransportChannel* quic_channel() { return &quic_channel_; } |
| 259 |
| 260 private: |
| 261 // QUIC channel callback. |
| 262 void OnTransportChannelReadPacket(TransportChannel* channel, |
| 263 const char* data, |
| 264 size_t size, |
| 265 const rtc::PacketTime& packet_time, |
| 266 int flags) { |
| 267 uint32_t packet_num = rtc::GetBE32(data + kPacketNumOffset); |
| 268 // Check that packet number was not received yet. |
| 269 ASSERT_TRUE(received_.insert(packet_num).second); |
| 270 // Only SRTP packets should have the bypass flag set. |
| 271 int expected_flags = handshake_confirmed() && IsRtpLeadByte(data[0]) |
| 272 ? cricket::PF_SRTP_BYPASS |
| 273 : 0; |
| 274 ASSERT_EQ(expected_flags, flags); |
| 275 } |
| 276 |
| 277 std::string name_; // Channel name. |
| 278 std::set<int> received_; // Packet numbers received. |
| 279 size_t bytes_sent_; // Bytes sent by QUIC channel. |
| 280 FakeTransportChannel fake_channel_; |
| 281 QuicTransportChannel quic_channel_; |
| 282 }; |
| 283 |
| 284 class QuicTransportChannelTest : public testing::Test { |
| 285 public: |
| 286 QuicTransportChannelTest() : peer1_("P1"), peer2_("P2") {} |
| 287 |
| 288 // Sets certificates for QUIC channels. |
| 289 void PrepareQuic(bool c1, bool c2, rtc::KeyType key_type) { |
| 290 if (c1) { |
| 291 peer1_.SetLocalCertificate(key_type); |
| 292 } |
| 293 if (c2) { |
| 294 peer2_.SetLocalCertificate(key_type); |
| 295 } |
| 296 } |
| 297 |
| 298 // Performs preconditions of QUIC handshake, then connects the fake transport |
| 299 // channels of each peer. As a side effect, the QUIC channels should start |
| 300 // sending handshake messages. |
| 301 void Connect(rtc::SSLRole peer1_ssl_role, rtc::SSLRole peer2_ssl_role) { |
| 302 ASSERT_NE(peer1_ssl_role, peer2_ssl_role); |
| 303 NegotiateBeforeQuic(peer1_ssl_role, peer2_ssl_role); |
| 304 peer1_.Connect(&peer2_); |
| 305 } |
| 306 |
| 307 // By default, |peer1_| has client role and |peer2_| has server role in the |
| 308 // QUIC handshake. |
| 309 void Connect() { Connect(rtc::SSL_CLIENT, rtc::SSL_SERVER); } |
| 310 |
| 311 // Disconnects the fake transport channels. |
| 312 void Disconnect() { |
| 313 peer1_.Disconnect(); |
| 314 peer2_.Disconnect(); |
| 315 } |
| 316 |
| 317 // Sets up ICE parameters and exchanges fingerprints before QUIC handshake. |
| 318 void NegotiateBeforeQuic(rtc::SSLRole peer1_ssl_role, |
| 319 rtc::SSLRole peer2_ssl_role) { |
| 320 peer1_.NegotiateBeforeQuic(&peer2_, cricket::ICEROLE_CONTROLLED, |
| 321 peer1_ssl_role, peer2_ssl_role); |
| 322 peer2_.NegotiateBeforeQuic(&peer1_, cricket::ICEROLE_CONTROLLING, |
| 323 peer2_ssl_role, peer1_ssl_role); |
| 324 } |
| 325 |
| 326 // Check whether |peer2_| receives packets sent by |peer1_|. |
| 327 void TestTransfer(size_t size, size_t count, bool srtp, bool expect_success) { |
| 328 LOG(LS_INFO) << "Expect packets, size=" << size << ", srtp=" << srtp |
| 329 << ", success=" << expect_success; |
| 330 peer2_.ClearPackets(); |
| 331 peer1_.SendPackets(size, count, srtp, expect_success); |
| 332 |
| 333 if (expect_success) { |
| 334 EXPECT_EQ_WAIT(count, peer2_.num_packets_received(), kTimeoutMs); |
| 335 EXPECT_EQ(size * count, peer1_.bytes_sent()); |
| 336 } else { |
| 337 EXPECT_EQ(0u, peer1_.bytes_sent()); |
| 338 } |
| 339 } |
| 340 |
| 341 // Check that peers export identical keying material after the QUIC handshake. |
| 342 void TestExportKeyingMaterial() { |
| 343 uint8_t key1[kOutputKeyLength]; |
| 344 uint8_t key2[kOutputKeyLength]; |
| 345 |
| 346 bool from_success = peer1_.quic_channel()->ExportKeyingMaterial( |
| 347 kExporterLabel, kExporterContext, kExporterContextLength, true, key1, |
| 348 kOutputKeyLength); |
| 349 ASSERT_TRUE(from_success); |
| 350 bool to_success = peer2_.quic_channel()->ExportKeyingMaterial( |
| 351 kExporterLabel, kExporterContext, kExporterContextLength, true, key2, |
| 352 kOutputKeyLength); |
| 353 ASSERT_TRUE(to_success); |
| 354 |
| 355 EXPECT_EQ(0, memcmp(key1, key2, sizeof(key1))); |
| 356 } |
| 357 |
| 358 // Checks if QUIC handshake is done. |
| 359 bool handshake_confirmed() const { |
| 360 return peer1_.handshake_confirmed() && peer2_.handshake_confirmed(); |
| 361 } |
| 362 |
| 363 // Checks if QUIC channels are writable. |
| 364 bool quic_writable() { |
| 365 return peer1_.quic_channel()->writable() && |
| 366 peer2_.quic_channel()->writable(); |
| 367 } |
| 368 |
| 369 protected: |
| 370 // QUIC peer with a client role, who initiates the QUIC handshake. |
| 371 QuicTestPeer peer1_; |
| 372 // QUIC peer with a server role, who responds to the client peer. |
| 373 QuicTestPeer peer2_; |
| 374 }; |
| 375 |
| 376 // Test that the QUIC channel passes down ICE parameters to the underlying ICE |
| 377 // channel. |
| 378 TEST_F(QuicTransportChannelTest, ChannelSetupIce) { |
| 379 NegotiateBeforeQuic(rtc::SSL_CLIENT, rtc::SSL_SERVER); |
| 380 FakeTransportChannel* channel1 = peer1_.fake_channel(); |
| 381 FakeTransportChannel* channel2 = peer2_.fake_channel(); |
| 382 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); |
| 383 EXPECT_EQ(2u, channel1->IceTiebreaker()); |
| 384 EXPECT_EQ(kIceUfrag, channel1->ice_ufrag()); |
| 385 EXPECT_EQ(kIcePwd, channel1->ice_pwd()); |
| 386 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole()); |
| 387 EXPECT_EQ(1u, channel2->IceTiebreaker()); |
| 388 } |
| 389 |
| 390 // Test export keying material after QUIC handshake. |
| 391 TEST_F(QuicTransportChannelTest, ExportKeyingMaterial) { |
| 392 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 393 Connect(); |
| 394 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 395 TestExportKeyingMaterial(); |
| 396 } |
| 397 |
| 398 // Test that QUIC channel connectivity state is consistent |
| 399 // with underlying channel before the QUIC handshake. |
| 400 TEST_F(QuicTransportChannelTest, ConnectDisconnect) { |
| 401 Connect(); |
| 402 EXPECT_TRUE(quic_writable()); |
| 403 Disconnect(); |
| 404 EXPECT_FALSE(quic_writable()); |
| 405 Connect(); |
| 406 EXPECT_TRUE(quic_writable()); |
| 407 Disconnect(); |
| 408 EXPECT_FALSE(quic_writable()); |
| 409 } |
| 410 |
| 411 // Test that once handshake begins, QUIC is not connected until its completion. |
| 412 TEST_F(QuicTransportChannelTest, QuicHandshake) { |
| 413 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 414 Connect(); |
| 415 EXPECT_FALSE(quic_writable()); |
| 416 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 417 EXPECT_TRUE(quic_writable()); |
| 418 } |
| 419 |
| 420 // Test that QuicTransportChannel::SendPacket fails before peers are connected. |
| 421 TEST_F(QuicTransportChannelTest, TransferBeforeConnect) { |
| 422 TestTransfer(100, 1, false, false); |
| 423 TestTransfer(100, 1, true, false); |
| 424 } |
| 425 |
| 426 // Connect without QUIC, and transfer non-SRTP data. |
| 427 TEST_F(QuicTransportChannelTest, TransferBeforeQuic) { |
| 428 Connect(); |
| 429 TestTransfer(100, 10, false, true); |
| 430 } |
| 431 |
| 432 // Connect without QUIC, and transfer SRTP data. |
| 433 TEST_F(QuicTransportChannelTest, TransferSrtpBeforeQuic) { |
| 434 Connect(); |
| 435 TestTransfer(100, 10, true, true); |
| 436 } |
| 437 |
| 438 // Connect with QUIC, and transfer SRTP data. |
| 439 TEST_F(QuicTransportChannelTest, TransferSrtpAfterQuic) { |
| 440 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 441 Connect(); |
| 442 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 443 TestTransfer(100, 10, true, true); |
| 444 } |
| 445 |
| 446 // Connect with QUIC, and test that invalid SRTP (non-SRTP data with |
| 447 // PF_SRTP_BYPASS flag) fails to send with return value -1. |
| 448 TEST_F(QuicTransportChannelTest, TransferInvalidSrtpAfterQuic) { |
| 449 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 450 Connect(); |
| 451 int result = peer1_.SendInvalidSrtpPacket(0, 100); |
| 452 EXPECT_EQ(-1, result); |
| 453 EXPECT_EQ(0u, peer2_.num_packets_received()); |
| 454 } |
| 455 |
| 456 // Test QuicTransportChannel::WritePacket return values under various states |
| 457 // of the wrapped channel. |
| 458 TEST_F(QuicTransportChannelTest, QuicWritePacket) { |
| 459 peer1_.fake_channel()->Connect(); |
| 460 peer2_.fake_channel()->Connect(); |
| 461 peer1_.fake_channel()->SetDestination(peer2_.fake_channel()); |
| 462 |
| 463 // Write blocked error. |
| 464 peer1_.SetWriteError(EWOULDBLOCK); |
| 465 std::string packet = "FAKEQUICPACKET"; |
| 466 net::WriteResult write_blocked_result = peer1_.WriteQuicPacket(packet); |
| 467 EXPECT_EQ(net::WRITE_STATUS_BLOCKED, write_blocked_result.status); |
| 468 EXPECT_EQ(EWOULDBLOCK, write_blocked_result.error_code); |
| 469 |
| 470 // Errors other than write blocked. |
| 471 peer1_.SetWriteError(ETIMEDOUT); |
| 472 net::WriteResult write_error_result = peer1_.WriteQuicPacket(packet); |
| 473 EXPECT_EQ(net::WRITE_STATUS_BLOCKED, write_error_result.status); |
| 474 EXPECT_EQ(ETIMEDOUT, write_error_result.error_code); |
| 475 |
| 476 // No error. |
| 477 peer1_.SetWriteError(kNoWriteError); |
| 478 net::WriteResult no_error_result = peer1_.WriteQuicPacket(packet); |
| 479 EXPECT_EQ(net::WRITE_STATUS_OK, no_error_result.status); |
| 480 EXPECT_EQ(static_cast<int>(packet.size()), no_error_result.bytes_written); |
| 481 } |
| 482 |
| 483 // Test that SSL roles can be reversed before QUIC handshake. |
| 484 TEST_F(QuicTransportChannelTest, QuicRoleReversalBeforeQuic) { |
| 485 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 486 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 487 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 488 } |
| 489 |
| 490 // Test that SSL roles cannot be reversed after QUIC handshake. SetSslRole |
| 491 // returns true if the current SSL role equals the proposed SSL role. |
| 492 TEST_F(QuicTransportChannelTest, QuicRoleReversalAfterQuic) { |
| 493 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 494 Connect(); |
| 495 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 496 EXPECT_FALSE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 497 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 498 EXPECT_FALSE(peer2_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 499 EXPECT_TRUE(peer2_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 500 } |
| 501 |
| 502 // Set SSL role, then check that GetSslRole returns the same value. |
| 503 TEST_F(QuicTransportChannelTest, SetGetSslRole) { |
| 504 ASSERT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 505 rtc::scoped_ptr<rtc::SSLRole> role(new rtc::SSLRole()); |
| 506 ASSERT_TRUE(peer1_.quic_channel()->GetSslRole(role.get())); |
| 507 EXPECT_EQ(rtc::SSL_SERVER, *role); |
| 508 } |
| 509 |
| 510 // Test that after QUIC handshake is complete, QUIC handshake remains confirmed |
| 511 // even if underlying channel reconnects. |
| 512 TEST_F(QuicTransportChannelTest, HandshakeConfirmedAfterReconnect) { |
| 513 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 514 Connect(); |
| 515 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 516 Disconnect(); |
| 517 EXPECT_TRUE(handshake_confirmed()); |
| 518 Connect(); |
| 519 EXPECT_TRUE(handshake_confirmed()); |
| 520 } |
| 521 |
| 522 // Test that QUIC is able to resume a handshake if the channel becomes write |
| 523 // blocked then writable again. |
| 524 TEST_F(QuicTransportChannelTest, TestQuicCryptoStreamWriteBlocked) { |
| 525 PrepareQuic(true, true, rtc::KT_DEFAULT); |
| 526 peer1_.SetWriteError(EWOULDBLOCK); |
| 527 ASSERT_FALSE(peer1_.quic_channel()->HasDataToWrite()); |
| 528 Connect(); |
| 529 ASSERT_TRUE(peer1_.quic_channel()->HasDataToWrite()); |
| 530 ASSERT_FALSE(handshake_confirmed()); |
| 531 peer1_.SetWriteError(kNoWriteError); |
| 532 peer1_.quic_channel()->OnCanWrite(); |
| 533 ASSERT_FALSE(peer1_.quic_channel()->HasDataToWrite()); |
| 534 ASSERT_TRUE_WAIT(handshake_confirmed(), kTimeoutMs); |
| 535 } |
OLD | NEW |