xref: /aosp_15_r20/external/cronet/net/tools/quic/quic_client_message_loop_network_helper.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/tools/quic/quic_client_message_loop_network_helper.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/logging.h"
11 #include "base/run_loop.h"
12 #include "base/task/single_thread_task_runner.h"
13 #include "net/base/net_errors.h"
14 #include "net/http/http_request_info.h"
15 #include "net/http/http_response_info.h"
16 #include "net/log/net_log_source.h"
17 #include "net/log/net_log_with_source.h"
18 #include "net/quic/address_utils.h"
19 #include "net/quic/quic_chromium_alarm_factory.h"
20 #include "net/quic/quic_chromium_connection_helper.h"
21 #include "net/quic/quic_chromium_packet_reader.h"
22 #include "net/quic/quic_chromium_packet_writer.h"
23 #include "net/socket/udp_client_socket.h"
24 #include "net/spdy/spdy_http_utils.h"
25 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_random.h"
26 #include "net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.h"
27 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
28 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
29 #include "net/third_party/quiche/src/quiche/quic/core/quic_server_id.h"
30 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
31 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
32 
33 using std::string;
34 
35 namespace net {
36 
QuicClientMessageLooplNetworkHelper(quic::QuicChromiumClock * clock,quic::QuicClientBase * client)37 QuicClientMessageLooplNetworkHelper::QuicClientMessageLooplNetworkHelper(
38     quic::QuicChromiumClock* clock,
39     quic::QuicClientBase* client)
40     : clock_(clock), client_(client) {}
41 
42 QuicClientMessageLooplNetworkHelper::~QuicClientMessageLooplNetworkHelper() =
43     default;
44 
CreateUDPSocketAndBind(quic::QuicSocketAddress server_address,quic::QuicIpAddress bind_to_address,int bind_to_port)45 bool QuicClientMessageLooplNetworkHelper::CreateUDPSocketAndBind(
46     quic::QuicSocketAddress server_address,
47     quic::QuicIpAddress bind_to_address,
48     int bind_to_port) {
49   auto socket = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND,
50                                                   nullptr, NetLogSource());
51 
52   if (bind_to_address.IsInitialized()) {
53     client_address_ =
54         quic::QuicSocketAddress(bind_to_address, client_->local_port());
55   } else if (server_address.host().address_family() ==
56              quiche::IpAddressFamily::IP_V4) {
57     client_address_ =
58         quic::QuicSocketAddress(quic::QuicIpAddress::Any4(), bind_to_port);
59   } else {
60     client_address_ =
61         quic::QuicSocketAddress(quic::QuicIpAddress::Any6(), bind_to_port);
62   }
63 
64   int rc = socket->Connect(ToIPEndPoint(server_address));
65   if (rc != OK) {
66     LOG(ERROR) << "Connect failed: " << ErrorToShortString(rc);
67     return false;
68   }
69 
70   rc = socket->SetReceiveBufferSize(quic::kDefaultSocketReceiveBuffer);
71   if (rc != OK) {
72     LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToShortString(rc);
73     return false;
74   }
75 
76   rc = socket->SetSendBufferSize(quic::kDefaultSocketReceiveBuffer);
77   if (rc != OK) {
78     LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToShortString(rc);
79     return false;
80   }
81 
82   IPEndPoint address;
83   rc = socket->GetLocalAddress(&address);
84   if (rc != OK) {
85     LOG(ERROR) << "GetLocalAddress failed: " << ErrorToShortString(rc);
86     return false;
87   }
88   client_address_ = ToQuicSocketAddress(address);
89 
90   socket_.swap(socket);
91   packet_reader_ = std::make_unique<QuicChromiumPacketReader>(
92       std::move(socket_), clock_, this, kQuicYieldAfterPacketsRead,
93       quic::QuicTime::Delta::FromMilliseconds(
94           kQuicYieldAfterDurationMilliseconds),
95       NetLogWithSource());
96 
97   if (socket != nullptr) {
98     socket->Close();
99   }
100 
101   return true;
102 }
103 
CleanUpAllUDPSockets()104 void QuicClientMessageLooplNetworkHelper::CleanUpAllUDPSockets() {
105   client_->reset_writer();
106   packet_reader_.reset();
107   packet_reader_started_ = false;
108 }
109 
StartPacketReaderIfNotStarted()110 void QuicClientMessageLooplNetworkHelper::StartPacketReaderIfNotStarted() {
111   if (!packet_reader_started_) {
112     packet_reader_->StartReading();
113     packet_reader_started_ = true;
114   }
115 }
116 
RunEventLoop()117 void QuicClientMessageLooplNetworkHelper::RunEventLoop() {
118   StartPacketReaderIfNotStarted();
119   base::RunLoop().RunUntilIdle();
120 }
121 
122 quic::QuicPacketWriter*
CreateQuicPacketWriter()123 QuicClientMessageLooplNetworkHelper::CreateQuicPacketWriter() {
124   // This is always called once per QuicSession before
125   // StartPacketReaderIfNotStarted. However if the QuicClient is creating
126   // multiple sessions it needs to restart the packet reader for the second one
127   // so we set packet_reader_started_ to false to ensure that.
128   packet_reader_started_ = false;
129 
130   return new QuicChromiumPacketWriter(
131       packet_reader_->socket(),
132       base::SingleThreadTaskRunner::GetCurrentDefault().get());
133 }
134 
OnReadError(int result,const DatagramClientSocket * socket)135 bool QuicClientMessageLooplNetworkHelper::OnReadError(
136     int result,
137     const DatagramClientSocket* socket) {
138   LOG(ERROR) << "QuicSimpleClient read failed: " << ErrorToShortString(result);
139   client_->Disconnect();
140   return false;
141 }
142 
143 quic::QuicSocketAddress
GetLatestClientAddress() const144 QuicClientMessageLooplNetworkHelper::GetLatestClientAddress() const {
145   return client_address_;
146 }
147 
OnPacket(const quic::QuicReceivedPacket & packet,const quic::QuicSocketAddress & local_address,const quic::QuicSocketAddress & peer_address)148 bool QuicClientMessageLooplNetworkHelper::OnPacket(
149     const quic::QuicReceivedPacket& packet,
150     const quic::QuicSocketAddress& local_address,
151     const quic::QuicSocketAddress& peer_address) {
152   client_->session()->connection()->ProcessUdpPacket(local_address,
153                                                      peer_address, packet);
154   if (!client_->session()->connection()->connected()) {
155     return false;
156   }
157 
158   return true;
159 }
160 
161 }  // namespace net
162