| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_server_session.h" | 5 #include "net/tools/quic/quic_server_session.h" |
| 6 | 6 |
| 7 #include "net/quic/crypto/quic_crypto_server_config.h" | 7 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 8 #include "net/quic/crypto/quic_random.h" | 8 #include "net/quic/crypto/quic_random.h" |
| 9 #include "net/quic/quic_connection.h" | 9 #include "net/quic/quic_connection.h" |
| 10 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 visitor_ = QuicConnectionPeer::GetVisitor(connection_); | 103 visitor_ = QuicConnectionPeer::GetVisitor(connection_); |
| 104 } | 104 } |
| 105 | 105 |
| 106 void MarkHeadersReadForStream(QuicStreamId id) { | 106 void MarkHeadersReadForStream(QuicStreamId id) { |
| 107 QuicDataStream* stream = QuicServerSessionPeer::GetDataStream( | 107 QuicDataStream* stream = QuicServerSessionPeer::GetDataStream( |
| 108 session_.get(), id); | 108 session_.get(), id); |
| 109 ASSERT_TRUE(stream != NULL); | 109 ASSERT_TRUE(stream != NULL); |
| 110 QuicDataStreamPeer::SetHeadersDecompressed(stream, true); | 110 QuicDataStreamPeer::SetHeadersDecompressed(stream, true); |
| 111 } | 111 } |
| 112 | 112 |
| 113 QuicVersion version() const { return connection_->version(); } |
| 114 |
| 113 StrictMock<MockQuicServerSessionVisitor> owner_; | 115 StrictMock<MockQuicServerSessionVisitor> owner_; |
| 114 StrictMock<MockConnection>* connection_; | 116 StrictMock<MockConnection>* connection_; |
| 115 QuicConfig config_; | 117 QuicConfig config_; |
| 116 QuicCryptoServerConfig crypto_config_; | 118 QuicCryptoServerConfig crypto_config_; |
| 117 scoped_ptr<TestQuicQuicServerSession> session_; | 119 scoped_ptr<TestQuicQuicServerSession> session_; |
| 118 QuicConnectionVisitorInterface* visitor_; | 120 QuicConnectionVisitorInterface* visitor_; |
| 119 }; | 121 }; |
| 120 | 122 |
| 121 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, | 123 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, |
| 122 ::testing::ValuesIn(QuicSupportedVersions())); | 124 ::testing::ValuesIn(QuicSupportedVersions())); |
| 123 | 125 |
| 124 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { | 126 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { |
| 125 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 127 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 126 // Open a stream, then reset it. | 128 // Open a stream, then reset it. |
| 127 // Send two bytes of payload to open it. | 129 // Send two bytes of payload to open it. |
| 128 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); | 130 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); |
| 129 vector<QuicStreamFrame> frames; | 131 vector<QuicStreamFrame> frames; |
| 130 frames.push_back(data1); | 132 frames.push_back(data1); |
| 131 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 133 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
| 132 EXPECT_EQ(1u, session_->GetNumOpenStreams()); | 134 EXPECT_EQ(1u, session_->GetNumOpenStreams()); |
| 133 | 135 |
| 134 // Pretend we got full headers, so we won't trigger the 'unrecoverable | 136 // Pretend we got full headers, so we won't trigger the 'unrecoverable |
| 135 // compression context' state. | 137 // compression context' state. |
| 136 MarkHeadersReadForStream(stream_id); | 138 MarkHeadersReadForStream(stream_id); |
| 137 | 139 |
| 138 // Send a reset. | 140 // Send a reset. |
| 139 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); | 141 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); |
| 140 visitor_->OnRstStream(rst1); | 142 visitor_->OnRstStream(rst1); |
| 141 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 143 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 142 | 144 |
| 143 // Send the same two bytes of payload in a new packet. | 145 // Send the same two bytes of payload in a new packet. |
| 144 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 146 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
| 145 | 147 |
| 146 // The stream should not be re-opened. | 148 // The stream should not be re-opened. |
| 147 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 149 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 148 } | 150 } |
| 149 | 151 |
| 150 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { | 152 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { |
| 151 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 153 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 152 // Send a reset. | 154 // Send a reset. |
| 153 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); | 155 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); |
| 154 visitor_->OnRstStream(rst1); | 156 visitor_->OnRstStream(rst1); |
| 155 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 157 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 156 | 158 |
| 157 // Send two bytes of payload. | 159 // Send two bytes of payload. |
| 158 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); | 160 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); |
| 159 vector<QuicStreamFrame> frames; | 161 vector<QuicStreamFrame> frames; |
| 160 frames.push_back(data1); | 162 frames.push_back(data1); |
| 161 | 163 |
| 162 if (connection_->version() > QUIC_VERSION_12) { | 164 if (version() > QUIC_VERSION_12) { |
| 163 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 165 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
| 164 } else { | 166 } else { |
| 165 // When we get data for the closed stream, it implies the far side has | 167 // When we get data for the closed stream, it implies the far side has |
| 166 // compressed some headers. As a result we're going to bail due to | 168 // compressed some headers. As a result we're going to bail due to |
| 167 // unrecoverable compression context state. | 169 // unrecoverable compression context state. |
| 168 EXPECT_CALL(*connection_, SendConnectionClose( | 170 EXPECT_CALL(*connection_, SendConnectionClose( |
| 169 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); | 171 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); |
| 170 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); | 172 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); |
| 171 } | 173 } |
| 172 | 174 |
| 173 // The stream should never be opened, now that the reset is received. | 175 // The stream should never be opened, now that the reset is received. |
| 174 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 176 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 175 } | 177 } |
| 176 | 178 |
| 177 TEST_P(QuicServerSessionTest, GoOverPrematureClosedStreamLimit) { | 179 TEST_P(QuicServerSessionTest, GoOverPrematureClosedStreamLimit) { |
| 178 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 180 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 179 if (connection_->version() > QUIC_VERSION_12) { | 181 if (version() > QUIC_VERSION_12) { |
| 180 // The prematurely closed stream limit is v12 specific. | 182 // The prematurely closed stream limit is v12 specific. |
| 181 return; | 183 return; |
| 182 } | 184 } |
| 183 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("H")); | 185 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("H")); |
| 184 vector<QuicStreamFrame> frames; | 186 vector<QuicStreamFrame> frames; |
| 185 frames.push_back(data1); | 187 frames.push_back(data1); |
| 186 | 188 |
| 187 // Set up the stream such that it's open in OnPacket, but closes half way | 189 // Set up the stream such that it's open in OnPacket, but closes half way |
| 188 // through while on the decompression blocked list. | 190 // through while on the decompression blocked list. |
| 189 session_->CloseStreamOnData(); | 191 session_->CloseStreamOnData(); |
| 190 | 192 |
| 191 EXPECT_CALL(*connection_, SendConnectionClose( | 193 EXPECT_CALL(*connection_, SendConnectionClose( |
| 192 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); | 194 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); |
| 193 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); | 195 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); |
| 194 } | 196 } |
| 195 | 197 |
| 196 TEST_P(QuicServerSessionTest, AcceptClosedStream) { | 198 TEST_P(QuicServerSessionTest, AcceptClosedStream) { |
| 197 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 199 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 198 vector<QuicStreamFrame> frames; | 200 vector<QuicStreamFrame> frames; |
| 199 // Send (empty) compressed headers followed by two bytes of data. | 201 // Send (empty) compressed headers followed by two bytes of data. |
| 200 frames.push_back(QuicStreamFrame(stream_id, false, 0, | 202 frames.push_back(QuicStreamFrame(stream_id, false, 0, |
| 201 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); | 203 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); |
| 202 frames.push_back(QuicStreamFrame(stream_id + 2, false, 0, | 204 frames.push_back(QuicStreamFrame(stream_id + 2, false, 0, |
| 203 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); | 205 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); |
| 204 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 206 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
| 205 | 207 |
| 206 // Pretend we got full headers, so we won't trigger the 'unercoverable | 208 // Pretend we got full headers, so we won't trigger the 'unercoverable |
| 207 // compression context' state. | 209 // compression context' state. |
| 208 MarkHeadersReadForStream(stream_id); | 210 MarkHeadersReadForStream(stream_id); |
| 209 | 211 |
| 210 // Send a reset. | 212 // Send a reset. |
| 211 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR, 0); | 213 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR, 0); |
| 212 visitor_->OnRstStream(rst); | 214 visitor_->OnRstStream(rst); |
| 213 | 215 |
| 214 // If we were tracking, we'd probably want to reject this because it's data | 216 // If we were tracking, we'd probably want to reject this because it's data |
| 215 // past the reset point of stream 3. As it's a closed stream we just drop the | 217 // past the reset point of stream 3. As it's a closed stream we just drop the |
| 216 // data on the floor, but accept the packet because it has data for stream 5. | 218 // data on the floor, but accept the packet because it has data for stream 5. |
| 217 frames.clear(); | 219 frames.clear(); |
| 218 frames.push_back(QuicStreamFrame(stream_id, false, 2, MakeIOVector("TP"))); | 220 frames.push_back(QuicStreamFrame(stream_id, false, 2, MakeIOVector("TP"))); |
| 219 frames.push_back(QuicStreamFrame(stream_id + 2, false, 2, | 221 frames.push_back(QuicStreamFrame(stream_id + 2, false, 2, |
| 220 MakeIOVector("TP"))); | 222 MakeIOVector("TP"))); |
| 221 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 223 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
| 222 } | 224 } |
| 223 | 225 |
| 224 TEST_P(QuicServerSessionTest, MaxNumConnections) { | 226 TEST_P(QuicServerSessionTest, MaxNumConnections) { |
| 225 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 227 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 226 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 228 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 227 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 229 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 228 stream_id)); | 230 stream_id)); |
| 229 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 231 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 230 stream_id + 2)); | 232 stream_id + 2)); |
| 231 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 233 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 232 stream_id + 4)); | 234 stream_id + 4)); |
| 233 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 235 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
| 234 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 236 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 235 stream_id + 6)); | 237 stream_id + 6)); |
| 236 } | 238 } |
| 237 | 239 |
| 238 TEST_P(QuicServerSessionTest, MaxNumConnectionsImplicit) { | 240 TEST_P(QuicServerSessionTest, MaxNumConnectionsImplicit) { |
| 239 QuicStreamId stream_id = GetParam() == QUIC_VERSION_12 ? 3 : 5; | 241 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); |
| 240 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 242 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
| 241 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 243 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 242 stream_id)); | 244 stream_id)); |
| 243 // Implicitly opens two more streams. | 245 // Implicitly opens two more streams. |
| 244 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 246 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
| 245 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 247 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
| 246 stream_id + 6)); | 248 stream_id + 6)); |
| 247 } | 249 } |
| 248 | 250 |
| 249 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { | 251 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { |
| 250 // Incoming streams on the server session must be odd. | 252 // Incoming streams on the server session must be odd. |
| 251 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); | 253 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); |
| 252 EXPECT_EQ(NULL, | 254 EXPECT_EQ(NULL, |
| 253 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); | 255 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); |
| 254 } | 256 } |
| 255 | 257 |
| 256 } // namespace | 258 } // namespace |
| 257 } // namespace test | 259 } // namespace test |
| 258 } // namespace tools | 260 } // namespace tools |
| 259 } // namespace net | 261 } // namespace net |
| OLD | NEW |