| 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 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 class TestDispatcher : public QuicDispatcher { | 41 class TestDispatcher : public QuicDispatcher { |
| 42 public: | 42 public: |
| 43 explicit TestDispatcher(const QuicConfig& config, | 43 explicit TestDispatcher(const QuicConfig& config, |
| 44 const QuicCryptoServerConfig& crypto_config, | 44 const QuicCryptoServerConfig& crypto_config, |
| 45 EpollServer* eps) | 45 EpollServer* eps) |
| 46 : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), eps) { | 46 : QuicDispatcher(config, crypto_config, QuicSupportedVersions(), eps) { |
| 47 } | 47 } |
| 48 | 48 |
| 49 MOCK_METHOD3(CreateQuicSession, QuicSession*( | 49 MOCK_METHOD3(CreateQuicSession, QuicSession*( |
| 50 QuicGuid guid, | 50 QuicConnectionId connection_id, |
| 51 const IPEndPoint& server_address, | 51 const IPEndPoint& server_address, |
| 52 const IPEndPoint& client_address)); | 52 const IPEndPoint& client_address)); |
| 53 using QuicDispatcher::write_blocked_list; | 53 using QuicDispatcher::write_blocked_list; |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 // A Connection class which unregisters the session from the dispatcher | 56 // A Connection class which unregisters the session from the dispatcher |
| 57 // when sending connection close. | 57 // when sending connection close. |
| 58 // It'd be slightly more realistic to do this from the Session but it would | 58 // It'd be slightly more realistic to do this from the Session but it would |
| 59 // involve a lot more mocking. | 59 // involve a lot more mocking. |
| 60 class MockServerConnection : public MockConnection { | 60 class MockServerConnection : public MockConnection { |
| 61 public: | 61 public: |
| 62 MockServerConnection(QuicGuid guid, | 62 MockServerConnection(QuicConnectionId connection_id, |
| 63 QuicDispatcher* dispatcher) | 63 QuicDispatcher* dispatcher) |
| 64 : MockConnection(guid, true), | 64 : MockConnection(connection_id, true), |
| 65 dispatcher_(dispatcher) {} | 65 dispatcher_(dispatcher) {} |
| 66 | 66 |
| 67 void UnregisterOnConnectionClosed() { | 67 void UnregisterOnConnectionClosed() { |
| 68 LOG(ERROR) << "Unregistering " << guid(); | 68 LOG(ERROR) << "Unregistering " << connection_id(); |
| 69 dispatcher_->OnConnectionClosed(guid(), QUIC_NO_ERROR); | 69 dispatcher_->OnConnectionClosed(connection_id(), QUIC_NO_ERROR); |
| 70 } | 70 } |
| 71 private: | 71 private: |
| 72 QuicDispatcher* dispatcher_; | 72 QuicDispatcher* dispatcher_; |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 QuicSession* CreateSession(QuicDispatcher* dispatcher, | 75 QuicSession* CreateSession(QuicDispatcher* dispatcher, |
| 76 QuicGuid guid, | 76 QuicConnectionId connection_id, |
| 77 const IPEndPoint& addr, | 77 const IPEndPoint& addr, |
| 78 MockSession** session) { | 78 MockSession** session) { |
| 79 MockServerConnection* connection = new MockServerConnection(guid, dispatcher); | 79 MockServerConnection* connection = |
| 80 new MockServerConnection(connection_id, dispatcher); |
| 80 *session = new MockSession(connection); | 81 *session = new MockSession(connection); |
| 81 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( | 82 ON_CALL(*connection, SendConnectionClose(_)).WillByDefault( |
| 82 WithoutArgs(Invoke( | 83 WithoutArgs(Invoke( |
| 83 connection, &MockServerConnection::UnregisterOnConnectionClosed))); | 84 connection, &MockServerConnection::UnregisterOnConnectionClosed))); |
| 84 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), | 85 EXPECT_CALL(*reinterpret_cast<MockConnection*>((*session)->connection()), |
| 85 ProcessUdpPacket(_, addr, _)); | 86 ProcessUdpPacket(_, addr, _)); |
| 86 | 87 |
| 87 return *session; | 88 return *session; |
| 88 } | 89 } |
| 89 | 90 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 102 | 103 |
| 103 MockConnection* connection1() { | 104 MockConnection* connection1() { |
| 104 return reinterpret_cast<MockConnection*>(session1_->connection()); | 105 return reinterpret_cast<MockConnection*>(session1_->connection()); |
| 105 } | 106 } |
| 106 | 107 |
| 107 MockConnection* connection2() { | 108 MockConnection* connection2() { |
| 108 return reinterpret_cast<MockConnection*>(session2_->connection()); | 109 return reinterpret_cast<MockConnection*>(session2_->connection()); |
| 109 } | 110 } |
| 110 | 111 |
| 111 QuicEncryptedPacket* ConstructEncryptedPacket( | 112 QuicEncryptedPacket* ConstructEncryptedPacket( |
| 112 QuicGuid guid, | 113 QuicConnectionId connection_id, |
| 113 bool version_flag, | 114 bool version_flag, |
| 114 bool reset_flag, | 115 bool reset_flag, |
| 115 QuicPacketSequenceNumber sequence_number, | 116 QuicPacketSequenceNumber sequence_number, |
| 116 const string& data) { | 117 const string& data) { |
| 117 QuicPacketHeader header; | 118 QuicPacketHeader header; |
| 118 header.public_header.guid = guid; | 119 header.public_header.connection_id = connection_id; |
| 119 header.public_header.guid_length = PACKET_8BYTE_GUID; | 120 header.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID; |
| 120 header.public_header.version_flag = version_flag; | 121 header.public_header.version_flag = version_flag; |
| 121 header.public_header.reset_flag = reset_flag; | 122 header.public_header.reset_flag = reset_flag; |
| 122 header.public_header.sequence_number_length = PACKET_6BYTE_SEQUENCE_NUMBER; | 123 header.public_header.sequence_number_length = PACKET_6BYTE_SEQUENCE_NUMBER; |
| 123 header.packet_sequence_number = sequence_number; | 124 header.packet_sequence_number = sequence_number; |
| 124 header.entropy_flag = false; | 125 header.entropy_flag = false; |
| 125 header.entropy_hash = 0; | 126 header.entropy_hash = 0; |
| 126 header.fec_flag = false; | 127 header.fec_flag = false; |
| 127 header.is_in_fec_group = NOT_IN_FEC_GROUP; | 128 header.is_in_fec_group = NOT_IN_FEC_GROUP; |
| 128 header.fec_group = 0; | 129 header.fec_group = 0; |
| 129 QuicStreamFrame stream_frame(1, false, 0, MakeIOVector(data)); | 130 QuicStreamFrame stream_frame(1, false, 0, MakeIOVector(data)); |
| 130 QuicFrame frame(&stream_frame); | 131 QuicFrame frame(&stream_frame); |
| 131 QuicFrames frames; | 132 QuicFrames frames; |
| 132 frames.push_back(frame); | 133 frames.push_back(frame); |
| 133 QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), false); | 134 QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), false); |
| 134 scoped_ptr<QuicPacket> packet( | 135 scoped_ptr<QuicPacket> packet( |
| 135 framer.BuildUnsizedDataPacket(header, frames).packet); | 136 framer.BuildUnsizedDataPacket(header, frames).packet); |
| 136 EXPECT_TRUE(packet != NULL); | 137 EXPECT_TRUE(packet != NULL); |
| 137 QuicEncryptedPacket* encrypted = framer.EncryptPacket(ENCRYPTION_NONE, | 138 QuicEncryptedPacket* encrypted = framer.EncryptPacket(ENCRYPTION_NONE, |
| 138 sequence_number, | 139 sequence_number, |
| 139 *packet); | 140 *packet); |
| 140 EXPECT_TRUE(encrypted != NULL); | 141 EXPECT_TRUE(encrypted != NULL); |
| 141 data_ = string(encrypted->data(), encrypted->length()); | 142 data_ = string(encrypted->data(), encrypted->length()); |
| 142 return encrypted; | 143 return encrypted; |
| 143 } | 144 } |
| 144 | 145 |
| 145 void ProcessPacket(IPEndPoint addr, | 146 void ProcessPacket(IPEndPoint addr, |
| 146 QuicGuid guid, | 147 QuicConnectionId connection_id, |
| 147 bool has_version_flag, | 148 bool has_version_flag, |
| 148 const string& data) { | 149 const string& data) { |
| 149 scoped_ptr<QuicEncryptedPacket> packet( | 150 scoped_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket( |
| 150 ConstructEncryptedPacket(guid, has_version_flag, false, 1, data)); | 151 connection_id, has_version_flag, false, 1, data)); |
| 151 dispatcher_.ProcessPacket(IPEndPoint(), addr, *packet.get()); | 152 dispatcher_.ProcessPacket(IPEndPoint(), addr, *packet.get()); |
| 152 } | 153 } |
| 153 | 154 |
| 154 void ValidatePacket(const QuicEncryptedPacket& packet) { | 155 void ValidatePacket(const QuicEncryptedPacket& packet) { |
| 155 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); | 156 EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); |
| 156 EXPECT_EQ(data_, packet.AsStringPiece()); | 157 EXPECT_EQ(data_, packet.AsStringPiece()); |
| 157 } | 158 } |
| 158 | 159 |
| 159 EpollServer eps_; | 160 EpollServer eps_; |
| 160 QuicConfig config_; | 161 QuicConfig config_; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 class MockTimeWaitListManager : public QuicTimeWaitListManager { | 204 class MockTimeWaitListManager : public QuicTimeWaitListManager { |
| 204 public: | 205 public: |
| 205 MockTimeWaitListManager(QuicPacketWriter* writer, | 206 MockTimeWaitListManager(QuicPacketWriter* writer, |
| 206 QuicServerSessionVisitor* visitor, | 207 QuicServerSessionVisitor* visitor, |
| 207 EpollServer* eps) | 208 EpollServer* eps) |
| 208 : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { | 209 : QuicTimeWaitListManager(writer, visitor, eps, QuicSupportedVersions()) { |
| 209 } | 210 } |
| 210 | 211 |
| 211 MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address, | 212 MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address, |
| 212 const IPEndPoint& client_address, | 213 const IPEndPoint& client_address, |
| 213 QuicGuid guid, | 214 QuicConnectionId connection_id, |
| 214 QuicPacketSequenceNumber sequence_number)); | 215 QuicPacketSequenceNumber sequence_number)); |
| 215 }; | 216 }; |
| 216 | 217 |
| 217 TEST_F(QuicDispatcherTest, TimeWaitListManager) { | 218 TEST_F(QuicDispatcherTest, TimeWaitListManager) { |
| 218 MockTimeWaitListManager* time_wait_list_manager = | 219 MockTimeWaitListManager* time_wait_list_manager = |
| 219 new MockTimeWaitListManager( | 220 new MockTimeWaitListManager( |
| 220 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); | 221 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 221 // dispatcher takes the ownership of time_wait_list_manager. | 222 // dispatcher takes the ownership of time_wait_list_manager. |
| 222 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 223 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 223 time_wait_list_manager); | 224 time_wait_list_manager); |
| 224 // Create a new session. | 225 // Create a new session. |
| 225 IPEndPoint addr(net::test::Loopback4(), 1); | 226 IPEndPoint addr(net::test::Loopback4(), 1); |
| 226 QuicGuid guid = 1; | 227 QuicConnectionId connection_id = 1; |
| 227 EXPECT_CALL(dispatcher_, CreateQuicSession(guid, _, addr)) | 228 EXPECT_CALL(dispatcher_, CreateQuicSession(connection_id, _, addr)) |
| 228 .WillOnce(testing::Return(CreateSession( | 229 .WillOnce(testing::Return(CreateSession( |
| 229 &dispatcher_, guid, addr, &session1_))); | 230 &dispatcher_, connection_id, addr, &session1_))); |
| 230 ProcessPacket(addr, guid, true, "foo"); | 231 ProcessPacket(addr, connection_id, true, "foo"); |
| 231 | 232 |
| 232 // Close the connection by sending public reset packet. | 233 // Close the connection by sending public reset packet. |
| 233 QuicPublicResetPacket packet; | 234 QuicPublicResetPacket packet; |
| 234 packet.public_header.guid = guid; | 235 packet.public_header.connection_id = connection_id; |
| 235 packet.public_header.reset_flag = true; | 236 packet.public_header.reset_flag = true; |
| 236 packet.public_header.version_flag = false; | 237 packet.public_header.version_flag = false; |
| 237 packet.rejected_sequence_number = 19191; | 238 packet.rejected_sequence_number = 19191; |
| 238 packet.nonce_proof = 132232; | 239 packet.nonce_proof = 132232; |
| 239 scoped_ptr<QuicEncryptedPacket> encrypted( | 240 scoped_ptr<QuicEncryptedPacket> encrypted( |
| 240 QuicFramer::BuildPublicResetPacket(packet)); | 241 QuicFramer::BuildPublicResetPacket(packet)); |
| 241 EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)).Times(1) | 242 EXPECT_CALL(*session1_, OnConnectionClosed(QUIC_PUBLIC_RESET, true)).Times(1) |
| 242 .WillOnce(WithoutArgs(Invoke( | 243 .WillOnce(WithoutArgs(Invoke( |
| 243 reinterpret_cast<MockServerConnection*>(session1_->connection()), | 244 reinterpret_cast<MockServerConnection*>(session1_->connection()), |
| 244 &MockServerConnection::UnregisterOnConnectionClosed))); | 245 &MockServerConnection::UnregisterOnConnectionClosed))); |
| 245 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), | 246 EXPECT_CALL(*reinterpret_cast<MockConnection*>(session1_->connection()), |
| 246 ProcessUdpPacket(_, _, _)) | 247 ProcessUdpPacket(_, _, _)) |
| 247 .WillOnce(Invoke( | 248 .WillOnce(Invoke( |
| 248 reinterpret_cast<MockConnection*>(session1_->connection()), | 249 reinterpret_cast<MockConnection*>(session1_->connection()), |
| 249 &MockConnection::ReallyProcessUdpPacket)); | 250 &MockConnection::ReallyProcessUdpPacket)); |
| 250 dispatcher_.ProcessPacket(IPEndPoint(), addr, *encrypted); | 251 dispatcher_.ProcessPacket(IPEndPoint(), addr, *encrypted); |
| 251 EXPECT_TRUE(time_wait_list_manager->IsGuidInTimeWait(guid)); | 252 EXPECT_TRUE(time_wait_list_manager->IsConnectionIdInTimeWait(connection_id)); |
| 252 | 253 |
| 253 // Dispatcher forwards subsequent packets for this guid to the time wait list | 254 // Dispatcher forwards subsequent packets for this connection_id to the time |
| 254 // manager. | 255 // wait list manager. |
| 255 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); | 256 EXPECT_CALL(*time_wait_list_manager, |
| 256 ProcessPacket(addr, guid, true, "foo"); | 257 ProcessPacket(_, _, connection_id, _)).Times(1); |
| 258 ProcessPacket(addr, connection_id, true, "foo"); |
| 257 } | 259 } |
| 258 | 260 |
| 259 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { | 261 TEST_F(QuicDispatcherTest, StrayPacketToTimeWaitListManager) { |
| 260 MockTimeWaitListManager* time_wait_list_manager = | 262 MockTimeWaitListManager* time_wait_list_manager = |
| 261 new MockTimeWaitListManager( | 263 new MockTimeWaitListManager( |
| 262 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); | 264 QuicDispatcherPeer::GetWriter(&dispatcher_), &dispatcher_, &eps_); |
| 263 // dispatcher takes the ownership of time_wait_list_manager. | 265 // dispatcher takes the ownership of time_wait_list_manager. |
| 264 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, | 266 QuicDispatcherPeer::SetTimeWaitListManager(&dispatcher_, |
| 265 time_wait_list_manager); | 267 time_wait_list_manager); |
| 266 | 268 |
| 267 IPEndPoint addr(net::test::Loopback4(), 1); | 269 IPEndPoint addr(net::test::Loopback4(), 1); |
| 268 QuicGuid guid = 1; | 270 QuicConnectionId connection_id = 1; |
| 269 // Dispatcher forwards all packets for this guid to the time wait list | 271 // Dispatcher forwards all packets for this connection_id to the time wait |
| 270 // manager. | 272 // list manager. |
| 271 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); | 273 EXPECT_CALL(dispatcher_, CreateQuicSession(_, _, _)).Times(0); |
| 272 EXPECT_CALL(*time_wait_list_manager, ProcessPacket(_, _, guid, _)).Times(1); | 274 EXPECT_CALL(*time_wait_list_manager, |
| 275 ProcessPacket(_, _, connection_id, _)).Times(1); |
| 273 string data = "foo"; | 276 string data = "foo"; |
| 274 ProcessPacket(addr, guid, false, "foo"); | 277 ProcessPacket(addr, connection_id, false, "foo"); |
| 275 } | 278 } |
| 276 | 279 |
| 277 class BlockingWriter : public QuicPacketWriterWrapper { | 280 class BlockingWriter : public QuicPacketWriterWrapper { |
| 278 public: | 281 public: |
| 279 BlockingWriter() : write_blocked_(false) {} | 282 BlockingWriter() : write_blocked_(false) {} |
| 280 | 283 |
| 281 virtual bool IsWriteBlocked() const OVERRIDE { return write_blocked_; } | 284 virtual bool IsWriteBlocked() const OVERRIDE { return write_blocked_; } |
| 282 virtual void SetWritable() OVERRIDE { write_blocked_ = false; } | 285 virtual void SetWritable() OVERRIDE { write_blocked_ = false; } |
| 283 | 286 |
| 284 virtual WriteResult WritePacket( | 287 virtual WriteResult WritePacket( |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 // And we'll resume where we left off when we get another call. | 468 // And we'll resume where we left off when we get another call. |
| 466 EXPECT_CALL(*connection2(), OnCanWrite()); | 469 EXPECT_CALL(*connection2(), OnCanWrite()); |
| 467 dispatcher_.OnCanWrite(); | 470 dispatcher_.OnCanWrite(); |
| 468 EXPECT_FALSE(dispatcher_.HasPendingWrites()); | 471 EXPECT_FALSE(dispatcher_.HasPendingWrites()); |
| 469 } | 472 } |
| 470 | 473 |
| 471 } // namespace | 474 } // namespace |
| 472 } // namespace test | 475 } // namespace test |
| 473 } // namespace tools | 476 } // namespace tools |
| 474 } // namespace net | 477 } // namespace net |
| OLD | NEW |