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

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

Issue 1297853002: QUIC - reorganize common code between quic_client and quic_simple_client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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>
11 #include <sys/socket.h> 11 #include <sys/socket.h>
12 #include <unistd.h> 12 #include <unistd.h>
13 13
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "net/base/net_util.h" 15 #include "net/base/net_util.h"
16 #include "net/quic/crypto/quic_random.h" 16 #include "net/quic/crypto/quic_random.h"
17 #include "net/quic/quic_connection.h" 17 #include "net/quic/quic_connection.h"
18 #include "net/quic/quic_crypto_client_stream.h"
19 #include "net/quic/quic_data_reader.h" 18 #include "net/quic/quic_data_reader.h"
20 #include "net/quic/quic_flags.h" 19 #include "net/quic/quic_flags.h"
21 #include "net/quic/quic_protocol.h" 20 #include "net/quic/quic_protocol.h"
22 #include "net/quic/quic_server_id.h" 21 #include "net/quic/quic_server_id.h"
23 #include "net/tools/balsa/balsa_headers.h"
24 #include "net/tools/epoll_server/epoll_server.h"
25 #include "net/tools/quic/quic_epoll_connection_helper.h" 22 #include "net/tools/quic/quic_epoll_connection_helper.h"
26 #include "net/tools/quic/quic_socket_utils.h" 23 #include "net/tools/quic/quic_socket_utils.h"
27 #include "net/tools/quic/quic_spdy_client_stream.h"
28 #include "net/tools/quic/spdy_balsa_utils.h" 24 #include "net/tools/quic/spdy_balsa_utils.h"
29 25
30 #ifndef SO_RXQ_OVFL 26 #ifndef SO_RXQ_OVFL
31 #define SO_RXQ_OVFL 40 27 #define SO_RXQ_OVFL 40
32 #endif 28 #endif
33 29
34 using std::string; 30 using std::string;
35 using std::vector; 31 using std::vector;
36 32
37 namespace net { 33 namespace net {
(...skipping 15 matching lines...) Expand all
53 server_id, 49 server_id,
54 supported_versions, 50 supported_versions,
55 QuicConfig(), 51 QuicConfig(),
56 epoll_server) {} 52 epoll_server) {}
57 53
58 QuicClient::QuicClient(IPEndPoint server_address, 54 QuicClient::QuicClient(IPEndPoint server_address,
59 const QuicServerId& server_id, 55 const QuicServerId& server_id,
60 const QuicVersionVector& supported_versions, 56 const QuicVersionVector& supported_versions,
61 const QuicConfig& config, 57 const QuicConfig& config,
62 EpollServer* epoll_server) 58 EpollServer* epoll_server)
63 : server_address_(server_address), 59 : QuicClientBase(server_id, supported_versions, config),
64 server_id_(server_id), 60 server_address_(server_address),
65 config_(config),
66 local_port_(0), 61 local_port_(0),
67 epoll_server_(epoll_server), 62 epoll_server_(epoll_server),
68 fd_(-1), 63 fd_(-1),
69 helper_(CreateQuicConnectionHelper()), 64 helper_(CreateQuicConnectionHelper()),
70 initialized_(false), 65 initialized_(false),
71 packets_dropped_(0), 66 packets_dropped_(0),
72 overflow_supported_(false), 67 overflow_supported_(false),
73 supported_versions_(supported_versions),
74 store_response_(false), 68 store_response_(false),
75 latest_response_code_(-1), 69 latest_response_code_(-1) {}
76 initial_max_packet_length_(0),
77 num_stateless_rejects_received_(0),
78 num_sent_client_hellos_(0),
79 connection_error_(QUIC_NO_ERROR),
80 connected_or_attempting_connect_(false) {}
81 70
82 QuicClient::~QuicClient() { 71 QuicClient::~QuicClient() {
83 if (connected()) { 72 if (connected()) {
84 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); 73 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
85 } 74 }
75
86 STLDeleteElements(&data_to_resend_on_connect_); 76 STLDeleteElements(&data_to_resend_on_connect_);
87 STLDeleteElements(&data_sent_before_handshake_); 77 STLDeleteElements(&data_sent_before_handshake_);
88 78
89 CleanUpUDPSocketImpl(); 79 CleanUpUDPSocketImpl();
90 } 80 }
91 81
92 bool QuicClient::Initialize() { 82 bool QuicClient::Initialize() {
93 DCHECK(!initialized_); 83 QuicClientBase::Initialize();
94
95 num_sent_client_hellos_ = 0;
96 num_stateless_rejects_received_ = 0;
97 connection_error_ = QUIC_NO_ERROR;
98 connected_or_attempting_connect_ = false;
99 84
100 // If an initial flow control window has not explicitly been set, then use the 85 // If an initial flow control window has not explicitly been set, then use the
101 // same values that Chrome uses. 86 // same values that Chrome uses.
102 const uint32 kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB 87 const uint32 kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
103 const uint32 kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB 88 const uint32 kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
104 if (config_.GetInitialStreamFlowControlWindowToSend() == 89 if (config()->GetInitialStreamFlowControlWindowToSend() ==
105 kMinimumFlowControlSendWindow) { 90 kMinimumFlowControlSendWindow) {
106 config_.SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize); 91 config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize);
107 } 92 }
108 if (config_.GetInitialSessionFlowControlWindowToSend() == 93 if (config()->GetInitialSessionFlowControlWindowToSend() ==
109 kMinimumFlowControlSendWindow) { 94 kMinimumFlowControlSendWindow) {
110 config_.SetInitialSessionFlowControlWindowToSend(kSessionMaxRecvWindowSize); 95 config()->SetInitialSessionFlowControlWindowToSend(
96 kSessionMaxRecvWindowSize);
111 } 97 }
112 98
113 epoll_server_->set_timeout_in_us(50 * 1000); 99 epoll_server_->set_timeout_in_us(50 * 1000);
114 100
115 if (!CreateUDPSocket()) { 101 if (!CreateUDPSocket()) {
116 return false; 102 return false;
117 } 103 }
118 104
119 epoll_server_->RegisterFD(fd_, this, kEpollFlags); 105 epoll_server_->RegisterFD(fd_, this, kEpollFlags);
120 initialized_ = true; 106 initialized_ = true;
121 return true; 107 return true;
122 } 108 }
123 109
124 QuicClient::DummyPacketWriterFactory::DummyPacketWriterFactory(
125 QuicPacketWriter* writer)
126 : writer_(writer) {}
127
128 QuicClient::DummyPacketWriterFactory::~DummyPacketWriterFactory() {}
129
130 QuicPacketWriter* QuicClient::DummyPacketWriterFactory::Create(
131 QuicConnection* /*connection*/) const {
132 return writer_;
133 }
134
135 QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers, 110 QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers,
136 StringPiece body, 111 StringPiece body,
137 bool fin) 112 bool fin)
138 : headers_(headers), body_(body), fin_(fin) {} 113 : headers_(headers), body_(body), fin_(fin) {}
139 114
140 QuicClient::QuicDataToResend::~QuicDataToResend() { 115 QuicClient::QuicDataToResend::~QuicDataToResend() {
141 if (headers_) { 116 if (headers_) {
142 delete headers_; 117 delete headers_;
143 } 118 }
144 } 119 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 194 }
220 if (FLAGS_enable_quic_stateless_reject_support && connected() && 195 if (FLAGS_enable_quic_stateless_reject_support && connected() &&
221 !data_to_resend_on_connect_.empty()) { 196 !data_to_resend_on_connect_.empty()) {
222 // A connection has been established and there was previously queued data 197 // A connection has been established and there was previously queued data
223 // to resend. Resend it and empty the queue. 198 // to resend. Resend it and empty the queue.
224 for (QuicDataToResend* data : data_to_resend_on_connect_) { 199 for (QuicDataToResend* data : data_to_resend_on_connect_) {
225 data->Resend(); 200 data->Resend();
226 } 201 }
227 STLDeleteElements(&data_to_resend_on_connect_); 202 STLDeleteElements(&data_to_resend_on_connect_);
228 } 203 }
229 if (session_.get() != nullptr && 204 if (session() != nullptr &&
230 session_->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 205 session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
231 // We've successfully created a session but we're not connected, and there 206 // We've successfully created a session but we're not connected, and there
232 // is no stateless reject to recover from. Give up trying. 207 // is no stateless reject to recover from. Give up trying.
233 break; 208 break;
234 } 209 }
235 } 210 }
236 if (!connected() && 211 if (!connected() &&
237 GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos && 212 GetNumSentClientHellos() > QuicCryptoClientStream::kMaxClientHellos &&
238 session_ != nullptr && 213 session() != nullptr &&
239 session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 214 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
240 // The overall connection failed due too many stateless rejects. 215 // The overall connection failed due too many stateless rejects.
241 connection_error_ = QUIC_CRYPTO_TOO_MANY_REJECTS; 216 set_connection_error(QUIC_CRYPTO_TOO_MANY_REJECTS);
242 } 217 }
243 return session_->connection()->connected(); 218 return session()->connection()->connected();
244 }
245
246 QuicClientSession* QuicClient::CreateQuicClientSession(
247 const QuicConfig& config,
248 QuicConnection* connection,
249 const QuicServerId& server_id,
250 QuicCryptoClientConfig* crypto_config) {
251 return new QuicClientSession(config, connection, server_id_, &crypto_config_);
252 } 219 }
253 220
254 void QuicClient::StartConnect() { 221 void QuicClient::StartConnect() {
255 DCHECK(initialized_); 222 DCHECK(initialized_);
256 DCHECK(!connected()); 223 DCHECK(!connected());
257 224
258 QuicPacketWriter* writer = CreateQuicPacketWriter(); 225 QuicPacketWriter* writer = CreateQuicPacketWriter();
259 226
260 DummyPacketWriterFactory factory(writer); 227 DummyPacketWriterFactory factory(writer);
261 228
262 if (connected_or_attempting_connect_) { 229 if (connected_or_attempting_connect()) {
263 // Before we destroy the last session and create a new one, gather its stats 230 // Before we destroy the last session and create a new one, gather its stats
264 // and update the stats for the overall connection. 231 // and update the stats for the overall connection.
265 num_sent_client_hellos_ += session_->GetNumSentClientHellos(); 232 UpdateStats();
266 if (session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 233 if (session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
267 // If the last error was due to a stateless reject, queue up the data to 234 // If the last error was due to a stateless reject, queue up the data to
268 // be resent on the next successful connection. 235 // be resent on the next successful connection.
269 // TODO(jokulik): I'm a little bit concerned about ordering here. Maybe 236 // TODO(jokulik): I'm a little bit concerned about ordering here. Maybe
270 // we should just maintain one queue? 237 // we should just maintain one queue?
271 ++num_stateless_rejects_received_;
272 DCHECK(data_to_resend_on_connect_.empty()); 238 DCHECK(data_to_resend_on_connect_.empty());
273 data_to_resend_on_connect_.swap(data_sent_before_handshake_); 239 data_to_resend_on_connect_.swap(data_sent_before_handshake_);
274 } 240 }
275 } 241 }
276 242
277 session_.reset(CreateQuicClientSession( 243 CreateQuicClientSession(new QuicConnection(
278 config_, 244 GetNextConnectionId(), server_address_, helper_.get(), factory,
279 new QuicConnection(GetNextConnectionId(), server_address_, helper_.get(), 245 /* owns_writer= */ false, Perspective::IS_CLIENT, server_id().is_https(),
280 factory, 246 supported_versions()));
281 /* owns_writer= */ false, Perspective::IS_CLIENT,
282 server_id_.is_https(), supported_versions_),
283 server_id_, &crypto_config_));
284 if (initial_max_packet_length_ != 0) {
285 session_->connection()->set_max_packet_length(initial_max_packet_length_);
286 }
287 247
288 // Reset |writer_| after |session_| so that the old writer outlives the old 248 // Reset |writer_| after |session()| so that the old writer outlives the old
289 // session. 249 // session.
290 if (writer_.get() != writer) { 250 set_writer(writer);
291 writer_.reset(writer); 251 session()->Initialize();
292 } 252 session()->CryptoConnect();
293 session_->Initialize(); 253 set_connected_or_attempting_connect(true);
294 session_->CryptoConnect();
295 connected_or_attempting_connect_ = true;
296 }
297
298 bool QuicClient::EncryptionBeingEstablished() {
299 return !session_->IsEncryptionEstablished() &&
300 session_->connection()->connected();
301 } 254 }
302 255
303 void QuicClient::Disconnect() { 256 void QuicClient::Disconnect() {
304 DCHECK(initialized_); 257 DCHECK(initialized_);
305 258
306 if (connected()) { 259 if (connected()) {
307 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); 260 session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY);
308 } 261 }
309 STLDeleteElements(&data_to_resend_on_connect_); 262 STLDeleteElements(&data_to_resend_on_connect_);
310 STLDeleteElements(&data_sent_before_handshake_); 263 STLDeleteElements(&data_sent_before_handshake_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 auto new_headers = new BalsaHeaders; 297 auto new_headers = new BalsaHeaders;
345 new_headers->CopyFrom(headers); 298 new_headers->CopyFrom(headers);
346 auto data_to_resend = 299 auto data_to_resend =
347 new ClientQuicDataToResend(new_headers, body, fin, this); 300 new ClientQuicDataToResend(new_headers, body, fin, this);
348 MaybeAddQuicDataToResend(data_to_resend); 301 MaybeAddQuicDataToResend(data_to_resend);
349 } 302 }
350 } 303 }
351 304
352 void QuicClient::MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend) { 305 void QuicClient::MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend) {
353 DCHECK(FLAGS_enable_quic_stateless_reject_support); 306 DCHECK(FLAGS_enable_quic_stateless_reject_support);
354 if (session_->IsCryptoHandshakeConfirmed()) { 307 if (session()->IsCryptoHandshakeConfirmed()) {
355 // The handshake is confirmed. No need to continue saving requests to 308 // The handshake is confirmed. No need to continue saving requests to
356 // resend. 309 // resend.
357 STLDeleteElements(&data_sent_before_handshake_); 310 STLDeleteElements(&data_sent_before_handshake_);
358 delete data_to_resend; 311 delete data_to_resend;
359 return; 312 return;
360 } 313 }
361 314
362 // The handshake is not confirmed. Push the data onto the queue of data to 315 // The handshake is not confirmed. Push the data onto the queue of data to
363 // resend if statelessly rejected. 316 // resend if statelessly rejected.
364 data_sent_before_handshake_.push_back(data_to_resend); 317 data_sent_before_handshake_.push_back(data_to_resend);
(...skipping 10 matching lines...) Expand all
375 void QuicClient::SendRequestsAndWaitForResponse( 328 void QuicClient::SendRequestsAndWaitForResponse(
376 const vector<string>& url_list) { 329 const vector<string>& url_list) {
377 for (size_t i = 0; i < url_list.size(); ++i) { 330 for (size_t i = 0; i < url_list.size(); ++i) {
378 BalsaHeaders headers; 331 BalsaHeaders headers;
379 headers.SetRequestFirstlineFromStringPieces("GET", url_list[i], "HTTP/1.1"); 332 headers.SetRequestFirstlineFromStringPieces("GET", url_list[i], "HTTP/1.1");
380 SendRequest(headers, "", true); 333 SendRequest(headers, "", true);
381 } 334 }
382 while (WaitForEvents()) {} 335 while (WaitForEvents()) {}
383 } 336 }
384 337
385 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() {
386 if (!connected()) {
387 return nullptr;
388 }
389
390 return session_->CreateOutgoingDynamicStream();
391 }
392
393 void QuicClient::WaitForStreamToClose(QuicStreamId id) {
394 DCHECK(connected());
395
396 while (connected() && !session_->IsClosedStream(id)) {
397 WaitForEvents();
398 }
399 }
400
401 void QuicClient::WaitForCryptoHandshakeConfirmed() {
402 DCHECK(connected());
403
404 while (connected() && !session_->IsCryptoHandshakeConfirmed()) {
405 WaitForEvents();
406 }
407 }
408
409 bool QuicClient::WaitForEvents() { 338 bool QuicClient::WaitForEvents() {
410 DCHECK(connected()); 339 DCHECK(connected());
411 340
412 epoll_server_->WaitForEventsAndExecuteCallbacks(); 341 epoll_server_->WaitForEventsAndExecuteCallbacks();
413 342
414 DCHECK(session_ != nullptr); 343 DCHECK(session() != nullptr);
415 if (!connected() && 344 if (!connected() &&
416 session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { 345 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) {
417 DCHECK(FLAGS_enable_quic_stateless_reject_support); 346 DCHECK(FLAGS_enable_quic_stateless_reject_support);
418 DVLOG(1) << "Detected stateless reject while waiting for events. " 347 DVLOG(1) << "Detected stateless reject while waiting for events. "
419 << "Attempting to reconnect."; 348 << "Attempting to reconnect.";
420 Connect(); 349 Connect();
421 } 350 }
422 351
423 return session_->num_active_requests() != 0; 352 return session()->num_active_requests() != 0;
424 } 353 }
425 354
426 bool QuicClient::MigrateSocket(const IPAddressNumber& new_host) { 355 bool QuicClient::MigrateSocket(const IPAddressNumber& new_host) {
427 if (!connected()) { 356 if (!connected()) {
428 return false; 357 return false;
429 } 358 }
430 359
431 CleanUpUDPSocket(); 360 CleanUpUDPSocket();
432 361
433 bind_to_address_ = new_host; 362 bind_to_address_ = new_host;
434 if (!CreateUDPSocket()) { 363 if (!CreateUDPSocket()) {
435 return false; 364 return false;
436 } 365 }
437 366
438 epoll_server_->RegisterFD(fd_, this, kEpollFlags); 367 epoll_server_->RegisterFD(fd_, this, kEpollFlags);
439 session_->connection()->SetSelfAddress(client_address_); 368 session()->connection()->SetSelfAddress(client_address_);
440 369
441 QuicPacketWriter* writer = CreateQuicPacketWriter(); 370 QuicPacketWriter* writer = CreateQuicPacketWriter();
442 DummyPacketWriterFactory factory(writer); 371 DummyPacketWriterFactory factory(writer);
443 if (writer_.get() != writer) { 372 set_writer(writer);
444 writer_.reset(writer); 373 session()->connection()->SetQuicPacketWriter(writer, false);
445 }
446 session_->connection()->SetQuicPacketWriter(writer, false);
447 374
448 return true; 375 return true;
449 } 376 }
450 377
451 void QuicClient::OnEvent(int fd, EpollEvent* event) { 378 void QuicClient::OnEvent(int fd, EpollEvent* event) {
452 DCHECK_EQ(fd, fd_); 379 DCHECK_EQ(fd, fd_);
453 380
454 if (event->in_events & EPOLLIN) { 381 if (event->in_events & EPOLLIN) {
455 while (connected() && ReadAndProcessPacket()) { 382 while (connected() && ReadAndProcessPacket()) {
456 } 383 }
457 } 384 }
458 if (connected() && (event->in_events & EPOLLOUT)) { 385 if (connected() && (event->in_events & EPOLLOUT)) {
459 writer_->SetWritable(); 386 writer()->SetWritable();
460 session_->connection()->OnCanWrite(); 387 session()->connection()->OnCanWrite();
461 } 388 }
462 if (event->in_events & EPOLLERR) { 389 if (event->in_events & EPOLLERR) {
463 DVLOG(1) << "Epollerr"; 390 DVLOG(1) << "Epollerr";
464 } 391 }
465 } 392 }
466 393
467 void QuicClient::OnClose(QuicDataStream* stream) { 394 void QuicClient::OnClose(QuicDataStream* stream) {
468 DCHECK(stream != nullptr); 395 DCHECK(stream != nullptr);
469 QuicSpdyClientStream* client_stream = 396 QuicSpdyClientStream* client_stream =
470 static_cast<QuicSpdyClientStream*>(stream); 397 static_cast<QuicSpdyClientStream*>(stream);
471 BalsaHeaders headers; 398 BalsaHeaders headers;
472 SpdyBalsaUtils::SpdyHeadersToResponseHeaders(client_stream->headers(), 399 SpdyBalsaUtils::SpdyHeadersToResponseHeaders(client_stream->headers(),
473 &headers, stream->version()); 400 &headers, stream->version());
474 401
475 if (response_listener_.get() != nullptr) { 402 if (response_listener_.get() != nullptr) {
476 response_listener_->OnCompleteResponse( 403 response_listener_->OnCompleteResponse(
477 stream->id(), headers, client_stream->data()); 404 stream->id(), headers, client_stream->data());
478 } 405 }
479 406
480 // Store response headers and body. 407 // Store response headers and body.
481 if (store_response_) { 408 if (store_response_) {
482 latest_response_code_ = headers.parsed_response_code(); 409 latest_response_code_ = headers.parsed_response_code();
483 headers.DumpHeadersToString(&latest_response_headers_); 410 headers.DumpHeadersToString(&latest_response_headers_);
484 latest_response_body_ = client_stream->data(); 411 latest_response_body_ = client_stream->data();
485 } 412 }
486 } 413 }
487 414
488 bool QuicClient::connected() const {
489 return session_.get() && session_->connection() &&
490 session_->connection()->connected();
491 }
492
493 bool QuicClient::goaway_received() const {
494 return session_ != nullptr && session_->goaway_received();
495 }
496
497 size_t QuicClient::latest_response_code() const { 415 size_t QuicClient::latest_response_code() const {
498 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; 416 LOG_IF(DFATAL, !store_response_) << "Response not stored!";
499 return latest_response_code_; 417 return latest_response_code_;
500 } 418 }
501 419
502 const string& QuicClient::latest_response_headers() const { 420 const string& QuicClient::latest_response_headers() const {
503 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; 421 LOG_IF(DFATAL, !store_response_) << "Response not stored!";
504 return latest_response_headers_; 422 return latest_response_headers_;
505 } 423 }
506 424
507 const string& QuicClient::latest_response_body() const { 425 const string& QuicClient::latest_response_body() const {
508 LOG_IF(DFATAL, !store_response_) << "Response not stored!"; 426 LOG_IF(DFATAL, !store_response_) << "Response not stored!";
509 return latest_response_body_; 427 return latest_response_body_;
510 } 428 }
511 429
512 int QuicClient::GetNumSentClientHellos() {
513 // If we are not actively attempting to connect, the session object
514 // corresponds to the previous connection and should not be used.
515 const int current_session_hellos = !connected_or_attempting_connect_
516 ? 0
517 : session_->GetNumSentClientHellos();
518 return num_sent_client_hellos_ + current_session_hellos;
519 }
520
521 QuicErrorCode QuicClient::connection_error() const {
522 // Return the high-level error if there was one. Otherwise, return the
523 // connection error from the last session.
524 if (connection_error_ != QUIC_NO_ERROR) {
525 return connection_error_;
526 }
527 if (session_.get() == nullptr) {
528 return QUIC_NO_ERROR;
529 }
530 return session_->error();
531 }
532
533 QuicConnectionId QuicClient::GetNextConnectionId() {
534 QuicConnectionId server_designated_id = GetNextServerDesignatedConnectionId();
535 return server_designated_id ? server_designated_id
536 : GenerateNewConnectionId();
537 }
538
539 QuicConnectionId QuicClient::GetNextServerDesignatedConnectionId() {
540 QuicCryptoClientConfig::CachedState* cached =
541 crypto_config_.LookupOrCreate(server_id_);
542 // If the cached state indicates that we should use a server-designated
543 // connection ID, then return that connection ID.
544 CHECK(cached != nullptr) << "QuicClientCryptoConfig::LookupOrCreate returned "
545 << "unexpected nullptr.";
546 return cached->has_server_designated_connection_id()
547 ? cached->GetNextServerDesignatedConnectionId()
548 : 0;
549 }
550
551 QuicConnectionId QuicClient::GenerateNewConnectionId() {
552 return QuicRandom::GetInstance()->RandUint64();
553 }
554
555 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { 430 QuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() {
556 return new QuicEpollConnectionHelper(epoll_server_); 431 return new QuicEpollConnectionHelper(epoll_server_);
557 } 432 }
558 433
559 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { 434 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() {
560 return new QuicDefaultPacketWriter(fd_); 435 return new QuicDefaultPacketWriter(fd_);
561 } 436 }
562 437
563 int QuicClient::ReadPacket(char* buffer, 438 int QuicClient::ReadPacket(char* buffer,
564 int buffer_len, 439 int buffer_len,
(...skipping 15 matching lines...) Expand all
580 455
581 int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip); 456 int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip);
582 457
583 if (bytes_read < 0) { 458 if (bytes_read < 0) {
584 return false; 459 return false;
585 } 460 }
586 461
587 QuicEncryptedPacket packet(buf, bytes_read, false); 462 QuicEncryptedPacket packet(buf, bytes_read, false);
588 463
589 IPEndPoint client_address(client_ip, client_address_.port()); 464 IPEndPoint client_address(client_ip, client_address_.port());
590 session_->connection()->ProcessUdpPacket( 465 session()->connection()->ProcessUdpPacket(client_address, server_address,
591 client_address, server_address, packet); 466 packet);
592 return true; 467 return true;
593 } 468 }
594 469
595 } // namespace tools 470 } // namespace tools
596 } // namespace net 471 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698