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 22 matching lines...) Expand all Loading... |
33 public: | 33 public: |
34 static QuicDataStream* GetIncomingDataStream( | 34 static QuicDataStream* GetIncomingDataStream( |
35 QuicServerSession* s, QuicStreamId id) { | 35 QuicServerSession* s, QuicStreamId id) { |
36 return s->GetIncomingDataStream(id); | 36 return s->GetIncomingDataStream(id); |
37 } | 37 } |
38 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { | 38 static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) { |
39 return s->GetDataStream(id); | 39 return s->GetDataStream(id); |
40 } | 40 } |
41 }; | 41 }; |
42 | 42 |
43 class CloseOnDataStream : public QuicDataStream { | |
44 public: | |
45 CloseOnDataStream(QuicStreamId id, QuicSession* session) | |
46 : QuicDataStream(id, session) { | |
47 } | |
48 | |
49 virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE { | |
50 session()->MarkDecompressionBlocked(1, id()); | |
51 session()->CloseStream(id()); | |
52 return true; | |
53 } | |
54 | |
55 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { | |
56 return 0; | |
57 } | |
58 }; | |
59 | |
60 class TestQuicServerSession : public QuicServerSession { | |
61 public: | |
62 TestQuicServerSession(const QuicConfig& config, | |
63 QuicConnection* connection, | |
64 QuicServerSessionVisitor* owner) | |
65 : QuicServerSession(config, connection, owner), | |
66 close_stream_on_data_(false) {} | |
67 | |
68 virtual QuicDataStream* CreateIncomingDataStream( | |
69 QuicStreamId id) OVERRIDE { | |
70 if (!ShouldCreateIncomingDataStream(id)) { | |
71 return NULL; | |
72 } | |
73 if (close_stream_on_data_) { | |
74 return new CloseOnDataStream(id, this); | |
75 } else { | |
76 return new QuicSpdyServerStream(id, this); | |
77 } | |
78 } | |
79 | |
80 void CloseStreamOnData() { | |
81 close_stream_on_data_ = true; | |
82 } | |
83 | |
84 private: | |
85 bool close_stream_on_data_; | |
86 }; | |
87 | |
88 namespace { | 43 namespace { |
89 | 44 |
90 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { | 45 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> { |
91 protected: | 46 protected: |
92 QuicServerSessionTest() | 47 QuicServerSessionTest() |
93 : crypto_config_(QuicCryptoServerConfig::TESTING, | 48 : crypto_config_(QuicCryptoServerConfig::TESTING, |
94 QuicRandom::GetInstance()) { | 49 QuicRandom::GetInstance()) { |
95 config_.SetDefaults(); | 50 config_.SetDefaults(); |
96 config_.set_max_streams_per_connection(3, 3); | 51 config_.set_max_streams_per_connection(3, 3); |
97 | 52 |
98 connection_ = | 53 connection_ = |
99 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); | 54 new StrictMock<MockConnection>(true, SupportedVersions(GetParam())); |
100 session_.reset(new TestQuicServerSession( | 55 session_.reset(new QuicServerSession( |
101 config_, connection_, &owner_)); | 56 config_, connection_, &owner_)); |
102 session_->InitializeSession(crypto_config_); | 57 session_->InitializeSession(crypto_config_); |
103 visitor_ = QuicConnectionPeer::GetVisitor(connection_); | 58 visitor_ = QuicConnectionPeer::GetVisitor(connection_); |
104 } | 59 } |
105 | 60 |
106 void MarkHeadersReadForStream(QuicStreamId id) { | |
107 QuicDataStream* stream = QuicServerSessionPeer::GetDataStream( | |
108 session_.get(), id); | |
109 ASSERT_TRUE(stream != NULL); | |
110 QuicDataStreamPeer::SetHeadersDecompressed(stream, true); | |
111 } | |
112 | |
113 QuicVersion version() const { return connection_->version(); } | 61 QuicVersion version() const { return connection_->version(); } |
114 | 62 |
115 StrictMock<MockQuicServerSessionVisitor> owner_; | 63 StrictMock<MockQuicServerSessionVisitor> owner_; |
116 StrictMock<MockConnection>* connection_; | 64 StrictMock<MockConnection>* connection_; |
117 QuicConfig config_; | 65 QuicConfig config_; |
118 QuicCryptoServerConfig crypto_config_; | 66 QuicCryptoServerConfig crypto_config_; |
119 scoped_ptr<TestQuicServerSession> session_; | 67 scoped_ptr<QuicServerSession> session_; |
120 QuicConnectionVisitorInterface* visitor_; | 68 QuicConnectionVisitorInterface* visitor_; |
121 }; | 69 }; |
122 | 70 |
123 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, | 71 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest, |
124 ::testing::ValuesIn(QuicSupportedVersions())); | 72 ::testing::ValuesIn(QuicSupportedVersions())); |
125 | 73 |
126 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { | 74 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) { |
127 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | 75 QuicStreamId stream_id = 5; |
128 // Open a stream, then reset it. | 76 // Open a stream, then reset it. |
129 // Send two bytes of payload to open it. | 77 // Send two bytes of payload to open it. |
130 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); | 78 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); |
131 vector<QuicStreamFrame> frames; | 79 vector<QuicStreamFrame> frames; |
132 frames.push_back(data1); | 80 frames.push_back(data1); |
133 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 81 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
134 EXPECT_EQ(1u, session_->GetNumOpenStreams()); | 82 EXPECT_EQ(1u, session_->GetNumOpenStreams()); |
135 | 83 |
136 // Pretend we got full headers, so we won't trigger the 'unrecoverable | |
137 // compression context' state. | |
138 MarkHeadersReadForStream(stream_id); | |
139 | |
140 // Send a reset (and expect the peer to send a RST in response). | 84 // Send a reset (and expect the peer to send a RST in response). |
141 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); | 85 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); |
142 if (version() > QUIC_VERSION_13) { | 86 if (version() > QUIC_VERSION_13) { |
143 EXPECT_CALL(*connection_, | 87 EXPECT_CALL(*connection_, |
144 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); | 88 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); |
145 } | 89 } |
146 visitor_->OnRstStream(rst1); | 90 visitor_->OnRstStream(rst1); |
147 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 91 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
148 | 92 |
149 // Send the same two bytes of payload in a new packet. | 93 // Send the same two bytes of payload in a new packet. |
150 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 94 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
151 | 95 |
152 // The stream should not be re-opened. | 96 // The stream should not be re-opened. |
153 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 97 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
154 } | 98 } |
155 | 99 |
156 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { | 100 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) { |
157 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | 101 QuicStreamId stream_id = 5; |
158 | 102 |
159 // Send a reset (and expect the peer to send a RST in response). | 103 // Send a reset (and expect the peer to send a RST in response). |
160 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); | 104 QuicRstStreamFrame rst1(stream_id, QUIC_STREAM_NO_ERROR, 0); |
161 if (version() > QUIC_VERSION_13) { | 105 if (version() > QUIC_VERSION_13) { |
162 EXPECT_CALL(*connection_, | 106 EXPECT_CALL(*connection_, |
163 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); | 107 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); |
164 } | 108 } |
165 visitor_->OnRstStream(rst1); | 109 visitor_->OnRstStream(rst1); |
166 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 110 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
167 | 111 |
168 // Send two bytes of payload. | 112 // Send two bytes of payload. |
169 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); | 113 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("HT")); |
170 vector<QuicStreamFrame> frames; | 114 vector<QuicStreamFrame> frames; |
171 frames.push_back(data1); | 115 frames.push_back(data1); |
172 | 116 |
173 if (version() > QUIC_VERSION_12) { | 117 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
174 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | |
175 } else { | |
176 // When we get data for the closed stream, it implies the far side has | |
177 // compressed some headers. As a result we're going to bail due to | |
178 // unrecoverable compression context state. | |
179 EXPECT_CALL(*connection_, SendConnectionClose( | |
180 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); | |
181 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); | |
182 } | |
183 | 118 |
184 // The stream should never be opened, now that the reset is received. | 119 // The stream should never be opened, now that the reset is received. |
185 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 120 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
186 } | 121 } |
187 | 122 |
188 TEST_P(QuicServerSessionTest, GoOverPrematureClosedStreamLimit) { | |
189 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | |
190 if (version() > QUIC_VERSION_12) { | |
191 // The prematurely closed stream limit is v12 specific. | |
192 return; | |
193 } | |
194 QuicStreamFrame data1(stream_id, false, 0, MakeIOVector("H")); | |
195 vector<QuicStreamFrame> frames; | |
196 frames.push_back(data1); | |
197 | |
198 // Set up the stream such that it's open in OnPacket, but closes half way | |
199 // through while on the decompression blocked list. | |
200 session_->CloseStreamOnData(); | |
201 | |
202 EXPECT_CALL(*connection_, SendConnectionClose( | |
203 QUIC_STREAM_RST_BEFORE_HEADERS_DECOMPRESSED)); | |
204 EXPECT_FALSE(visitor_->OnStreamFrames(frames)); | |
205 } | |
206 | |
207 TEST_P(QuicServerSessionTest, AcceptClosedStream) { | 123 TEST_P(QuicServerSessionTest, AcceptClosedStream) { |
208 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | 124 QuicStreamId stream_id = 5; |
209 vector<QuicStreamFrame> frames; | 125 vector<QuicStreamFrame> frames; |
210 // Send (empty) compressed headers followed by two bytes of data. | 126 // Send (empty) compressed headers followed by two bytes of data. |
211 frames.push_back(QuicStreamFrame(stream_id, false, 0, | 127 frames.push_back(QuicStreamFrame(stream_id, false, 0, |
212 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); | 128 MakeIOVector("\1\0\0\0\0\0\0\0HT"))); |
213 frames.push_back(QuicStreamFrame(stream_id + 2, false, 0, | 129 frames.push_back(QuicStreamFrame(stream_id + 2, false, 0, |
214 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); | 130 MakeIOVector("\2\0\0\0\0\0\0\0HT"))); |
215 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 131 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
216 | 132 |
217 // Pretend we got full headers, so we won't trigger the 'unercoverable | |
218 // compression context' state. | |
219 MarkHeadersReadForStream(stream_id); | |
220 | |
221 // Send a reset (and expect the peer to send a RST in response). | 133 // Send a reset (and expect the peer to send a RST in response). |
222 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR, 0); | 134 QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR, 0); |
223 if (version() > QUIC_VERSION_13) { | 135 if (version() > QUIC_VERSION_13) { |
224 EXPECT_CALL(*connection_, | 136 EXPECT_CALL(*connection_, |
225 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); | 137 SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 0)); |
226 } | 138 } |
227 visitor_->OnRstStream(rst); | 139 visitor_->OnRstStream(rst); |
228 | 140 |
229 // If we were tracking, we'd probably want to reject this because it's data | 141 // If we were tracking, we'd probably want to reject this because it's data |
230 // past the reset point of stream 3. As it's a closed stream we just drop the | 142 // past the reset point of stream 3. As it's a closed stream we just drop the |
231 // data on the floor, but accept the packet because it has data for stream 5. | 143 // data on the floor, but accept the packet because it has data for stream 5. |
232 frames.clear(); | 144 frames.clear(); |
233 frames.push_back(QuicStreamFrame(stream_id, false, 2, MakeIOVector("TP"))); | 145 frames.push_back(QuicStreamFrame(stream_id, false, 2, MakeIOVector("TP"))); |
234 frames.push_back(QuicStreamFrame(stream_id + 2, false, 2, | 146 frames.push_back(QuicStreamFrame(stream_id + 2, false, 2, |
235 MakeIOVector("TP"))); | 147 MakeIOVector("TP"))); |
236 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); | 148 EXPECT_TRUE(visitor_->OnStreamFrames(frames)); |
237 } | 149 } |
238 | 150 |
239 TEST_P(QuicServerSessionTest, MaxNumConnections) { | 151 TEST_P(QuicServerSessionTest, MaxNumConnections) { |
240 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | 152 QuicStreamId stream_id = 5; |
241 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 153 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
242 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 154 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
243 stream_id)); | 155 stream_id)); |
244 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 156 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
245 stream_id + 2)); | 157 stream_id + 2)); |
246 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 158 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
247 stream_id + 4)); | 159 stream_id + 4)); |
248 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 160 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
249 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 161 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
250 stream_id + 6)); | 162 stream_id + 6)); |
251 } | 163 } |
252 | 164 |
253 TEST_P(QuicServerSessionTest, MaxNumConnectionsImplicit) { | 165 TEST_P(QuicServerSessionTest, MaxNumConnectionsImplicit) { |
254 QuicStreamId stream_id = (version() == QUIC_VERSION_12 ? 3 : 5); | 166 QuicStreamId stream_id = 5; |
255 EXPECT_EQ(0u, session_->GetNumOpenStreams()); | 167 EXPECT_EQ(0u, session_->GetNumOpenStreams()); |
256 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 168 EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
257 stream_id)); | 169 stream_id)); |
258 // Implicitly opens two more streams. | 170 // Implicitly opens two more streams. |
259 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); | 171 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS)); |
260 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), | 172 EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(), |
261 stream_id + 6)); | 173 stream_id + 6)); |
262 } | 174 } |
263 | 175 |
264 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { | 176 TEST_P(QuicServerSessionTest, GetEvenIncomingError) { |
265 // Incoming streams on the server session must be odd. | 177 // Incoming streams on the server session must be odd. |
266 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); | 178 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); |
267 EXPECT_EQ(NULL, | 179 EXPECT_EQ(NULL, |
268 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); | 180 QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4)); |
269 } | 181 } |
270 | 182 |
271 } // namespace | 183 } // namespace |
272 } // namespace test | 184 } // namespace test |
273 } // namespace tools | 185 } // namespace tools |
274 } // namespace net | 186 } // namespace net |
OLD | NEW |