| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/tools/quic/quic_dispatcher.h" | 5 #include "net/tools/quic/quic_dispatcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/strings/string_piece.h" | 9 #include "base/strings/string_piece.h" |
| 10 #include "net/quic/crypto/crypto_handshake.h" | 10 #include "net/quic/crypto/crypto_handshake.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 class TestDispatcher : public QuicDispatcher { | 42 class TestDispatcher : public QuicDispatcher { |
| 43 public: | 43 public: |
| 44 explicit TestDispatcher(const QuicConfig& config, | 44 explicit TestDispatcher(const QuicConfig& config, |
| 45 const QuicCryptoServerConfig& crypto_config, | 45 const QuicCryptoServerConfig& crypto_config, |
| 46 EpollServer* eps) | 46 EpollServer* eps) |
| 47 : QuicDispatcher(config, | 47 : QuicDispatcher(config, |
| 48 crypto_config, | 48 crypto_config, |
| 49 QuicSupportedVersions(), | 49 QuicSupportedVersions(), |
| 50 eps, | 50 eps, |
| 51 kInitialFlowControlWindowForTest) { | 51 kInitialFlowControlWindowForTest) {} |
| 52 } | |
| 53 | 52 |
| 54 MOCK_METHOD3(CreateQuicSession, QuicSession*( | 53 MOCK_METHOD3(CreateQuicSession, |
| 55 QuicConnectionId connection_id, | 54 QuicSession*(QuicConnectionId connection_id, |
| 56 const IPEndPoint& server_address, | 55 const IPEndPoint& server_address, |
| 57 const IPEndPoint& client_address)); | 56 const IPEndPoint& client_address)); |
| 58 using QuicDispatcher::write_blocked_list; | 57 using QuicDispatcher::write_blocked_list; |
| 59 | 58 |
| 60 using QuicDispatcher::current_server_address; | 59 using QuicDispatcher::current_server_address; |
| 61 using QuicDispatcher::current_client_address; | 60 using QuicDispatcher::current_client_address; |
| 62 }; | 61 }; |
| 63 | 62 |
| 64 // A Connection class which unregisters the session from the dispatcher | 63 // A Connection class which unregisters the session from the dispatcher |
| 65 // when sending connection close. | 64 // when sending connection close. |
| 66 // It'd be slightly more realistic to do this from the Session but it would | 65 // It'd be slightly more realistic to do this from the Session but it would |
| 67 // involve a lot more mocking. | 66 // involve a lot more mocking. |
| 68 class MockServerConnection : public MockConnection { | 67 class MockServerConnection : public MockConnection { |
| 69 public: | 68 public: |
| 70 MockServerConnection(QuicConnectionId connection_id, | 69 MockServerConnection(QuicConnectionId connection_id, |
| 71 QuicDispatcher* dispatcher) | 70 QuicDispatcher* dispatcher) |
| 72 : MockConnection(connection_id, true), | 71 : MockConnection(connection_id, true), dispatcher_(dispatcher) {} |
| 73 dispatcher_(dispatcher) {} | |
| 74 | 72 |
| 75 void UnregisterOnConnectionClosed() { | 73 void UnregisterOnConnectionClosed() { |
| 76 LOG(ERROR) << "Unregistering " << connection_id(); | 74 LOG(ERROR) << "Unregistering " << connection_id(); |
| 77 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); | 75 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); |
| 78 } | 76 } |
| 77 |
| 79 private: | 78 private: |
| 80 QuicDispatcher* dispatcher_; | 79 QuicDispatcher* dispatcher_; |
| 81 }; | 80 }; |
| 82 | 81 |
| 83 QuicSession* CreateSession(QuicDispatcher* dispatcher, | 82 QuicSession* CreateSession(QuicDispatcher* dispatcher, |
| 84 QuicConnectionId connection_id, | 83 QuicConnectionId connection_id, |
| 85 const IPEndPoint& client_address, | 84 const IPEndPoint& client_address, |
| 86 MockSession** session) { | 85 MockSession** session) { |
| 87 MockServerConnection* connection = | 86 MockServerConnection* connection = |
| 88 new MockServerConnection(connection_id, dispatcher); | 87 new MockServerConnection(connection_id, dispatcher); |
| 89 *session = new MockSession(connection); | 88 *session = new MockSession(connection); |
| 90 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( | 89 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault(WithoutArgs( |
| 91 WithoutArgs(Invoke( | 90 Invoke(connection, &MockServerConnection::UnregisterOnConnectionClosed))); |
| 92 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | |
| 93 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), | 91 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), |
| 94 ProcessUdpPacket(_, client_address, _)); | 92 ProcessUdpPacket(_, client_address, _)); |
| 95 | 93 |
| 96 return *session; | 94 return *session; |
| 97 } | 95 } |
| 98 | 96 |
| 99 class QuicDispatcherTest : public ::testing::Test { | 97 class QuicDispatcherTest : public ::testing::Test { |
| 100 public: | 98 public: |
| 101 QuicDispatcherTest() | 99 QuicDispatcherTest() |
| 102 : crypto_config_(QuicCryptoServerConfig::TESTING, | 100 : crypto_config_(QuicCryptoServerConfig::TESTING, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 string data_; | 140 string data_; |
| 143 }; | 141 }; |
| 144 | 142 |
| 145 TEST_F(QuicDispatcherTest, ProcessPackets) { | 143 TEST_F(QuicDispatcherTest, ProcessPackets) { |
| 146 IPEndPoint client_address(net::test::Loopback4(), 1); | 144 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 147 IPAddressNumber any4; | 145 IPAddressNumber any4; |
| 148 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); | 146 CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); |
| 149 server_address_ = IPEndPoint(any4, 5); | 147 server_address_ = IPEndPoint(any4, 5); |
| 150 | 148 |
| 151 EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address)) | 149 EXPECT_CALL(dispatcher_, CreateQuicSession(1, _, client_address)) |
| 152 .WillOnce(testing::Return(CreateSession( | 150 .WillOnce(testing::Return( |
| 153 &dispatcher_, 1, client_address, &session1_))); | 151 CreateSession(&dispatcher_, 1, client_address, &session1_))); |
| 154 ProcessPacket(client_address, 1, true, "foo"); | 152 ProcessPacket(client_address, 1, true, "foo"); |
| 155 EXPECT_EQ(client_address, dispatcher_.current_client_address()); | 153 EXPECT_EQ(client_address, dispatcher_.current_client_address()); |
| 156 EXPECT_EQ(server_address_, dispatcher_.current_server_address()); | 154 EXPECT_EQ(server_address_, dispatcher_.current_server_address()); |
| 157 | 155 |
| 158 | |
| 159 EXPECT_CALL(dispatcher_, CreateQuicSession(2, _, client_address)) | 156 EXPECT_CALL(dispatcher_, CreateQuicSession(2, _, client_address)) |
| 160 .WillOnce(testing::Return(CreateSession( | 157 .WillOnce(testing::Return( |
| 161 &dispatcher_, 2, client_address, &session2_))); | 158 CreateSession(&dispatcher_, 2, client_address, &session2_))); |
| 162 ProcessPacket(client_address, 2, true, "bar"); | 159 ProcessPacket(client_address, 2, true, "bar"); |
| 163 | 160 |
| 164 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), | 161 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), |
| 165 ProcessUdpPacket(_, _, _)).Times(1). | 162 ProcessUdpPacket(_, _, _)) |
| 166 WillOnce(testing::WithArgs<2>(Invoke( | 163 .Times(1) |
| 167 this, &QuicDispatcherTest::ValidatePacket))); | 164 .WillOnce(testing::WithArgs<2>( |
| 165 Invoke(this, &QuicDispatcherTest::ValidatePacket))); |
| 168 ProcessPacket(client_address, 1, false, "eep"); | 166 ProcessPacket(client_address, 1, false, "eep"); |
| 169 } | 167 } |
| 170 | 168 |
| 171 TEST_F(QuicDispatcherTest, Shutdown) { | 169 TEST_F(QuicDispatcherTest, Shutdown) { |
| 172 IPEndPoint client_address(net::test::Loopback4(), 1); | 170 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 173 | 171 |
| 174 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) | 172 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) |
| 175 .WillOnce(testing::Return(CreateSession( | 173 .WillOnce(testing::Return( |
| 176 &dispatcher_, 1, client_address, &session1_))); | 174 CreateSession(&dispatcher_, 1, client_address, &session1_))); |
| 177 | 175 |
| 178 ProcessPacket(client_address, 1, true, "foo"); | 176 ProcessPacket(client_address, 1, true, "foo"); |
| 179 | 177 |
| 180 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), | 178 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), |
| 181 SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 179 SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 182 | 180 |
| 183 dispatcher_.Shutdown(); | 181 dispatcher_.Shutdown(); |
| 184 } | 182 } |
| 185 | 183 |
| 186 class MockTimeWaitListManager : public QuicTimeWaitListManager { | 184 class MockTimeWaitListManager : public QuicTimeWaitListManager { |
| 187 public: | 185 public: |
| 188 MockTimeWaitListManager(QuicPacketWriter* writer, | 186 MockTimeWaitListManager(QuicPacketWriter* writer, |
| 189 QuicServerSessionVisitor* visitor, | 187 QuicServerSessionVisitor* visitor, |
| 190 EpollServer* eps) | 188 EpollServer* eps) |
| 191 : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { | 189 : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { |
| 192 } | 190 } |
| 193 | 191 |
| 194 MOCK_METHOD5(ProcessPacket, void(const IPEndPoint& server_address, | 192 MOCK_METHOD5(ProcessPacket, |
| 195 const IPEndPoint& client_address, | 193 void(const IPEndPoint& server_address, |
| 196 QuicConnectionId connection_id, | 194 const IPEndPoint& client_address, |
| 197 QuicPacketSequenceNumber sequence_number, | 195 QuicConnectionId connection_id, |
| 198 const QuicEncryptedPacket& packet)); | 196 QuicPacketSequenceNumber sequence_number, |
| 197 const QuicEncryptedPacket& packet)); |
| 199 }; | 198 }; |
| 200 | 199 |
| 201 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 200 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
| 202 MockTimeWaitListManager* time_wait_list_manager = | 201 MockTimeWaitListManager* time_wait_list_manager = new MockTimeWaitListManager( |
| 203 new MockTimeWaitListManager( | 202 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 204 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); | |
| 205 // dispatcher takes the ownership of time_wait_list_manager. | 203 // dispatcher takes the ownership of time_wait_list_manager. |
| 206 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 204 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 207 time_wait_list_manager); | 205 time_wait_list_manager); |
| 208 // Create a new session. | 206 // Create a new session. |
| 209 IPEndPoint client_address(net::test::Loopback4(), 1); | 207 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 210 QuicConnectionId connection_id = 1; | 208 QuicConnectionId connection_id = 1; |
| 211 EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, client_address)) | 209 EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, client_address)) |
| 212 .WillOnce(testing::Return(CreateSession( | 210 .WillOnce(testing::Return(CreateSession( |
| 213 &dispatcher_, connection_id, client_address, &session1_))); | 211 &dispatcher_, connection_id, client_address, &session1_))); |
| 214 ProcessPacket(client_address, connection_id, true, "foo"); | 212 ProcessPacket(client_address, connection_id, true, "foo"); |
| 215 | 213 |
| 216 // Close the connection by sending public reset packet. | 214 // Close the connection by sending public reset packet. |
| 217 QuicPublicResetPacket packet; | 215 QuicPublicResetPacket packet; |
| 218 packet.public_header.connection_id = connection_id; | 216 packet.public_header.connection_id = connection_id; |
| 219 packet.public_header.reset_flag = true; | 217 packet.public_header.reset_flag = true; |
| 220 packet.public_header.version_flag = false; | 218 packet.public_header.version_flag = false; |
| 221 packet.rejected_sequence_number = 19191; | 219 packet.rejected_sequence_number = 19191; |
| 222 packet.nonce_proof = 132232; | 220 packet.nonce_proof = 132232; |
| 223 scoped_ptr<QuicEncryptedPacket> encrypted( | 221 scoped_ptr<QuicEncryptedPacket> encrypted( |
| 224 QuicFramer::BuildPublicResetPacket(packet)); | 222 QuicFramer::BuildPublicResetPacket(packet)); |
| 225 EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)).Times(1) | 223 EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)) |
| 224 .Times(1) |
| 226 .WillOnce(WithoutArgs(Invoke( | 225 .WillOnce(WithoutArgs(Invoke( |
| 227 reinterpret_cast<MockServerConnection*>(session1_->connection()), | 226 reinterpret_cast<MockServerConnection*>(session1_->connection()), |
| 228 &MockServerConnection::UnregisterOnConnectionClosed))); | 227 &MockServerConnection::UnregisterOnConnectionClosed))); |
| 229 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), | 228 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), |
| 230 ProcessUdpPacket(_, _, _)) | 229 ProcessUdpPacket(_, _, _)) |
| 231 .WillOnce(Invoke( | 230 .WillOnce( |
| 232 reinterpret_cast<MockConnection*>(session1_->connection()), | 231 Invoke(reinterpret_cast<MockConnection*>(session1_->connection()), |
| 233 &MockConnection::ReallyProcessUdpPacket)); | 232 &MockConnection::ReallyProcessUdpPacket)); |
| 234 dispatcher_.ProcessPacket(IPEndPoint(), client_address, *encrypted); | 233 dispatcher_.ProcessPacket(IPEndPoint(), client_address, *encrypted); |
| 235 EXPECT_TRUE(time_wait_list_manager->IsConnectionIdInTimeWait(connection_id)); | 234 EXPECT_TRUE(time_wait_list_manager->IsConnectionIdInTimeWait(connection_id)); |
| 236 | 235 |
| 237 // Dispatcher forwards subsequent packets for this connection_id to the time | 236 // Dispatcher forwards subsequent packets for this connection_id to the time |
| 238 // wait list manager. | 237 // wait list manager. |
| 239 EXPECT_CALL(*time_wait_list_manager, | 238 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, connection_id, _, _)) |
| 240 ProcessPacket(_, _, connection_id, _, _)).Times(1); | 239 .Times(1); |
| 241 ProcessPacket(client_address, connection_id, true, "foo"); | 240 ProcessPacket(client_address, connection_id, true, "foo"); |
| 242 } | 241 } |
| 243 | 242 |
| 244 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { | 243 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { |
| 245 MockTimeWaitListManager* time_wait_list_manager = | 244 MockTimeWaitListManager* time_wait_list_manager = new MockTimeWaitListManager( |
| 246 new MockTimeWaitListManager( | 245 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 247 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); | |
| 248 // dispatcher takes the ownership of time_wait_list_manager. | 246 // dispatcher takes the ownership of time_wait_list_manager. |
| 249 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 247 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 250 time_wait_list_manager); | 248 time_wait_list_manager); |
| 251 | 249 |
| 252 IPEndPoint client_address(net::test::Loopback4(), 1); | 250 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 253 QuicConnectionId connection_id = 1; | 251 QuicConnectionId connection_id = 1; |
| 254 // Dispatcher forwards all packets for this connection_id to the time wait | 252 // Dispatcher forwards all packets for this connection_id to the time wait |
| 255 // list manager. | 253 // list manager. |
| 256 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); | 254 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); |
| 257 EXPECT_CALL(*time_wait_list_manager, | 255 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, connection_id, _, _)) |
| 258 ProcessPacket(_, _, connection_id, _, _)).Times(1); | 256 .Times(1); |
| 259 string data = "foo"; | 257 string data = "foo"; |
| 260 ProcessPacket(client_address, connection_id, false, "foo"); | 258 ProcessPacket(client_address, connection_id, false, "foo"); |
| 261 } | 259 } |
| 262 | 260 |
| 263 TEST(QuicDispatcherFlowControlTest, NoNewVersion17ConnectionsIfFlagDisabled) { | 261 TEST(QuicDispatcherFlowControlTest, NoNewVersion17ConnectionsIfFlagDisabled) { |
| 264 // If FLAGS_enable_quic_stream_flow_control_2 is disabled | 262 // If FLAGS_enable_quic_stream_flow_control_2 is disabled |
| 265 // then the dispatcher should stop creating connections that support | 263 // then the dispatcher should stop creating connections that support |
| 266 // QUIC_VERSION_17 (existing connections will stay alive). | 264 // QUIC_VERSION_17 (existing connections will stay alive). |
| 267 // TODO(rjshade): Remove once | 265 // TODO(rjshade): Remove once |
| 268 // FLAGS_enable_quic_stream_flow_control_2 is removed. | 266 // FLAGS_enable_quic_stream_flow_control_2 is removed. |
| 269 | 267 |
| 270 EpollServer eps; | 268 EpollServer eps; |
| 271 QuicConfig config; | 269 QuicConfig config; |
| 272 QuicCryptoServerConfig server_config(QuicCryptoServerConfig::TESTING, | 270 QuicCryptoServerConfig server_config(QuicCryptoServerConfig::TESTING, |
| 273 QuicRandom::GetInstance()); | 271 QuicRandom::GetInstance()); |
| 274 IPEndPoint client(net::test::Loopback4(), 1); | 272 IPEndPoint client(net::test::Loopback4(), 1); |
| 275 IPEndPoint server(net::test::Loopback4(), 1); | 273 IPEndPoint server(net::test::Loopback4(), 1); |
| 276 QuicConnectionId kCID = 1234; | 274 QuicConnectionId kCID = 1234; |
| 277 | 275 |
| 278 QuicVersion kTestQuicVersions[] = {QUIC_VERSION_17, | 276 QuicVersion kTestQuicVersions[] = {QUIC_VERSION_17, QUIC_VERSION_16, |
| 279 QUIC_VERSION_16, | |
| 280 QUIC_VERSION_15}; | 277 QUIC_VERSION_15}; |
| 281 QuicVersionVector kTestVersions; | 278 QuicVersionVector kTestVersions; |
| 282 for (size_t i = 0; i < arraysize(kTestQuicVersions); ++i) { | 279 for (size_t i = 0; i < arraysize(kTestQuicVersions); ++i) { |
| 283 kTestVersions.push_back(kTestQuicVersions[i]); | 280 kTestVersions.push_back(kTestQuicVersions[i]); |
| 284 } | 281 } |
| 285 | 282 |
| 286 QuicDispatcher dispatcher(config, server_config, kTestVersions, &eps, | 283 QuicDispatcher dispatcher(config, |
| 284 server_config, |
| 285 kTestVersions, |
| 286 &eps, |
| 287 kInitialFlowControlWindowForTest); | 287 kInitialFlowControlWindowForTest); |
| 288 dispatcher.Initialize(0); | 288 dispatcher.Initialize(0); |
| 289 | 289 |
| 290 // When flag is enabled, new connections should support QUIC_VERSION_17. | 290 // When flag is enabled, new connections should support QUIC_VERSION_17. |
| 291 FLAGS_enable_quic_stream_flow_control_2 = true; | 291 FLAGS_enable_quic_stream_flow_control_2 = true; |
| 292 scoped_ptr<QuicConnection> connection_1( | 292 scoped_ptr<QuicConnection> connection_1( |
| 293 QuicDispatcherPeer::CreateQuicConnection( | 293 QuicDispatcherPeer::CreateQuicConnection( |
| 294 &dispatcher, kCID, client, server, kInitialFlowControlWindowForTest)); | 294 &dispatcher, kCID, client, server, kInitialFlowControlWindowForTest)); |
| 295 EXPECT_EQ(QUIC_VERSION_17, connection_1->version()); | 295 EXPECT_EQ(QUIC_VERSION_17, connection_1->version()); |
| 296 | 296 |
| 297 | |
| 298 // When flag is disabled, new connections should not support QUIC_VERSION_17. | 297 // When flag is disabled, new connections should not support QUIC_VERSION_17. |
| 299 FLAGS_enable_quic_stream_flow_control_2 = false; | 298 FLAGS_enable_quic_stream_flow_control_2 = false; |
| 300 scoped_ptr<QuicConnection> connection_2( | 299 scoped_ptr<QuicConnection> connection_2( |
| 301 QuicDispatcherPeer::CreateQuicConnection( | 300 QuicDispatcherPeer::CreateQuicConnection( |
| 302 &dispatcher, kCID, client, server, kInitialFlowControlWindowForTest)); | 301 &dispatcher, kCID, client, server, kInitialFlowControlWindowForTest)); |
| 303 EXPECT_EQ(QUIC_VERSION_16, connection_2->version()); | 302 EXPECT_EQ(QUIC_VERSION_16, connection_2->version()); |
| 304 } | 303 } |
| 305 | 304 |
| 306 class BlockingWriter : public QuicPacketWriterWrapper { | 305 class BlockingWriter : public QuicPacketWriterWrapper { |
| 307 public: | 306 public: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 328 | 327 |
| 329 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { | 328 class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { |
| 330 public: | 329 public: |
| 331 virtual void SetUp() { | 330 virtual void SetUp() { |
| 332 writer_ = new BlockingWriter; | 331 writer_ = new BlockingWriter; |
| 333 QuicDispatcherPeer::UseWriter(&dispatcher_, writer_); | 332 QuicDispatcherPeer::UseWriter(&dispatcher_, writer_); |
| 334 | 333 |
| 335 IPEndPoint client_address(net::test::Loopback4(), 1); | 334 IPEndPoint client_address(net::test::Loopback4(), 1); |
| 336 | 335 |
| 337 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) | 336 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) |
| 338 .WillOnce(testing::Return(CreateSession( | 337 .WillOnce(testing::Return( |
| 339 &dispatcher_, 1, client_address, &session1_))); | 338 CreateSession(&dispatcher_, 1, client_address, &session1_))); |
| 340 ProcessPacket(client_address, 1, true, "foo"); | 339 ProcessPacket(client_address, 1, true, "foo"); |
| 341 | 340 |
| 342 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) | 341 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, client_address)) |
| 343 .WillOnce(testing::Return(CreateSession( | 342 .WillOnce(testing::Return( |
| 344 &dispatcher_, 2, client_address, &session2_))); | 343 CreateSession(&dispatcher_, 2, client_address, &session2_))); |
| 345 ProcessPacket(client_address, 2, true, "bar"); | 344 ProcessPacket(client_address, 2, true, "bar"); |
| 346 | 345 |
| 347 blocked_list_ = dispatcher_.write_blocked_list(); | 346 blocked_list_ = dispatcher_.write_blocked_list(); |
| 348 } | 347 } |
| 349 | 348 |
| 350 virtual void TearDown() { | 349 virtual void TearDown() { |
| 351 EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 350 EXPECT_CALL(*connection1(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 352 EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); | 351 EXPECT_CALL(*connection2(), SendConnectionClose(QUIC_PEER_GOING_AWAY)); |
| 353 dispatcher_.Shutdown(); | 352 dispatcher_.Shutdown(); |
| 354 } | 353 } |
| 355 | 354 |
| 356 void SetBlocked() { | 355 void SetBlocked() { writer_->write_blocked_ = true; } |
| 357 writer_->write_blocked_ = true; | |
| 358 } | |
| 359 | 356 |
| 360 void BlockConnection2() { | 357 void BlockConnection2() { |
| 361 writer_->write_blocked_ = true; | 358 writer_->write_blocked_ = true; |
| 362 dispatcher_.OnWriteBlocked(connection2()); | 359 dispatcher_.OnWriteBlocked(connection2()); |
| 363 } | 360 } |
| 364 | 361 |
| 365 protected: | 362 protected: |
| 366 BlockingWriter* writer_; | 363 BlockingWriter* writer_; |
| 367 QuicDispatcher::WriteBlockedList* blocked_list_; | 364 QuicDispatcher::WriteBlockedList* blocked_list_; |
| 368 }; | 365 }; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); | 440 EXPECT_CALL(*connection1(), OnCanWrite()).Times(1); |
| 444 dispatcher_.OnCanWrite(); | 441 dispatcher_.OnCanWrite(); |
| 445 } | 442 } |
| 446 | 443 |
| 447 TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) { | 444 TEST_F(QuicDispatcherWriteBlockedListTest, OnCanWriteHandleBlock) { |
| 448 // Finally make sure if we write block on a write call, we stop calling. | 445 // Finally make sure if we write block on a write call, we stop calling. |
| 449 InSequence s; | 446 InSequence s; |
| 450 SetBlocked(); | 447 SetBlocked(); |
| 451 dispatcher_.OnWriteBlocked(connection1()); | 448 dispatcher_.OnWriteBlocked(connection1()); |
| 452 dispatcher_.OnWriteBlocked(connection2()); | 449 dispatcher_.OnWriteBlocked(connection2()); |
| 453 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( | 450 EXPECT_CALL(*connection1(), OnCanWrite()) |
| 454 Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); | 451 .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); |
| 455 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 452 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 456 dispatcher_.OnCanWrite(); | 453 dispatcher_.OnCanWrite(); |
| 457 | 454 |
| 458 // And we'll resume where we left off when we get another call. | 455 // And we'll resume where we left off when we get another call. |
| 459 EXPECT_CALL(*connection2(), OnCanWrite()); | 456 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 460 dispatcher_.OnCanWrite(); | 457 dispatcher_.OnCanWrite(); |
| 461 } | 458 } |
| 462 | 459 |
| 463 TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) { | 460 TEST_F(QuicDispatcherWriteBlockedListTest, LimitedWrites) { |
| 464 // Make sure we call both writers. The first will register for more writing | 461 // Make sure we call both writers. The first will register for more writing |
| (...skipping 13 matching lines...) Expand all Loading... |
| 478 dispatcher_.OnCanWrite(); | 475 dispatcher_.OnCanWrite(); |
| 479 EXPECT_FALSE(dispatcher_.HasPendingWrites()); | 476 EXPECT_FALSE(dispatcher_.HasPendingWrites()); |
| 480 } | 477 } |
| 481 | 478 |
| 482 TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) { | 479 TEST_F(QuicDispatcherWriteBlockedListTest, TestWriteLimits) { |
| 483 // Finally make sure if we write block on a write call, we stop calling. | 480 // Finally make sure if we write block on a write call, we stop calling. |
| 484 InSequence s; | 481 InSequence s; |
| 485 SetBlocked(); | 482 SetBlocked(); |
| 486 dispatcher_.OnWriteBlocked(connection1()); | 483 dispatcher_.OnWriteBlocked(connection1()); |
| 487 dispatcher_.OnWriteBlocked(connection2()); | 484 dispatcher_.OnWriteBlocked(connection2()); |
| 488 EXPECT_CALL(*connection1(), OnCanWrite()).WillOnce( | 485 EXPECT_CALL(*connection1(), OnCanWrite()) |
| 489 Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); | 486 .WillOnce(Invoke(this, &QuicDispatcherWriteBlockedListTest::SetBlocked)); |
| 490 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); | 487 EXPECT_CALL(*connection2(), OnCanWrite()).Times(0); |
| 491 dispatcher_.OnCanWrite(); | 488 dispatcher_.OnCanWrite(); |
| 492 EXPECT_TRUE(dispatcher_.HasPendingWrites()); | 489 EXPECT_TRUE(dispatcher_.HasPendingWrites()); |
| 493 | 490 |
| 494 // And we'll resume where we left off when we get another call. | 491 // And we'll resume where we left off when we get another call. |
| 495 EXPECT_CALL(*connection2(), OnCanWrite()); | 492 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 496 dispatcher_.OnCanWrite(); | 493 dispatcher_.OnCanWrite(); |
| 497 EXPECT_FALSE(dispatcher_.HasPendingWrites()); | 494 EXPECT_FALSE(dispatcher_.HasPendingWrites()); |
| 498 } | 495 } |
| 499 | 496 |
| 500 } // namespace | 497 } // namespace |
| 501 } // namespace test | 498 } // namespace test |
| 502 } // namespace tools | 499 } // namespace tools |
| 503 } // namespace net | 500 } // namespace net |
| OLD | NEW |