| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "net/tools/quic/quic_client_message_loop_network_helper.h" | |
| #include <utility> | |
| #include "base/logging.h" | |
| #include "base/run_loop.h" | |
| #include "base/threading/thread_task_runner_handle.h" | |
| #include "net/base/net_errors.h" | |
| #include "net/http/http_request_info.h" | |
| #include "net/http/http_response_info.h" | |
| #include "net/log/net_log_source.h" | |
| #include "net/log/net_log_with_source.h" | |
| #include "net/quic/quic_chromium_alarm_factory.h" | |
| #include "net/quic/quic_chromium_connection_helper.h" | |
| #include "net/quic/quic_chromium_packet_reader.h" | |
| #include "net/quic/quic_chromium_packet_writer.h" | |
| #include "net/socket/udp_client_socket.h" | |
| #include "net/spdy/spdy_http_utils.h" | |
| #include "net/third_party/quic/core/crypto/quic_random.h" | |
| #include "net/third_party/quic/core/http/spdy_utils.h" | |
| #include "net/third_party/quic/core/quic_connection.h" | |
| #include "net/third_party/quic/core/quic_packets.h" | |
| #include "net/third_party/quic/core/quic_server_id.h" | |
| #include "net/third_party/quic/platform/api/quic_flags.h" | |
| #include "net/third_party/quic/platform/api/quic_ptr_util.h" | |
| #include "net/third_party/quiche/src/spdy/core/spdy_header_block.h" | |
| using std::string; | |
| namespace net { | |
| QuicClientMessageLooplNetworkHelper::QuicClientMessageLooplNetworkHelper( | |
| quic::QuicChromiumClock* clock, | |
| quic::QuicClientBase* client) | |
| : packet_reader_started_(false), clock_(clock), client_(client) {} | |
| QuicClientMessageLooplNetworkHelper::~QuicClientMessageLooplNetworkHelper() = | |
| default; | |
| bool QuicClientMessageLooplNetworkHelper::CreateUDPSocketAndBind( | |
| quic::QuicSocketAddress server_address, | |
| quic::QuicIpAddress bind_to_address, | |
| int bind_to_port) { | |
| auto socket = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND, | |
| &net_log_, NetLogSource()); | |
| if (bind_to_address.IsInitialized()) { | |
| client_address_ = | |
| quic::QuicSocketAddress(bind_to_address, client_->local_port()); | |
| } else if (server_address.host().address_family() == | |
| quic::IpAddressFamily::IP_V4) { | |
| client_address_ = | |
| quic::QuicSocketAddress(quic::QuicIpAddress::Any4(), bind_to_port); | |
| } else { | |
| client_address_ = | |
| quic::QuicSocketAddress(quic::QuicIpAddress::Any6(), bind_to_port); | |
| } | |
| int rc = socket->Connect(server_address.impl().socket_address()); | |
| if (rc != OK) { | |
| LOG(ERROR) << "Connect failed: " << ErrorToShortString(rc); | |
| return false; | |
| } | |
| rc = socket->SetReceiveBufferSize(quic::kDefaultSocketReceiveBuffer); | |
| if (rc != OK) { | |
| LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToShortString(rc); | |
| return false; | |
| } | |
| rc = socket->SetSendBufferSize(quic::kDefaultSocketReceiveBuffer); | |
| if (rc != OK) { | |
| LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToShortString(rc); | |
| return false; | |
| } | |
| IPEndPoint address; | |
| rc = socket->GetLocalAddress(&address); | |
| if (rc != OK) { | |
| LOG(ERROR) << "GetLocalAddress failed: " << ErrorToShortString(rc); | |
| return false; | |
| } | |
| client_address_ = | |
| quic::QuicSocketAddress(quic::QuicSocketAddressImpl(address)); | |
| socket_.swap(socket); | |
| packet_reader_.reset(new QuicChromiumPacketReader( | |
| socket_.get(), clock_, this, kQuicYieldAfterPacketsRead, | |
| quic::QuicTime::Delta::FromMilliseconds( | |
| kQuicYieldAfterDurationMilliseconds), | |
| NetLogWithSource())); | |
| if (socket != nullptr) { | |
| socket->Close(); | |
| } | |
| return true; | |
| } | |
| void QuicClientMessageLooplNetworkHelper::CleanUpAllUDPSockets() { | |
| client_->reset_writer(); | |
| packet_reader_.reset(); | |
| packet_reader_started_ = false; | |
| } | |
| void QuicClientMessageLooplNetworkHelper::StartPacketReaderIfNotStarted() { | |
| if (!packet_reader_started_) { | |
| packet_reader_->StartReading(); | |
| packet_reader_started_ = true; | |
| } | |
| } | |
| void QuicClientMessageLooplNetworkHelper::RunEventLoop() { | |
| StartPacketReaderIfNotStarted(); | |
| base::RunLoop().RunUntilIdle(); | |
| } | |
| quic::QuicPacketWriter* | |
| QuicClientMessageLooplNetworkHelper::CreateQuicPacketWriter() { | |
| return new QuicChromiumPacketWriter( | |
| socket_.get(), base::ThreadTaskRunnerHandle::Get().get()); | |
| } | |
| void QuicClientMessageLooplNetworkHelper::OnReadError( | |
| int result, | |
| const DatagramClientSocket* socket) { | |
| LOG(ERROR) << "QuicSimpleClient read failed: " << ErrorToShortString(result); | |
| client_->Disconnect(); | |
| } | |
| quic::QuicSocketAddress | |
| QuicClientMessageLooplNetworkHelper::GetLatestClientAddress() const { | |
| return client_address_; | |
| } | |
| bool QuicClientMessageLooplNetworkHelper::OnPacket( | |
| const quic::QuicReceivedPacket& packet, | |
| const quic::QuicSocketAddress& local_address, | |
| const quic::QuicSocketAddress& peer_address) { | |
| client_->session()->connection()->ProcessUdpPacket(local_address, | |
| peer_address, packet); | |
| if (!client_->session()->connection()->connected()) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| } // namespace net |