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 |