 Chromium Code Reviews
 Chromium Code Reviews Issue 1888903002:
  Fix QuicSession to unbuffer data when the QuicTransportChannel reconnects  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1888903002:
  Fix QuicSession to unbuffer data when the QuicTransportChannel reconnects  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 | 88 | 
| 89 // Peer who establishes a handshake using a QuicTransportChannel, which wraps | 89 // Peer who establishes a handshake using a QuicTransportChannel, which wraps | 
| 90 // a FailableTransportChannel to simulate network connectivity and ICE | 90 // a FailableTransportChannel to simulate network connectivity and ICE | 
| 91 // negotiation. | 91 // negotiation. | 
| 92 class QuicTestPeer : public sigslot::has_slots<> { | 92 class QuicTestPeer : public sigslot::has_slots<> { | 
| 93 public: | 93 public: | 
| 94 explicit QuicTestPeer(const std::string& name) | 94 explicit QuicTestPeer(const std::string& name) | 
| 95 : name_(name), | 95 : name_(name), | 
| 96 bytes_sent_(0), | 96 bytes_sent_(0), | 
| 97 ice_channel_(name_, 0), | 97 ice_channel_(name_, 0), | 
| 98 quic_channel_(&ice_channel_) { | 98 quic_channel_(&ice_channel_), | 
| 99 num_incoming_quic_streams_(0) { | |
| 99 quic_channel_.SignalReadPacket.connect( | 100 quic_channel_.SignalReadPacket.connect( | 
| 100 this, &QuicTestPeer::OnTransportChannelReadPacket); | 101 this, &QuicTestPeer::OnTransportChannelReadPacket); | 
| 101 quic_channel_.SignalIncomingStream.connect(this, | 102 quic_channel_.SignalIncomingStream.connect(this, | 
| 102 &QuicTestPeer::OnIncomingStream); | 103 &QuicTestPeer::OnIncomingStream); | 
| 103 quic_channel_.SignalClosed.connect(this, &QuicTestPeer::OnClosed); | 104 quic_channel_.SignalClosed.connect(this, &QuicTestPeer::OnClosed); | 
| 104 ice_channel_.SetAsync(true); | 105 ice_channel_.SetAsync(true); | 
| 105 rtc::scoped_refptr<rtc::RTCCertificate> local_cert = | 106 rtc::scoped_refptr<rtc::RTCCertificate> local_cert = | 
| 106 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( | 107 rtc::RTCCertificate::Create(rtc::scoped_ptr<rtc::SSLIdentity>( | 
| 107 rtc::SSLIdentity::Generate(name_, rtc::KT_DEFAULT))); | 108 rtc::SSLIdentity::Generate(name_, rtc::KT_DEFAULT))); | 
| 108 quic_channel_.SetLocalCertificate(local_cert); | 109 quic_channel_.SetLocalCertificate(local_cert); | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 FailableTransportChannel* ice_channel() { return &ice_channel_; } | 198 FailableTransportChannel* ice_channel() { return &ice_channel_; } | 
| 198 | 199 | 
| 199 QuicTransportChannel* quic_channel() { return &quic_channel_; } | 200 QuicTransportChannel* quic_channel() { return &quic_channel_; } | 
| 200 | 201 | 
| 201 rtc::scoped_ptr<rtc::SSLFingerprint>& local_fingerprint() { | 202 rtc::scoped_ptr<rtc::SSLFingerprint>& local_fingerprint() { | 
| 202 return local_fingerprint_; | 203 return local_fingerprint_; | 
| 203 } | 204 } | 
| 204 | 205 | 
| 205 ReliableQuicStream* incoming_quic_stream() { return incoming_quic_stream_; } | 206 ReliableQuicStream* incoming_quic_stream() { return incoming_quic_stream_; } | 
| 206 | 207 | 
| 208 size_t num_incoming_quic_streams() const { | |
| 209 return num_incoming_quic_streams_; | |
| 
pthatcher1
2016/04/29 20:15:46
I'd prefer incoming_stream_count() and incoming_st
 
mikescarlett
2016/04/29 23:29:50
Done.
 | |
| 210 } | |
| 211 | |
| 207 bool signal_closed_emitted() const { return signal_closed_emitted_; } | 212 bool signal_closed_emitted() const { return signal_closed_emitted_; } | 
| 208 | 213 | 
| 209 private: | 214 private: | 
| 210 // QuicTransportChannel callbacks. | 215 // QuicTransportChannel callbacks. | 
| 211 void OnTransportChannelReadPacket(TransportChannel* channel, | 216 void OnTransportChannelReadPacket(TransportChannel* channel, | 
| 212 const char* data, | 217 const char* data, | 
| 213 size_t size, | 218 size_t size, | 
| 214 const rtc::PacketTime& packet_time, | 219 const rtc::PacketTime& packet_time, | 
| 215 int flags) { | 220 int flags) { | 
| 216 bytes_received_ += size; | 221 bytes_received_ += size; | 
| 217 // Only SRTP packets should have the bypass flag set. | 222 // Only SRTP packets should have the bypass flag set. | 
| 218 int expected_flags = IsRtpLeadByte(data[0]) ? cricket::PF_SRTP_BYPASS : 0; | 223 int expected_flags = IsRtpLeadByte(data[0]) ? cricket::PF_SRTP_BYPASS : 0; | 
| 219 ASSERT_EQ(expected_flags, flags); | 224 ASSERT_EQ(expected_flags, flags); | 
| 220 } | 225 } | 
| 221 void OnIncomingStream(ReliableQuicStream* stream) { | 226 void OnIncomingStream(ReliableQuicStream* stream) { | 
| 222 incoming_quic_stream_ = stream; | 227 incoming_quic_stream_ = stream; | 
| 228 ++num_incoming_quic_streams_; | |
| 223 } | 229 } | 
| 224 void OnClosed() { signal_closed_emitted_ = true; } | 230 void OnClosed() { signal_closed_emitted_ = true; } | 
| 225 | 231 | 
| 226 std::string name_; // Channel name. | 232 std::string name_; // Channel name. | 
| 227 size_t bytes_sent_; // Bytes sent by QUIC channel. | 233 size_t bytes_sent_; // Bytes sent by QUIC channel. | 
| 228 size_t bytes_received_; // Bytes received by QUIC channel. | 234 size_t bytes_received_; // Bytes received by QUIC channel. | 
| 229 FailableTransportChannel ice_channel_; // Simulates an ICE channel. | 235 FailableTransportChannel ice_channel_; // Simulates an ICE channel. | 
| 230 QuicTransportChannel quic_channel_; // QUIC channel to test. | 236 QuicTransportChannel quic_channel_; // QUIC channel to test. | 
| 231 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint_; | 237 rtc::scoped_ptr<rtc::SSLFingerprint> local_fingerprint_; | 
| 232 ReliableQuicStream* incoming_quic_stream_ = nullptr; | 238 ReliableQuicStream* incoming_quic_stream_ = nullptr; | 
| 239 size_t num_incoming_quic_streams_; | |
| 233 bool signal_closed_emitted_ = false; | 240 bool signal_closed_emitted_ = false; | 
| 234 }; | 241 }; | 
| 235 | 242 | 
| 236 class QuicTransportChannelTest : public testing::Test { | 243 class QuicTransportChannelTest : public testing::Test { | 
| 237 public: | 244 public: | 
| 238 QuicTransportChannelTest() : peer1_("P1"), peer2_("P2") {} | 245 QuicTransportChannelTest() : peer1_("P1"), peer2_("P2") {} | 
| 239 | 246 | 
| 240 // Performs negotiation before QUIC handshake, then connects the fake | 247 // Performs negotiation before QUIC handshake, then connects the fake | 
| 241 // transport channels of each peer. As a side effect, the QUIC channels | 248 // transport channels of each peer. As a side effect, the QUIC channels | 
| 242 // start sending handshake messages. |peer1_| has a client role and |peer2_| | 249 // start sending handshake messages. |peer1_| has a client role and |peer2_| | 
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 Connect(); | 514 Connect(); | 
| 508 EXPECT_EQ(nullptr, peer1_.quic_channel()->CreateQuicStream()); | 515 EXPECT_EQ(nullptr, peer1_.quic_channel()->CreateQuicStream()); | 
| 509 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); | 516 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); | 
| 510 ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream(); | 517 ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream(); | 
| 511 ASSERT_NE(nullptr, stream); | 518 ASSERT_NE(nullptr, stream); | 
| 512 stream->Write("Hi", 2); | 519 stream->Write("Hi", 2); | 
| 513 EXPECT_TRUE_WAIT(peer2_.incoming_quic_stream() != nullptr, kTimeoutMs); | 520 EXPECT_TRUE_WAIT(peer2_.incoming_quic_stream() != nullptr, kTimeoutMs); | 
| 514 EXPECT_EQ(stream->id(), peer2_.incoming_quic_stream()->id()); | 521 EXPECT_EQ(stream->id(), peer2_.incoming_quic_stream()->id()); | 
| 515 } | 522 } | 
| 516 | 523 | 
| 524 // Test that if the QuicTransportChannel is unwritable, then all outgoing QUIC | |
| 525 // streams can send data once the QuicTransprotChannel becomes writable again. | |
| 526 TEST_F(QuicTransportChannelTest, OutgoingQuicStreamSendsDataAfterReconnect) { | |
| 527 Connect(); | |
| 528 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); | |
| 529 ReliableQuicStream* stream1 = peer1_.quic_channel()->CreateQuicStream(); | |
| 530 ASSERT_NE(nullptr, stream1); | |
| 531 ReliableQuicStream* stream2 = peer1_.quic_channel()->CreateQuicStream(); | |
| 532 ASSERT_NE(nullptr, stream2); | |
| 533 ReliableQuicStream* stream3 = peer1_.quic_channel()->CreateQuicStream(); | |
| 534 ASSERT_NE(nullptr, stream3); | |
| 535 ReliableQuicStream* stream4 = peer1_.quic_channel()->CreateQuicStream(); | |
| 536 ASSERT_NE(nullptr, stream4); | |
| 
pthatcher1
2016/04/29 20:15:47
Why do we need 4 streams for this?  Isn't 1 or 2 e
 
mikescarlett
2016/04/29 23:29:50
2 is fine. I agree 4 is redundant but wanted to te
 | |
| 537 | |
| 538 peer1_.ice_channel()->SetWritable(false); | |
| 539 stream1->Write("First", 5); | |
| 540 EXPECT_EQ(5u, stream1->queued_data_bytes()); | |
| 541 stream2->Write("Second", 6); | |
| 542 EXPECT_EQ(6u, stream2->queued_data_bytes()); | |
| 543 stream3->Write("Third", 5); | |
| 544 EXPECT_EQ(5u, stream3->queued_data_bytes()); | |
| 545 stream4->Write("Fourth", 6); | |
| 546 EXPECT_EQ(6u, stream4->queued_data_bytes()); | |
| 547 EXPECT_EQ(0u, peer2_.num_incoming_quic_streams()); | |
| 548 | |
| 549 peer1_.ice_channel()->SetWritable(true); | |
| 550 EXPECT_EQ_WAIT(0u, stream1->queued_data_bytes(), kTimeoutMs); | |
| 551 EXPECT_EQ_WAIT(0u, stream2->queued_data_bytes(), kTimeoutMs); | |
| 552 EXPECT_EQ_WAIT(0u, stream3->queued_data_bytes(), kTimeoutMs); | |
| 553 EXPECT_EQ_WAIT(0u, stream4->queued_data_bytes(), kTimeoutMs); | |
| 554 EXPECT_EQ_WAIT(4u, peer2_.num_incoming_quic_streams(), kTimeoutMs); | |
| 555 } | |
| 556 | |
| 517 // Test that SignalClosed is emitted when the QuicConnection closes. | 557 // Test that SignalClosed is emitted when the QuicConnection closes. | 
| 518 TEST_F(QuicTransportChannelTest, SignalClosedEmitted) { | 558 TEST_F(QuicTransportChannelTest, SignalClosedEmitted) { | 
| 519 Connect(); | 559 Connect(); | 
| 520 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); | 560 ASSERT_TRUE_WAIT(quic_connected(), kTimeoutMs); | 
| 521 ASSERT_FALSE(peer1_.signal_closed_emitted()); | 561 ASSERT_FALSE(peer1_.signal_closed_emitted()); | 
| 522 ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream(); | 562 ReliableQuicStream* stream = peer1_.quic_channel()->CreateQuicStream(); | 
| 523 ASSERT_NE(nullptr, stream); | 563 ASSERT_NE(nullptr, stream); | 
| 524 stream->CloseConnectionWithDetails(net::QuicErrorCode::QUIC_NO_ERROR, | 564 stream->CloseConnectionWithDetails(net::QuicErrorCode::QUIC_NO_ERROR, | 
| 525 "Closing QUIC for testing"); | 565 "Closing QUIC for testing"); | 
| 526 EXPECT_TRUE(peer1_.signal_closed_emitted()); | 566 EXPECT_TRUE(peer1_.signal_closed_emitted()); | 
| 527 EXPECT_TRUE_WAIT(peer2_.signal_closed_emitted(), kTimeoutMs); | 567 EXPECT_TRUE_WAIT(peer2_.signal_closed_emitted(), kTimeoutMs); | 
| 528 } | 568 } | 
| OLD | NEW |