Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: net/tools/quic/quic_client.cc

Issue 2368183003: Move QuicClient::ClientQuicDataToResend from QuicClient to QuicClientBase. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_client.h" 5 #include "net/tools/quic/quic_client.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <netinet/in.h> 8 #include <netinet/in.h>
9 #include <string.h> 9 #include <string.h>
10 #include <sys/epoll.h> 10 #include <sys/epoll.h>
(...skipping 26 matching lines...) Expand all
37 37
38 using base::StringPiece; 38 using base::StringPiece;
39 using base::StringToInt; 39 using base::StringToInt;
40 using std::string; 40 using std::string;
41 using std::vector; 41 using std::vector;
42 42
43 namespace net { 43 namespace net {
44 44
45 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; 45 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
46 46
47 void QuicClient::ClientQuicDataToResend::Resend() {
48 client_->SendRequest(*headers_, body_, fin_);
49 headers_ = nullptr;
50 }
51
52 QuicClient::QuicClient(IPEndPoint server_address, 47 QuicClient::QuicClient(IPEndPoint server_address,
53 const QuicServerId& server_id, 48 const QuicServerId& server_id,
54 const QuicVersionVector& supported_versions, 49 const QuicVersionVector& supported_versions,
55 EpollServer* epoll_server, 50 EpollServer* epoll_server,
56 std::unique_ptr<ProofVerifier> proof_verifier) 51 std::unique_ptr<ProofVerifier> proof_verifier)
57 : QuicClient(server_address, 52 : QuicClient(server_address,
58 server_id, 53 server_id,
59 supported_versions, 54 supported_versions,
60 QuicConfig(), 55 QuicConfig(),
61 epoll_server, 56 epoll_server,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 162
168 bool QuicClient::Connect() { 163 bool QuicClient::Connect() {
169 // Attempt multiple connects until the maximum number of client hellos have 164 // Attempt multiple connects until the maximum number of client hellos have
170 // been sent. 165 // been sent.
171 while (!connected() && 166 while (!connected() &&
172 GetNumSentClientHellos() <= QuicCryptoClientStream::kMaxClientHellos) { 167 GetNumSentClientHellos() <= QuicCryptoClientStream::kMaxClientHellos) {
173 StartConnect(); 168 StartConnect();
174 while (EncryptionBeingEstablished()) { 169 while (EncryptionBeingEstablished()) {
175 WaitForEvents(); 170 WaitForEvents();
176 } 171 }
177 if (FLAGS_enable_quic_stateless_reject_support && connected() && 172 if (FLAGS_enable_quic_stateless_reject_support && connected()) {
178 !data_to_resend_on_connect_.empty()) { 173 // Resend any previously queued data.
Zhongyi Shi 2016/09/27 04:40:25 nit: comments here seem to be out of sync with int
Ryan Hamilton 2016/09/27 14:28:00 Silly long story, but will be fixed in the next cl
179 // A connection has been established and there was previously queued data 174 ResendSavedData();
180 // to resend. Resend it and empty the queue.
181 std::vector<std::unique_ptr<QuicDataToResend>> old_data;
182 old_data.swap(data_to_resend_on_connect_);
183 for (const auto& data : old_data) {
184 data->Resend();
185 }
186 } 175 }
187 if (session() != nullptr && 176 if (session() != nullptr &&
188 session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 177 session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
189 // We've successfully created a session but we're not connected, and there 178 // We've successfully created a session but we're not connected, and there
190 // is no stateless reject to recover from. Give up trying. 179 // is no stateless reject to recover from. Give up trying.
191 break; 180 break;
192 } 181 }
193 } 182 }
194 if (!connected() && 183 if (!connected() &&
195 GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos && 184 GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos &&
196 session() != nullptr && 185 session() != nullptr &&
197 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 186 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
198 // The overall connection failed due too many stateless rejects. 187 // The overall connection failed due too many stateless rejects.
199 set_connection_error(QUIC_CRYPTO_TOO_MANY_REJECTS); 188 set_connection_error(QUIC_CRYPTO_TOO_MANY_REJECTS);
200 } 189 }
201 return session()->connection()->connected(); 190 return session()->connection()->connected();
202 } 191 }
203 192
204 void QuicClient::StartConnect() { 193 void QuicClient::StartConnect() {
205 DCHECK(initialized_); 194 DCHECK(initialized_);
206 DCHECK(!connected()); 195 DCHECK(!connected());
207 196
208 QuicPacketWriter* writer = CreateQuicPacketWriter(); 197 QuicPacketWriter* writer = CreateQuicPacketWriter();
209 198
210 if (connected_or_attempting_connect()) { 199 if (connected_or_attempting_connect()) {
211 // If the last error was not a stateless reject, then the queued up data 200 // If the last error was not a stateless reject, then the queued up data
212 // does not need to be resent. 201 // does not need to be resent.
213 if (session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 202 if (session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
214 data_to_resend_on_connect_.clear(); 203 ClearDataToResend();
215 } 204 }
216 // Before we destroy the last session and create a new one, gather its stats 205 // Before we destroy the last session and create a new one, gather its stats
217 // and update the stats for the overall connection. 206 // and update the stats for the overall connection.
218 UpdateStats(); 207 UpdateStats();
219 } 208 }
220 209
221 CreateQuicClientSession(new QuicConnection( 210 CreateQuicClientSession(new QuicConnection(
222 GetNextConnectionId(), server_address_, helper(), alarm_factory(), writer, 211 GetNextConnectionId(), server_address_, helper(), alarm_factory(), writer,
223 /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions())); 212 /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions()));
224 213
225 // Reset |writer()| after |session()| so that the old writer outlives the old 214 // Reset |writer()| after |session()| so that the old writer outlives the old
226 // session. 215 // session.
227 set_writer(writer); 216 set_writer(writer);
228 session()->Initialize(); 217 session()->Initialize();
229 session()->CryptoConnect(); 218 session()->CryptoConnect();
230 set_connected_or_attempting_connect(true); 219 set_connected_or_attempting_connect(true);
231 } 220 }
232 221
233 void QuicClient::Disconnect() { 222 void QuicClient::Disconnect() {
234 DCHECK(initialized_); 223 DCHECK(initialized_);
235 224
236 if (connected()) { 225 if (connected()) {
237 session()->connection()->CloseConnection( 226 session()->connection()->CloseConnection(
238 QUIC_PEER_GOING_AWAY, "Client disconnecting", 227 QUIC_PEER_GOING_AWAY, "Client disconnecting",
239 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); 228 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
240 } 229 }
241 230
242 data_to_resend_on_connect_.clear(); 231 ClearDataToResend();
243 232
244 CleanUpAllUDPSockets(); 233 CleanUpAllUDPSockets();
245 234
246 initialized_ = false; 235 initialized_ = false;
247 } 236 }
248 237
249 void QuicClient::CleanUpUDPSocket(int fd) { 238 void QuicClient::CleanUpUDPSocket(int fd) {
250 CleanUpUDPSocketImpl(fd); 239 CleanUpUDPSocketImpl(fd);
251 fd_address_map_.erase(fd); 240 fd_address_map_.erase(fd);
252 } 241 }
(...skipping 16 matching lines...) Expand all
269 void QuicClient::SendRequest(const SpdyHeaderBlock& headers, 258 void QuicClient::SendRequest(const SpdyHeaderBlock& headers,
270 StringPiece body, 259 StringPiece body,
271 bool fin) { 260 bool fin) {
272 QuicClientPushPromiseIndex::TryHandle* handle; 261 QuicClientPushPromiseIndex::TryHandle* handle;
273 QuicAsyncStatus rv = push_promise_index()->Try(headers, this, &handle); 262 QuicAsyncStatus rv = push_promise_index()->Try(headers, this, &handle);
274 if (rv == QUIC_SUCCESS) 263 if (rv == QUIC_SUCCESS)
275 return; 264 return;
276 265
277 if (rv == QUIC_PENDING) { 266 if (rv == QUIC_PENDING) {
278 // May need to retry request if asynchronous rendezvous fails. 267 // May need to retry request if asynchronous rendezvous fails.
279 std::unique_ptr<SpdyHeaderBlock> new_headers( 268 AddPromiseDataToResend(headers, body, fin);
280 new SpdyHeaderBlock(headers.Clone()));
281 push_promise_data_to_resend_.reset(
282 new ClientQuicDataToResend(std::move(new_headers), body, fin, this));
283 return; 269 return;
284 } 270 }
285 271
286 QuicSpdyClientStream* stream = CreateReliableClientStream(); 272 QuicSpdyClientStream* stream = CreateReliableClientStream();
287 if (stream == nullptr) { 273 if (stream == nullptr) {
288 QUIC_BUG << "stream creation failed!"; 274 QUIC_BUG << "stream creation failed!";
289 return; 275 return;
290 } 276 }
291 stream->SendRequest(headers.Clone(), body, fin); 277 stream->SendRequest(headers.Clone(), body, fin);
292 if (FLAGS_enable_quic_stateless_reject_support) { 278 // Record this in case we need to resend.
293 // Record this in case we need to resend. 279 MaybeAddDataToResend(headers, body, fin);
294 std::unique_ptr<SpdyHeaderBlock> new_headers(
295 new SpdyHeaderBlock(headers.Clone()));
296 auto data_to_resend =
297 new ClientQuicDataToResend(std::move(new_headers), body, fin, this);
298 MaybeAddQuicDataToResend(std::unique_ptr<QuicDataToResend>(data_to_resend));
299 }
300 }
301
302 void QuicClient::MaybeAddQuicDataToResend(
303 std::unique_ptr<QuicDataToResend> data_to_resend) {
304 DCHECK(FLAGS_enable_quic_stateless_reject_support);
305 if (session()->IsCryptoHandshakeConfirmed()) {
306 // The handshake is confirmed. No need to continue saving requests to
307 // resend.
308 data_to_resend_on_connect_.clear();
309 return;
310 }
311
312 // The handshake is not confirmed. Push the data onto the queue of data to
313 // resend if statelessly rejected.
314 data_to_resend_on_connect_.push_back(std::move(data_to_resend));
315 } 280 }
316 281
317 void QuicClient::SendRequestAndWaitForResponse(const SpdyHeaderBlock& headers, 282 void QuicClient::SendRequestAndWaitForResponse(const SpdyHeaderBlock& headers,
318 StringPiece body, 283 StringPiece body,
319 bool fin) { 284 bool fin) {
320 SendRequest(headers, body, fin); 285 SendRequest(headers, body, fin);
321 while (WaitForEvents()) { 286 while (WaitForEvents()) {
322 } 287 }
323 } 288 }
324 289
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 LOG(ERROR) << "Invalid response headers: no status code"; 389 LOG(ERROR) << "Invalid response headers: no status code";
425 } 390 }
426 latest_response_headers_ = response_headers.DebugString(); 391 latest_response_headers_ = response_headers.DebugString();
427 latest_response_header_block_ = response_headers.Clone(); 392 latest_response_header_block_ = response_headers.Clone();
428 latest_response_body_ = client_stream->data(); 393 latest_response_body_ = client_stream->data();
429 latest_response_trailers_ = 394 latest_response_trailers_ =
430 client_stream->received_trailers().DebugString(); 395 client_stream->received_trailers().DebugString();
431 } 396 }
432 } 397 }
433 398
434 bool QuicClient::CheckVary(const SpdyHeaderBlock& client_request,
435 const SpdyHeaderBlock& promise_request,
436 const SpdyHeaderBlock& promise_response) {
437 return true;
438 }
439
440 void QuicClient::OnRendezvousResult(QuicSpdyStream* stream) {
441 std::unique_ptr<ClientQuicDataToResend> data_to_resend =
442 std::move(push_promise_data_to_resend_);
443 if (stream) {
444 stream->set_visitor(this);
445 stream->OnDataAvailable();
446 } else if (data_to_resend.get()) {
447 data_to_resend->Resend();
448 }
449 }
450
451 size_t QuicClient::latest_response_code() const { 399 size_t QuicClient::latest_response_code() const {
452 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 400 QUIC_BUG_IF(!store_response_) << "Response not stored!";
453 return latest_response_code_; 401 return latest_response_code_;
454 } 402 }
455 403
456 const string& QuicClient::latest_response_headers() const { 404 const string& QuicClient::latest_response_headers() const {
457 QUIC_BUG_IF(!store_response_) << "Response not stored!"; 405 QUIC_BUG_IF(!store_response_) << "Response not stored!";
458 return latest_response_headers_; 406 return latest_response_headers_;
459 } 407 }
460 408
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 return fd_address_map_.back().first; 441 return fd_address_map_.back().first;
494 } 442 }
495 443
496 void QuicClient::ProcessPacket(const IPEndPoint& self_address, 444 void QuicClient::ProcessPacket(const IPEndPoint& self_address,
497 const IPEndPoint& peer_address, 445 const IPEndPoint& peer_address,
498 const QuicReceivedPacket& packet) { 446 const QuicReceivedPacket& packet) {
499 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); 447 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet);
500 } 448 }
501 449
502 } // namespace net 450 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698