1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_QUIC_QUIC_TRANSPORT_CLIENT_H_
6 #define NET_QUIC_QUIC_TRANSPORT_CLIENT_H_
7 
8 #include "base/memory/weak_ptr.h"
9 #include "net/base/network_isolation_key.h"
10 #include "net/dns/host_resolver.h"
11 #include "net/log/net_log_with_source.h"
12 #include "net/proxy_resolution/proxy_info.h"
13 #include "net/quic/quic_chromium_packet_reader.h"
14 #include "net/quic/quic_chromium_packet_writer.h"
15 #include "net/quic/quic_context.h"
16 #include "net/quic/quic_event_logger.h"
17 #include "net/quic/quic_transport_error.h"
18 #include "net/socket/client_socket_factory.h"
19 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
20 #include "net/third_party/quiche/src/quic/core/quic_config.h"
21 #include "net/third_party/quiche/src/quic/core/quic_versions.h"
22 #include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
23 #include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
24 #include "url/gurl.h"
25 #include "url/origin.h"
26 
27 namespace net {
28 
29 class ProxyResolutionRequest;
30 class QuicChromiumAlarmFactory;
31 class URLRequestContext;
32 
33 // QuicTransportClient is the top-level API for QuicTransport in //net.
34 class NET_EXPORT QuicTransportClient
35     : public quic::QuicTransportClientSession::ClientVisitor,
36       public QuicChromiumPacketReader::Visitor,
37       public QuicChromiumPacketWriter::Delegate,
38       public quic::QuicSession::Visitor {
39  public:
40   //
41   // Diagram of allowed state transitions:
42   //
43   //    NEW -> CONNECTING -> CONNECTED -> CLOSED
44   //              |                |
45   //              |                |
46   //              +---> FAILED <---+
47   //
48   // These values are logged to UMA. Entries should not be renumbered and
49   // numeric values should never be reused. Please keep in sync with
50   // "QuicTransportClientState" in src/tools/metrics/histograms/enums.xml.
51   enum State {
52     // The client object has been created but Connect() has not been called.
53     NEW,
54     // Connection establishment is in progress.  No application data can be sent
55     // or received at this point.
56     CONNECTING,
57     // The connection has been established and application data can be sent and
58     // received.
59     CONNECTED,
60     // The connection has been closed gracefully by either endpoint.
61     CLOSED,
62     // The connection has been closed abruptly.
63     FAILED,
64 
65     // Total number of possible states.
66     NUM_STATES,
67   };
68 
69   class NET_EXPORT Visitor {
70    public:
71     virtual ~Visitor();
72 
73     // State change notifiers.
74     virtual void OnConnected() = 0;         // CONNECTING -> CONNECTED
75     virtual void OnConnectionFailed() = 0;  // CONNECTING -> FAILED
76     virtual void OnClosed() = 0;            // CONNECTED -> CLOSED
77     virtual void OnError() = 0;             // CONNECTED -> FAILED
78 
79     virtual void OnIncomingBidirectionalStreamAvailable() = 0;
80     virtual void OnIncomingUnidirectionalStreamAvailable() = 0;
81     virtual void OnDatagramReceived(base::StringPiece datagram) = 0;
82     virtual void OnCanCreateNewOutgoingBidirectionalStream() = 0;
83     virtual void OnCanCreateNewOutgoingUnidirectionalStream() = 0;
84   };
85 
86   struct NET_EXPORT Parameters {
87     Parameters();
88     ~Parameters();
89     Parameters(const Parameters&);
90     Parameters(Parameters&&);
91 
92     // A vector of fingerprints for expected server certificates, as described
93     // in
94     // https://wicg.github.io/web-transport/#dom-quictransportconfiguration-server_certificate_fingerprints
95     // When empty, Web PKI is used.
96     std::vector<quic::CertificateFingerprint> server_certificate_fingerprints;
97   };
98 
99   // QUIC protocol versions that are used in the origin trial.
100   static quic::ParsedQuicVersionVector
QuicVersionsForWebTransportOriginTrial()101   QuicVersionsForWebTransportOriginTrial() {
102     return quic::ParsedQuicVersionVector{
103         quic::ParsedQuicVersion::Draft29(),  // Enabled in M85.
104         quic::ParsedQuicVersion::Draft27()   // Enabled in M84.
105     };
106   }
107 
108   // |visitor| and |context| must outlive this object.
109   QuicTransportClient(const GURL& url,
110                       const url::Origin& origin,
111                       Visitor* visitor,
112                       const NetworkIsolationKey& isolation_key,
113                       URLRequestContext* context,
114                       const Parameters& parameters);
115   ~QuicTransportClient() override;
116 
state()117   State state() const { return state_; }
error()118   const QuicTransportError& error() const { return error_; }
119 
120   // Connect() is an asynchronous operation.  Once the operation is finished,
121   // OnConnected() or OnConnectionFailed() is called on the Visitor.
122   void Connect();
123 
124   quic::QuicTransportClientSession* session();
125 
126   // QuicTransportClientSession::ClientVisitor methods.
127   void OnSessionReady() override;
128   void OnIncomingBidirectionalStreamAvailable() override;
129   void OnIncomingUnidirectionalStreamAvailable() override;
130   void OnDatagramReceived(absl::string_view datagram) override;
131   void OnCanCreateNewOutgoingBidirectionalStream() override;
132   void OnCanCreateNewOutgoingUnidirectionalStream() override;
133 
134   // QuicChromiumPacketReader::Visitor methods.
135   void OnReadError(int result, const DatagramClientSocket* socket) override;
136   bool OnPacket(const quic::QuicReceivedPacket& packet,
137                 const quic::QuicSocketAddress& local_address,
138                 const quic::QuicSocketAddress& peer_address) override;
139 
140   // QuicChromiumPacketWriter::Delegate methods.
141   int HandleWriteError(int error_code,
142                        scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer>
143                            last_packet) override;
144   void OnWriteError(int error_code) override;
145   void OnWriteUnblocked() override;
146 
147   // QuicSession::Visitor methods.
148   void OnConnectionClosed(quic::QuicConnectionId server_connection_id,
149                           quic::QuicErrorCode error,
150                           const std::string& error_details,
151                           quic::ConnectionCloseSource source) override;
OnWriteBlocked(quic::QuicBlockedWriterInterface *)152   void OnWriteBlocked(
153       quic::QuicBlockedWriterInterface* /*blocked_writer*/) override {}
OnRstStreamReceived(const quic::QuicRstStreamFrame &)154   void OnRstStreamReceived(const quic::QuicRstStreamFrame& /*frame*/) override {
155   }
OnStopSendingReceived(const quic::QuicStopSendingFrame &)156   void OnStopSendingReceived(
157       const quic::QuicStopSendingFrame& /*frame*/) override {}
158 
159  private:
160   // State of the connection establishment process.
161   //
162   // These values are logged to UMA. Entries should not be renumbered and
163   // numeric values should never be reused. Please keep in sync with
164   // "QuicTransportClientConnectState" in
165   // src/tools/metrics/histograms/enums.xml.
166   enum ConnectState {
167     CONNECT_STATE_NONE,
168     CONNECT_STATE_INIT,
169     CONNECT_STATE_CHECK_PROXY,
170     CONNECT_STATE_CHECK_PROXY_COMPLETE,
171     CONNECT_STATE_RESOLVE_HOST,
172     CONNECT_STATE_RESOLVE_HOST_COMPLETE,
173     CONNECT_STATE_CONNECT,
174     CONNECT_STATE_CONFIRM_CONNECTION,
175 
176     CONNECT_STATE_NUM_STATES,
177   };
178 
179   // DoLoop processing the Connect() call.
180   void DoLoop(int rv);
181   // Verifies the basic preconditions for setting up the connection.
182   int DoInit();
183   // Verifies that there is no mandatory proxy configured for the specified URL.
184   int DoCheckProxy();
185   int DoCheckProxyComplete(int rv);
186   // Resolves the hostname in the URL.
187   int DoResolveHost();
188   int DoResolveHostComplete(int rv);
189   // Establishes the QUIC connection.
190   int DoConnect();
191   void CreateConnection();
192   // Verifies that the connection has succeeded.
193   int DoConfirmConnection();
194 
195   void TransitionToState(State next_state);
196 
197   const GURL url_;
198   const url::Origin origin_;
199   const NetworkIsolationKey isolation_key_;
200   URLRequestContext* const context_;  // Unowned.
201   Visitor* const visitor_;            // Unowned.
202 
203   ClientSocketFactory* const client_socket_factory_;
204   QuicContext* const quic_context_;
205   NetLogWithSource net_log_;
206   base::SequencedTaskRunner* task_runner_;
207 
208   quic::ParsedQuicVersionVector supported_versions_;
209   // TODO(vasilvv): move some of those into QuicContext.
210   std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
211   quic::QuicCryptoClientConfig crypto_config_;
212 
213   State state_ = NEW;
214   ConnectState next_connect_state_ = CONNECT_STATE_NONE;
215   QuicTransportError error_;
216   bool retried_with_new_version_ = false;
217 
218   ProxyInfo proxy_info_;
219   std::unique_ptr<ProxyResolutionRequest> proxy_resolution_request_;
220   std::unique_ptr<HostResolver::ResolveHostRequest> resolve_host_request_;
221 
222   std::unique_ptr<DatagramClientSocket> socket_;
223   std::unique_ptr<quic::QuicConnection> connection_;
224   std::unique_ptr<quic::QuicTransportClientSession> session_;
225   std::unique_ptr<QuicChromiumPacketReader> packet_reader_;
226   std::unique_ptr<QuicEventLogger> event_logger_;
227 
228   base::WeakPtrFactory<QuicTransportClient> weak_factory_{this};
229 };
230 
231 }  // namespace net
232 
233 #endif  // NET_QUIC_QUIC_TRANSPORT_CLIENT_H_
234