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 static const int kTimeoutMs = 1000; |
| 31 |
| 32 // Export keying material parameters. |
| 33 static const char kExporterLabel[] = "label"; |
| 34 static const uint8_t kExporterContext[] = "context"; |
| 35 static const size_t kExporterContextLength = sizeof(kExporterContext); |
| 36 static const size_t kOutputKeyLength = 20; |
| 37 |
| 38 // Packet size for SRTP. |
| 39 static const size_t kPacketSize = 100; |
| 40 |
| 41 // Indicates channel has no write error. |
| 42 static const int kNoWriteError = 0; |
| 43 |
| 44 // ICE parameters. |
| 45 static const char kIceUfrag[] = "TESTICEUFRAG0001"; |
| 46 static const char kIcePwd[] = "TESTICEPWD00000000000001"; |
| 47 |
| 48 // QUIC packet parameters. |
| 49 static const net::IPAddressNumber kIpAddress(net::kIPv4AddressSize, 0); |
| 50 static const net::IPEndPoint kIpEndpoint(kIpAddress, 0); |
| 51 |
| 52 // Detects incoming RTP packets. |
| 53 static bool IsRtpLeadByte(uint8_t b) { |
| 54 return (b & 0xC0) == 0x80; |
| 55 } |
| 56 |
| 57 // Maps SSL role to ICE connection role. The peer with a client role is assumed |
| 58 // to be the one who initiates the connection. |
| 59 static ConnectionRole SslRoleToConnectionRole(rtc::SSLRole ssl_role) { |
| 60 return (ssl_role == rtc::SSL_CLIENT) ? cricket::CONNECTIONROLE_ACTIVE |
| 61 : cricket::CONNECTIONROLE_PASSIVE; |
| 62 } |
| 63 |
| 64 // Allows cricket::FakeTransportChannel to simulate write blocked |
| 65 // and write error states. |
| 66 // TODO(mikescarlett): Add this functionality to cricket::FakeTransportChannel. |
| 67 class FailableTransportChannel : public cricket::FakeTransportChannel { |
| 68 public: |
| 69 FailableTransportChannel(const std::string& name, int component) |
| 70 : cricket::FakeTransportChannel(name, component), error_(kNoWriteError) {} |
| 71 int GetError() override { return error_; } |
| 72 void SetError(int error) { error_ = error; } |
| 73 int SendPacket(const char* data, |
| 74 size_t len, |
| 75 const rtc::PacketOptions& options, |
| 76 int flags) override { |
| 77 if (error_ == kNoWriteError) { |
| 78 return cricket::FakeTransportChannel::SendPacket(data, len, options, |
| 79 flags); |
| 80 } |
| 81 return -1; |
| 82 } |
| 83 |
| 84 private: |
| 85 int error_; |
| 86 }; |
| 87 |
| 88 // Peer who establishes a handshake using a QuicTransportChannel, which wraps |
| 89 // a FailableTransportChannel to simulate network connectivity and ICE |
| 90 // negotiation. |
| 91 class QuicTestPeer : public sigslot::has_slots<> { |
| 92 public: |
| 93 explicit QuicTestPeer(const std::string& name) |
| 94 : name_(name), |
| 95 bytes_sent_(0), |
| 96 ice_channel_(name_, 0), |
| 97 quic_channel_(&ice_channel_) { |
| 98 quic_channel_.SignalReadPacket.connect( |
| 99 this, &QuicTestPeer::OnTransportChannelReadPacket); |
| 100 ice_channel_.SetAsync(true); |
| 101 rtc::scoped_refptr<rtc::RTCCertificate> local_cert = |
| 102 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( |
| 103 rtc::SSLIdentity::Generate(name_, rtc::KT_DEFAULT))); |
| 104 quic_channel_.SetLocalCertificate(local_cert); |
| 105 local_fingerprint_.reset(CreateFingerprint(local_cert.get())); |
| 106 } |
| 107 |
| 108 // Connects |ice_channel_| to that of the other peer. |
| 109 void Connect(QuicTestPeer* other_peer) { |
| 110 ice_channel_.Connect(); |
| 111 other_peer->ice_channel_.Connect(); |
| 112 ice_channel_.SetDestination(&other_peer->ice_channel_); |
| 113 } |
| 114 |
| 115 // Disconnects |ice_channel_|. |
| 116 void Disconnect() { ice_channel_.SetDestination(nullptr); } |
| 117 |
| 118 // Generates ICE credentials and passes them to |quic_channel_|. |
| 119 void SetIceParameters(IceRole local_ice_role, |
| 120 ConnectionRole local_connection_role, |
| 121 ConnectionRole remote_connection_role, |
| 122 rtc::SSLFingerprint* remote_fingerprint) { |
| 123 quic_channel_.SetIceRole(local_ice_role); |
| 124 quic_channel_.SetIceTiebreaker( |
| 125 (local_ice_role == cricket::ICEROLE_CONTROLLING) ? 1 : 2); |
| 126 |
| 127 TransportDescription local_desc( |
| 128 std::vector<std::string>(), kIceUfrag, kIcePwd, cricket::ICEMODE_FULL, |
| 129 local_connection_role, local_fingerprint_.get()); |
| 130 TransportDescription remote_desc( |
| 131 std::vector<std::string>(), kIceUfrag, kIcePwd, cricket::ICEMODE_FULL, |
| 132 remote_connection_role, remote_fingerprint); |
| 133 |
| 134 quic_channel_.SetIceCredentials(local_desc.ice_ufrag, local_desc.ice_pwd); |
| 135 quic_channel_.SetRemoteIceCredentials(remote_desc.ice_ufrag, |
| 136 remote_desc.ice_pwd); |
| 137 } |
| 138 |
| 139 // Creates fingerprint from certificate. |
| 140 rtc::SSLFingerprint* CreateFingerprint(rtc::RTCCertificate* cert) { |
| 141 std::string digest_algorithm; |
| 142 bool get_digest_algorithm = |
| 143 cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_algorithm); |
| 144 if (!get_digest_algorithm || digest_algorithm.empty()) { |
| 145 return nullptr; |
| 146 } |
| 147 scoped_ptr<rtc::SSLFingerprint> fingerprint( |
| 148 rtc::SSLFingerprint::Create(digest_algorithm, cert->identity())); |
| 149 if (digest_algorithm != rtc::DIGEST_SHA_256) { |
| 150 return nullptr; |
| 151 } |
| 152 return fingerprint.release(); |
| 153 } |
| 154 |
| 155 // Send SRTP packet to the other peer via |quic_channel_|. |
| 156 int SendSrtpPacket() { |
| 157 char packet[kPacketSize]; |
| 158 packet[0] = 0x80; // Make the packet header look like RTP. |
| 159 int rv = quic_channel_.SendPacket( |
| 160 &packet[0], kPacketSize, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS); |
| 161 bytes_sent_ += rv; |
| 162 return rv; |
| 163 } |
| 164 |
| 165 // Sends a non-SRTP packet with the PF_SRTP_BYPASS flag via |quic_channel_|. |
| 166 int SendInvalidSrtpPacket() { |
| 167 char packet[kPacketSize]; |
| 168 // Fill the packet with 0 to form an invalid SRTP packet. |
| 169 memset(packet, 0, kPacketSize); |
| 170 return quic_channel_.SendPacket( |
| 171 &packet[0], kPacketSize, rtc::PacketOptions(), cricket::PF_SRTP_BYPASS); |
| 172 } |
| 173 |
| 174 // Sends an RTP packet to the other peer via |quic_channel_|, without the SRTP |
| 175 // bypass flag. |
| 176 int SendRtpPacket() { |
| 177 char packet[kPacketSize]; |
| 178 packet[0] = 0x80; // Make the packet header look like RTP. |
| 179 return quic_channel_.SendPacket(&packet[0], kPacketSize, |
| 180 rtc::PacketOptions(), 0); |
| 181 } |
| 182 |
| 183 void ClearBytesSent() { bytes_sent_ = 0; } |
| 184 |
| 185 void ClearBytesReceived() { bytes_received_ = 0; } |
| 186 |
| 187 void SetWriteError(int error) { ice_channel_.SetError(error); } |
| 188 |
| 189 size_t bytes_received() const { return bytes_received_; } |
| 190 |
| 191 size_t bytes_sent() const { return bytes_sent_; } |
| 192 |
| 193 FailableTransportChannel* ice_channel() { return &ice_channel_; } |
| 194 |
| 195 QuicTransportChannel* quic_channel() { return &quic_channel_; } |
| 196 |
| 197 rtc::scoped_ptr<rtc::SSLFingerprint>& local_fingerprint() { |
| 198 return local_fingerprint_; |
| 199 } |
| 200 |
| 201 private: |
| 202 // QUIC channel callback. |
| 203 void OnTransportChannelReadPacket(TransportChannel* channel, |
| 204 const char* data, |
| 205 size_t size, |
| 206 const rtc::PacketTime& packet_time, |
| 207 int flags) { |
| 208 bytes_received_ += size; |
| 209 // Only SRTP packets should have the bypass flag set. |
| 210 int expected_flags = IsRtpLeadByte(data[0]) ? cricket::PF_SRTP_BYPASS : 0; |
| 211 ASSERT_EQ(expected_flags, flags); |
| 212 } |
| 213 |
| 214 std::string name_; // Channel name. |
| 215 size_t bytes_sent_; // Bytes sent by QUIC channel. |
| 216 size_t bytes_received_; // Bytes received by fake channel. |
| 217 FailableTransportChannel ice_channel_; // Simulates an ICE channel. |
| 218 QuicTransportChannel quic_channel_; // QUIC channel to test. |
| 219 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint_; |
| 220 }; |
| 221 |
| 222 class QuicTransportChannelTest : public testing::Test { |
| 223 public: |
| 224 QuicTransportChannelTest() : peer1_("P1"), peer2_("P2") {} |
| 225 |
| 226 // Performs negotiation before QUIC handshake, then connects the fake |
| 227 // transport channels of each peer. As a side effect, the QUIC channels |
| 228 // start sending handshake messages. |peer1_| has a client role and |peer2_| |
| 229 // has server role in the QUIC handshake. |
| 230 void Connect() { |
| 231 SetIceAndCryptoParameters(rtc::SSL_CLIENT, rtc::SSL_SERVER); |
| 232 peer1_.Connect(&peer2_); |
| 233 } |
| 234 |
| 235 // Disconnects the fake transport channels. |
| 236 void Disconnect() { |
| 237 peer1_.Disconnect(); |
| 238 peer2_.Disconnect(); |
| 239 } |
| 240 |
| 241 // Sets up ICE parameters and exchanges fingerprints before QUIC handshake. |
| 242 void SetIceAndCryptoParameters(rtc::SSLRole peer1_ssl_role, |
| 243 rtc::SSLRole peer2_ssl_role) { |
| 244 peer1_.quic_channel()->SetSslRole(peer1_ssl_role); |
| 245 peer2_.quic_channel()->SetSslRole(peer2_ssl_role); |
| 246 |
| 247 rtc::scoped_ptr<rtc::SSLFingerprint>& peer1_fingerprint = |
| 248 peer1_.local_fingerprint(); |
| 249 rtc::scoped_ptr<rtc::SSLFingerprint>& peer2_fingerprint = |
| 250 peer2_.local_fingerprint(); |
| 251 |
| 252 peer1_.quic_channel()->SetRemoteFingerprint( |
| 253 peer2_fingerprint->algorithm, |
| 254 reinterpret_cast<const uint8_t*>(peer2_fingerprint->digest.data()), |
| 255 peer2_fingerprint->digest.size()); |
| 256 peer2_.quic_channel()->SetRemoteFingerprint( |
| 257 peer1_fingerprint->algorithm, |
| 258 reinterpret_cast<const uint8_t*>(peer1_fingerprint->digest.data()), |
| 259 peer1_fingerprint->digest.size()); |
| 260 |
| 261 ConnectionRole peer1_connection_role = |
| 262 SslRoleToConnectionRole(peer1_ssl_role); |
| 263 ConnectionRole peer2_connection_role = |
| 264 SslRoleToConnectionRole(peer2_ssl_role); |
| 265 |
| 266 peer1_.SetIceParameters(cricket::ICEROLE_CONTROLLED, peer1_connection_role, |
| 267 peer2_connection_role, peer2_fingerprint.get()); |
| 268 peer2_.SetIceParameters(cricket::ICEROLE_CONTROLLING, peer2_connection_role, |
| 269 peer1_connection_role, peer1_fingerprint.get()); |
| 270 } |
| 271 |
| 272 // Checks if QUIC handshake is done. |
| 273 bool quic_connected() { |
| 274 return peer1_.quic_channel()->quic_state() == |
| 275 cricket::QUIC_TRANSPORT_CONNECTED && |
| 276 peer2_.quic_channel()->quic_state() == |
| 277 cricket::QUIC_TRANSPORT_CONNECTED; |
| 278 } |
| 279 |
| 280 // Checks if QUIC channels are writable. |
| 281 bool quic_writable() { |
| 282 return peer1_.quic_channel()->writable() && |
| 283 peer2_.quic_channel()->writable(); |
| 284 } |
| 285 |
| 286 protected: |
| 287 // QUIC peer with a client role, who initiates the QUIC handshake. |
| 288 QuicTestPeer peer1_; |
| 289 // QUIC peer with a server role, who responds to the client peer. |
| 290 QuicTestPeer peer2_; |
| 291 }; |
| 292 |
| 293 // Test that the QUIC channel passes ICE parameters to the underlying ICE |
| 294 // channel. |
| 295 TEST_F(QuicTransportChannelTest, ChannelSetupIce) { |
| 296 SetIceAndCryptoParameters(rtc::SSL_CLIENT, rtc::SSL_SERVER); |
| 297 FailableTransportChannel* channel1 = peer1_.ice_channel(); |
| 298 FailableTransportChannel* channel2 = peer2_.ice_channel(); |
| 299 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel1->GetIceRole()); |
| 300 EXPECT_EQ(2u, channel1->IceTiebreaker()); |
| 301 EXPECT_EQ(kIceUfrag, channel1->ice_ufrag()); |
| 302 EXPECT_EQ(kIcePwd, channel1->ice_pwd()); |
| 303 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel2->GetIceRole()); |
| 304 EXPECT_EQ(1u, channel2->IceTiebreaker()); |
| 305 } |
| 306 |
| 307 // Test that export keying material generates identical keys for both peers |
| 308 // after the QUIC handshake. |
| 309 TEST_F(QuicTransportChannelTest, ExportKeyingMaterial) { |
| 310 Connect(); |
| 311 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 312 uint8_t key1[kOutputKeyLength]; |
| 313 uint8_t key2[kOutputKeyLength]; |
| 314 |
| 315 bool from_success = peer1_.quic_channel()->ExportKeyingMaterial( |
| 316 kExporterLabel, kExporterContext, kExporterContextLength, true, key1, |
| 317 kOutputKeyLength); |
| 318 ASSERT_TRUE(from_success); |
| 319 bool to_success = peer2_.quic_channel()->ExportKeyingMaterial( |
| 320 kExporterLabel, kExporterContext, kExporterContextLength, true, key2, |
| 321 kOutputKeyLength); |
| 322 ASSERT_TRUE(to_success); |
| 323 |
| 324 EXPECT_EQ(0, memcmp(key1, key2, sizeof(key1))); |
| 325 } |
| 326 |
| 327 // Test that the QUIC channel is not writable before the QUIC handshake. |
| 328 TEST_F(QuicTransportChannelTest, NotWritableBeforeHandshake) { |
| 329 Connect(); |
| 330 EXPECT_FALSE(quic_writable()); |
| 331 Disconnect(); |
| 332 EXPECT_FALSE(quic_writable()); |
| 333 Connect(); |
| 334 EXPECT_FALSE(quic_writable()); |
| 335 } |
| 336 |
| 337 // Test that once handshake begins, QUIC is not writable until its completion. |
| 338 TEST_F(QuicTransportChannelTest, QuicHandshake) { |
| 339 Connect(); |
| 340 EXPECT_FALSE(quic_writable()); |
| 341 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 342 EXPECT_TRUE(quic_writable()); |
| 343 } |
| 344 |
| 345 // Test that Non-SRTP data is not sent using SendPacket(), regardless of QUIC |
| 346 // channel state. |
| 347 TEST_F(QuicTransportChannelTest, TransferNonSrtp) { |
| 348 // Send data before ICE channel is connected. |
| 349 peer1_.ClearBytesSent(); |
| 350 peer2_.ClearBytesReceived(); |
| 351 ASSERT_EQ(-1, peer1_.SendRtpPacket()); |
| 352 EXPECT_EQ(0u, peer1_.bytes_sent()); |
| 353 // Send data after ICE channel is connected, before QUIC handshake. |
| 354 Connect(); |
| 355 peer1_.ClearBytesSent(); |
| 356 peer2_.ClearBytesReceived(); |
| 357 ASSERT_EQ(-1, peer1_.SendRtpPacket()); |
| 358 EXPECT_EQ(0u, peer1_.bytes_sent()); |
| 359 // Send data after QUIC handshake. |
| 360 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 361 peer1_.ClearBytesSent(); |
| 362 peer2_.ClearBytesReceived(); |
| 363 ASSERT_EQ(-1, peer1_.SendRtpPacket()); |
| 364 EXPECT_EQ(0u, peer1_.bytes_sent()); |
| 365 } |
| 366 |
| 367 // Test that SRTP data is always be sent, regardless of QUIC channel state, when |
| 368 // the ICE channel is connected. |
| 369 TEST_F(QuicTransportChannelTest, TransferSrtp) { |
| 370 // Send data after ICE channel is connected, before QUIC handshake. |
| 371 Connect(); |
| 372 peer1_.ClearBytesSent(); |
| 373 peer2_.ClearBytesReceived(); |
| 374 ASSERT_EQ(kPacketSize, static_cast<size_t>(peer1_.SendSrtpPacket())); |
| 375 EXPECT_EQ_WAIT(kPacketSize, peer2_.bytes_received(), kTimeoutMs); |
| 376 EXPECT_EQ(kPacketSize, peer1_.bytes_sent()); |
| 377 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 378 // Send data after QUIC handshake. |
| 379 peer1_.ClearBytesSent(); |
| 380 peer2_.ClearBytesReceived(); |
| 381 ASSERT_EQ(kPacketSize, static_cast<size_t>(peer1_.SendSrtpPacket())); |
| 382 EXPECT_EQ_WAIT(kPacketSize, peer2_.bytes_received(), kTimeoutMs); |
| 383 EXPECT_EQ(kPacketSize, peer1_.bytes_sent()); |
| 384 } |
| 385 |
| 386 // Test that invalid SRTP (non-SRTP data with |
| 387 // PF_SRTP_BYPASS flag) fails to send with return value -1. |
| 388 TEST_F(QuicTransportChannelTest, TransferInvalidSrtp) { |
| 389 peer1_.ClearBytesSent(); |
| 390 peer2_.ClearBytesReceived(); |
| 391 EXPECT_EQ(-1, peer1_.SendInvalidSrtpPacket()); |
| 392 EXPECT_EQ(0u, peer2_.bytes_received()); |
| 393 Connect(); |
| 394 peer1_.ClearBytesSent(); |
| 395 peer2_.ClearBytesReceived(); |
| 396 EXPECT_EQ(-1, peer1_.SendInvalidSrtpPacket()); |
| 397 EXPECT_EQ(0u, peer2_.bytes_received()); |
| 398 } |
| 399 |
| 400 // Test that QuicTransportChannel::WritePacket blocks when the ICE |
| 401 // channel is not writable, and otherwise succeeds. |
| 402 TEST_F(QuicTransportChannelTest, QuicWritePacket) { |
| 403 peer1_.ice_channel()->Connect(); |
| 404 peer2_.ice_channel()->Connect(); |
| 405 peer1_.ice_channel()->SetDestination(peer2_.ice_channel()); |
| 406 std::string packet = "FAKEQUICPACKET"; |
| 407 |
| 408 // QUIC should be write blocked when the ICE channel is not writable. |
| 409 peer1_.ice_channel()->SetWritable(false); |
| 410 EXPECT_TRUE(peer1_.quic_channel()->IsWriteBlocked()); |
| 411 net::WriteResult write_blocked_result = peer1_.quic_channel()->WritePacket( |
| 412 packet.data(), packet.size(), kIpAddress, kIpEndpoint); |
| 413 EXPECT_EQ(net::WRITE_STATUS_BLOCKED, write_blocked_result.status); |
| 414 EXPECT_EQ(EWOULDBLOCK, write_blocked_result.error_code); |
| 415 |
| 416 // QUIC should ignore errors when the ICE channel is writable. |
| 417 peer1_.ice_channel()->SetWritable(true); |
| 418 EXPECT_FALSE(peer1_.quic_channel()->IsWriteBlocked()); |
| 419 peer1_.SetWriteError(EWOULDBLOCK); |
| 420 net::WriteResult ignore_error_result = peer1_.quic_channel()->WritePacket( |
| 421 packet.data(), packet.size(), kIpAddress, kIpEndpoint); |
| 422 EXPECT_EQ(net::WRITE_STATUS_OK, ignore_error_result.status); |
| 423 EXPECT_EQ(0, ignore_error_result.bytes_written); |
| 424 |
| 425 peer1_.SetWriteError(kNoWriteError); |
| 426 net::WriteResult no_error_result = peer1_.quic_channel()->WritePacket( |
| 427 packet.data(), packet.size(), kIpAddress, kIpEndpoint); |
| 428 EXPECT_EQ(net::WRITE_STATUS_OK, no_error_result.status); |
| 429 EXPECT_EQ(static_cast<int>(packet.size()), no_error_result.bytes_written); |
| 430 } |
| 431 |
| 432 // Test that SSL roles can be reversed before QUIC handshake. |
| 433 TEST_F(QuicTransportChannelTest, QuicRoleReversalBeforeQuic) { |
| 434 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 435 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 436 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 437 } |
| 438 |
| 439 // Test that SSL roles cannot be reversed after the QUIC handshake. SetSslRole |
| 440 // returns true if the current SSL role equals the proposed SSL role. |
| 441 TEST_F(QuicTransportChannelTest, QuicRoleReversalAfterQuic) { |
| 442 Connect(); |
| 443 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 444 EXPECT_FALSE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 445 EXPECT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 446 EXPECT_FALSE(peer2_.quic_channel()->SetSslRole(rtc::SSL_CLIENT)); |
| 447 EXPECT_TRUE(peer2_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 448 } |
| 449 |
| 450 // Set the SSL role, then test that GetSslRole returns the same value. |
| 451 TEST_F(QuicTransportChannelTest, SetGetSslRole) { |
| 452 ASSERT_TRUE(peer1_.quic_channel()->SetSslRole(rtc::SSL_SERVER)); |
| 453 rtc::scoped_ptr<rtc::SSLRole> role(new rtc::SSLRole()); |
| 454 ASSERT_TRUE(peer1_.quic_channel()->GetSslRole(role.get())); |
| 455 EXPECT_EQ(rtc::SSL_SERVER, *role); |
| 456 } |
| 457 |
| 458 // Test that after the QUIC handshake is complete, the QUIC handshake remains |
| 459 // confirmed even if the ICE channel reconnects. |
| 460 TEST_F(QuicTransportChannelTest, HandshakeConfirmedAfterReconnect) { |
| 461 Connect(); |
| 462 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); |
| 463 Disconnect(); |
| 464 EXPECT_TRUE(quic_connected()); |
| 465 Connect(); |
| 466 EXPECT_TRUE(quic_connected()); |
| 467 } |
OLD | NEW |