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_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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 const QuicConfig& config, | 62 const QuicConfig& config, |
63 EpollServer* epoll_server, | 63 EpollServer* epoll_server, |
64 std::unique_ptr<ProofVerifier> proof_verifier) | 64 std::unique_ptr<ProofVerifier> proof_verifier) |
65 : QuicClientBase( | 65 : QuicClientBase( |
66 server_id, | 66 server_id, |
67 supported_versions, | 67 supported_versions, |
68 config, | 68 config, |
69 new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE), | 69 new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE), |
70 new QuicEpollAlarmFactory(epoll_server), | 70 new QuicEpollAlarmFactory(epoll_server), |
71 std::move(proof_verifier)), | 71 std::move(proof_verifier)), |
72 server_address_(server_address), | |
73 local_port_(0), | |
74 epoll_server_(epoll_server), | 72 epoll_server_(epoll_server), |
75 initialized_(false), | 73 initialized_(false), |
76 packets_dropped_(0), | 74 packets_dropped_(0), |
77 overflow_supported_(false), | 75 overflow_supported_(false), |
78 store_response_(false), | 76 packet_reader_(new QuicPacketReader()) { |
79 latest_response_code_(-1), | 77 set_server_address(server_address); |
80 packet_reader_(new QuicPacketReader()) {} | 78 } |
81 | 79 |
82 QuicClient::~QuicClient() { | 80 QuicClient::~QuicClient() { |
83 if (connected()) { | 81 if (connected()) { |
84 session()->connection()->CloseConnection( | 82 session()->connection()->CloseConnection( |
85 QUIC_PEER_GOING_AWAY, "Client being torn down", | 83 QUIC_PEER_GOING_AWAY, "Client being torn down", |
86 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); | 84 ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); |
87 } | 85 } |
88 | 86 |
89 CleanUpAllUDPSockets(); | 87 CleanUpAllUDPSockets(); |
90 } | 88 } |
(...skipping 25 matching lines...) Expand all Loading... |
116 return false; | 114 return false; |
117 } | 115 } |
118 | 116 |
119 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); | 117 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); |
120 initialized_ = true; | 118 initialized_ = true; |
121 return true; | 119 return true; |
122 } | 120 } |
123 | 121 |
124 bool QuicClient::CreateUDPSocketAndBind() { | 122 bool QuicClient::CreateUDPSocketAndBind() { |
125 int fd = | 123 int fd = |
126 QuicSocketUtils::CreateUDPSocket(server_address_, &overflow_supported_); | 124 QuicSocketUtils::CreateUDPSocket(server_address(), &overflow_supported_); |
127 if (fd < 0) { | 125 if (fd < 0) { |
128 return false; | 126 return false; |
129 } | 127 } |
130 | 128 |
131 IPEndPoint client_address; | 129 IPEndPoint client_address; |
132 if (bind_to_address_.size() != 0) { | 130 if (bind_to_address().size() != 0) { |
133 client_address = IPEndPoint(bind_to_address_, local_port_); | 131 client_address = IPEndPoint(bind_to_address(), local_port()); |
134 } else if (server_address_.GetSockAddrFamily() == AF_INET) { | 132 } else if (server_address().GetSockAddrFamily() == AF_INET) { |
135 client_address = IPEndPoint(IPAddress::IPv4AllZeros(), local_port_); | 133 client_address = IPEndPoint(IPAddress::IPv4AllZeros(), local_port()); |
136 } else { | 134 } else { |
137 IPAddress any6 = IPAddress::IPv6AllZeros(); | 135 IPAddress any6 = IPAddress::IPv6AllZeros(); |
138 client_address = IPEndPoint(any6, local_port_); | 136 client_address = IPEndPoint(any6, local_port()); |
139 } | 137 } |
140 | 138 |
141 sockaddr_storage raw_addr; | 139 sockaddr_storage raw_addr; |
142 socklen_t raw_addr_len = sizeof(raw_addr); | 140 socklen_t raw_addr_len = sizeof(raw_addr); |
143 CHECK(client_address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), | 141 CHECK(client_address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), |
144 &raw_addr_len)); | 142 &raw_addr_len)); |
145 int rc = | 143 int rc = |
146 bind(fd, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr)); | 144 bind(fd, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr)); |
147 if (rc < 0) { | 145 if (rc < 0) { |
148 LOG(ERROR) << "Bind failed: " << strerror(errno); | 146 LOG(ERROR) << "Bind failed: " << strerror(errno); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 // does not need to be resent. | 199 // does not need to be resent. |
202 if (session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { | 200 if (session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
203 ClearDataToResend(); | 201 ClearDataToResend(); |
204 } | 202 } |
205 // Before we destroy the last session and create a new one, gather its stats | 203 // Before we destroy the last session and create a new one, gather its stats |
206 // and update the stats for the overall connection. | 204 // and update the stats for the overall connection. |
207 UpdateStats(); | 205 UpdateStats(); |
208 } | 206 } |
209 | 207 |
210 CreateQuicClientSession(new QuicConnection( | 208 CreateQuicClientSession(new QuicConnection( |
211 GetNextConnectionId(), server_address_, helper(), alarm_factory(), writer, | 209 GetNextConnectionId(), server_address(), helper(), alarm_factory(), |
| 210 writer, |
212 /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions())); | 211 /* owns_writer= */ false, Perspective::IS_CLIENT, supported_versions())); |
213 | 212 |
214 // Reset |writer()| after |session()| so that the old writer outlives the old | 213 // Reset |writer()| after |session()| so that the old writer outlives the old |
215 // session. | 214 // session. |
216 set_writer(writer); | 215 set_writer(writer); |
217 session()->Initialize(); | 216 session()->Initialize(); |
218 session()->CryptoConnect(); | 217 session()->CryptoConnect(); |
219 set_connected_or_attempting_connect(true); | 218 set_connected_or_attempting_connect(true); |
220 } | 219 } |
221 | 220 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) { | 293 if (!SpdyUtils::PopulateHeaderBlockFromUrl(url_list[i], &headers)) { |
295 QUIC_BUG << "Unable to create request"; | 294 QUIC_BUG << "Unable to create request"; |
296 continue; | 295 continue; |
297 } | 296 } |
298 SendRequest(headers, "", true); | 297 SendRequest(headers, "", true); |
299 } | 298 } |
300 while (WaitForEvents()) { | 299 while (WaitForEvents()) { |
301 } | 300 } |
302 } | 301 } |
303 | 302 |
304 QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { | |
305 QuicSpdyClientStream* stream = QuicClientBase::CreateReliableClientStream(); | |
306 if (stream) { | |
307 stream->set_visitor(this); | |
308 } | |
309 return stream; | |
310 } | |
311 | |
312 bool QuicClient::WaitForEvents() { | 303 bool QuicClient::WaitForEvents() { |
313 DCHECK(connected()); | 304 DCHECK(connected()); |
314 | 305 |
315 epoll_server_->WaitForEventsAndExecuteCallbacks(); | 306 epoll_server_->WaitForEventsAndExecuteCallbacks(); |
316 base::RunLoop().RunUntilIdle(); | 307 base::RunLoop().RunUntilIdle(); |
317 | 308 |
318 DCHECK(session() != nullptr); | 309 DCHECK(session() != nullptr); |
319 if (!connected() && | 310 if (!connected() && |
320 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { | 311 session()->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
321 DCHECK(FLAGS_enable_quic_stateless_reject_support); | 312 DCHECK(FLAGS_enable_quic_stateless_reject_support); |
322 DVLOG(1) << "Detected stateless reject while waiting for events. " | 313 DVLOG(1) << "Detected stateless reject while waiting for events. " |
323 << "Attempting to reconnect."; | 314 << "Attempting to reconnect."; |
324 Connect(); | 315 Connect(); |
325 } | 316 } |
326 | 317 |
327 return session()->num_active_requests() != 0; | 318 return session()->num_active_requests() != 0; |
328 } | 319 } |
329 | 320 |
330 bool QuicClient::MigrateSocket(const IPAddress& new_host) { | 321 bool QuicClient::MigrateSocket(const IPAddress& new_host) { |
331 if (!connected()) { | 322 if (!connected()) { |
332 return false; | 323 return false; |
333 } | 324 } |
334 | 325 |
335 CleanUpUDPSocket(GetLatestFD()); | 326 CleanUpUDPSocket(GetLatestFD()); |
336 | 327 |
337 bind_to_address_ = new_host; | 328 set_bind_to_address(new_host); |
338 if (!CreateUDPSocketAndBind()) { | 329 if (!CreateUDPSocketAndBind()) { |
339 return false; | 330 return false; |
340 } | 331 } |
341 | 332 |
342 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); | 333 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); |
343 session()->connection()->SetSelfAddress(GetLatestClientAddress()); | 334 session()->connection()->SetSelfAddress(GetLatestClientAddress()); |
344 | 335 |
345 QuicPacketWriter* writer = CreateQuicPacketWriter(); | 336 QuicPacketWriter* writer = CreateQuicPacketWriter(); |
346 set_writer(writer); | 337 set_writer(writer); |
347 session()->connection()->SetQuicPacketWriter(writer, false); | 338 session()->connection()->SetQuicPacketWriter(writer, false); |
(...skipping 15 matching lines...) Expand all Loading... |
363 } | 354 } |
364 if (connected() && (event->in_events & EPOLLOUT)) { | 355 if (connected() && (event->in_events & EPOLLOUT)) { |
365 writer()->SetWritable(); | 356 writer()->SetWritable(); |
366 session()->connection()->OnCanWrite(); | 357 session()->connection()->OnCanWrite(); |
367 } | 358 } |
368 if (event->in_events & EPOLLERR) { | 359 if (event->in_events & EPOLLERR) { |
369 DVLOG(1) << "Epollerr"; | 360 DVLOG(1) << "Epollerr"; |
370 } | 361 } |
371 } | 362 } |
372 | 363 |
373 void QuicClient::OnClose(QuicSpdyStream* stream) { | |
374 DCHECK(stream != nullptr); | |
375 QuicSpdyClientStream* client_stream = | |
376 static_cast<QuicSpdyClientStream*>(stream); | |
377 | |
378 const SpdyHeaderBlock& response_headers = client_stream->response_headers(); | |
379 if (response_listener_.get() != nullptr) { | |
380 response_listener_->OnCompleteResponse(stream->id(), response_headers, | |
381 client_stream->data()); | |
382 } | |
383 | |
384 // Store response headers and body. | |
385 if (store_response_) { | |
386 auto status = response_headers.find(":status"); | |
387 if (status == response_headers.end() || | |
388 !StringToInt(status->second, &latest_response_code_)) { | |
389 LOG(ERROR) << "Invalid response headers: no status code"; | |
390 } | |
391 latest_response_headers_ = response_headers.DebugString(); | |
392 latest_response_header_block_ = response_headers.Clone(); | |
393 latest_response_body_ = client_stream->data(); | |
394 latest_response_trailers_ = | |
395 client_stream->received_trailers().DebugString(); | |
396 } | |
397 } | |
398 | |
399 size_t QuicClient::latest_response_code() const { | |
400 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | |
401 return latest_response_code_; | |
402 } | |
403 | |
404 const string& QuicClient::latest_response_headers() const { | |
405 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | |
406 return latest_response_headers_; | |
407 } | |
408 | |
409 const SpdyHeaderBlock& QuicClient::latest_response_header_block() const { | |
410 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | |
411 return latest_response_header_block_; | |
412 } | |
413 | |
414 const string& QuicClient::latest_response_body() const { | |
415 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | |
416 return latest_response_body_; | |
417 } | |
418 | |
419 const string& QuicClient::latest_response_trailers() const { | |
420 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | |
421 return latest_response_trailers_; | |
422 } | |
423 | |
424 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { | 364 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { |
425 return new QuicDefaultPacketWriter(GetLatestFD()); | 365 return new QuicDefaultPacketWriter(GetLatestFD()); |
426 } | 366 } |
427 | 367 |
428 const IPEndPoint QuicClient::GetLatestClientAddress() const { | 368 const IPEndPoint QuicClient::GetLatestClientAddress() const { |
429 if (fd_address_map_.empty()) { | 369 if (fd_address_map_.empty()) { |
430 return IPEndPoint(); | 370 return IPEndPoint(); |
431 } | 371 } |
432 | 372 |
433 return fd_address_map_.back().second; | 373 return fd_address_map_.back().second; |
434 } | 374 } |
435 | 375 |
436 int QuicClient::GetLatestFD() const { | 376 int QuicClient::GetLatestFD() const { |
437 if (fd_address_map_.empty()) { | 377 if (fd_address_map_.empty()) { |
438 return -1; | 378 return -1; |
439 } | 379 } |
440 | 380 |
441 return fd_address_map_.back().first; | 381 return fd_address_map_.back().first; |
442 } | 382 } |
443 | 383 |
444 void QuicClient::ProcessPacket(const IPEndPoint& self_address, | 384 void QuicClient::ProcessPacket(const IPEndPoint& self_address, |
445 const IPEndPoint& peer_address, | 385 const IPEndPoint& peer_address, |
446 const QuicReceivedPacket& packet) { | 386 const QuicReceivedPacket& packet) { |
447 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); | 387 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); |
448 } | 388 } |
449 | 389 |
450 } // namespace net | 390 } // namespace net |
OLD | NEW |