summaryrefslogtreecommitdiff
path: root/chromium/net/quic/quic_transport_client.h
blob: 7bd9ecdc9c7898a6ff987ee854192107ff9103f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright 2019 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.

#ifndef NET_QUIC_QUIC_TRANSPORT_CLIENT_H_
#define NET_QUIC_QUIC_TRANSPORT_CLIENT_H_

#include "base/memory/weak_ptr.h"
#include "net/base/network_isolation_key.h"
#include "net/dns/host_resolver.h"
#include "net/log/net_log_with_source.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/quic/quic_chromium_packet_reader.h"
#include "net/quic/quic_chromium_packet_writer.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_event_logger.h"
#include "net/quic/web_transport_client.h"
#include "net/quic/web_transport_error.h"
#include "net/socket/client_socket_factory.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
#include "net/third_party/quiche/src/quic/core/quic_config.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/core/web_transport_interface.h"
#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
#include "net/third_party/quiche/src/quic/quic_transport/web_transport_fingerprint_proof_verifier.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {

class ProxyResolutionRequest;
class QuicChromiumAlarmFactory;
class URLRequestContext;

// QuicTransportClient is the top-level API for QuicTransport in //net.
class NET_EXPORT QuicTransportClient
    : public WebTransportClient,
      public quic::WebTransportVisitor,
      public QuicChromiumPacketReader::Visitor,
      public QuicChromiumPacketWriter::Delegate,
      public quic::QuicSession::Visitor {
 public:
  // QUIC protocol versions that are used in the origin trial.
  static quic::ParsedQuicVersionVector
  QuicVersionsForWebTransportOriginTrial() {
    return quic::ParsedQuicVersionVector{
        quic::ParsedQuicVersion::Draft29(),  // Enabled in M85
    };
  }

  // |visitor| and |context| must outlive this object.
  QuicTransportClient(const GURL& url,
                      const url::Origin& origin,
                      WebTransportClientVisitor* visitor,
                      const NetworkIsolationKey& isolation_key,
                      URLRequestContext* context,
                      const WebTransportParameters& parameters);
  ~QuicTransportClient() override;

  WebTransportState state() const { return state_; }
  const WebTransportError& error() const override;

  // Connect() is an asynchronous operation.  Once the operation is finished,
  // OnConnected() or OnConnectionFailed() is called on the Visitor.
  void Connect() override;

  quic::WebTransportSession* session() override;
  quic::QuicTransportClientSession* quic_session();

  // QuicTransportClientSession::ClientVisitor methods.
  void OnSessionReady() override;
  void OnIncomingBidirectionalStreamAvailable() override;
  void OnIncomingUnidirectionalStreamAvailable() override;
  void OnDatagramReceived(absl::string_view datagram) override;
  void OnCanCreateNewOutgoingBidirectionalStream() override;
  void OnCanCreateNewOutgoingUnidirectionalStream() override;

  // QuicChromiumPacketReader::Visitor methods.
  bool OnReadError(int result, const DatagramClientSocket* socket) override;
  bool OnPacket(const quic::QuicReceivedPacket& packet,
                const quic::QuicSocketAddress& local_address,
                const quic::QuicSocketAddress& peer_address) override;

  // QuicChromiumPacketWriter::Delegate methods.
  int HandleWriteError(int error_code,
                       scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer>
                           last_packet) override;
  void OnWriteError(int error_code) override;
  void OnWriteUnblocked() override;

  // QuicSession::Visitor methods.
  void OnConnectionClosed(quic::QuicConnectionId server_connection_id,
                          quic::QuicErrorCode error,
                          const std::string& error_details,
                          quic::ConnectionCloseSource source) override;
  void OnWriteBlocked(
      quic::QuicBlockedWriterInterface* /*blocked_writer*/) override {}
  void OnRstStreamReceived(const quic::QuicRstStreamFrame& /*frame*/) override {
  }
  void OnStopSendingReceived(
      const quic::QuicStopSendingFrame& /*frame*/) override {}
  void OnNewConnectionIdSent(
      const quic::QuicConnectionId& /*server_connection_id*/,
      const quic::QuicConnectionId& /*new_connecition_id*/) override {}
  void OnConnectionIdRetired(
      const quic::QuicConnectionId& /*server_connection_id*/) override {}

 private:
  // State of the connection establishment process.
  //
  // These values are logged to UMA. Entries should not be renumbered and
  // numeric values should never be reused. Please keep in sync with
  // "QuicTransportClientConnectState" in
  // src/tools/metrics/histograms/enums.xml.
  enum ConnectState {
    CONNECT_STATE_NONE,
    CONNECT_STATE_INIT,
    CONNECT_STATE_CHECK_PROXY,
    CONNECT_STATE_CHECK_PROXY_COMPLETE,
    CONNECT_STATE_RESOLVE_HOST,
    CONNECT_STATE_RESOLVE_HOST_COMPLETE,
    CONNECT_STATE_CONNECT,
    CONNECT_STATE_CONFIRM_CONNECTION,

    CONNECT_STATE_NUM_STATES,
  };

  class DatagramObserverProxy : public quic::QuicDatagramQueue::Observer {
   public:
    explicit DatagramObserverProxy(QuicTransportClient* client)
        : client_(client) {}
    void OnDatagramProcessed(
        absl::optional<quic::MessageStatus> status) override;

   private:
    QuicTransportClient* client_;
  };

  // DoLoop processing the Connect() call.
  void DoLoop(int rv);
  // Verifies the basic preconditions for setting up the connection.
  int DoInit();
  // Verifies that there is no mandatory proxy configured for the specified URL.
  int DoCheckProxy();
  int DoCheckProxyComplete(int rv);
  // Resolves the hostname in the URL.
  int DoResolveHost();
  int DoResolveHostComplete(int rv);
  // Establishes the QUIC connection.
  int DoConnect();
  void CreateConnection();
  // Verifies that the connection has succeeded.
  int DoConfirmConnection();

  void TransitionToState(WebTransportState next_state);

  const GURL url_;
  const url::Origin origin_;
  const NetworkIsolationKey isolation_key_;
  URLRequestContext* const context_;  // Unowned.
  WebTransportClientVisitor* const visitor_;  // Unowned.

  ClientSocketFactory* const client_socket_factory_;
  QuicContext* const quic_context_;
  NetLogWithSource net_log_;
  base::SequencedTaskRunner* task_runner_;

  quic::ParsedQuicVersionVector supported_versions_;
  // TODO(vasilvv): move some of those into QuicContext.
  std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
  quic::QuicCryptoClientConfig crypto_config_;

  WebTransportState state_ = NEW;
  ConnectState next_connect_state_ = CONNECT_STATE_NONE;
  WebTransportError error_;
  bool retried_with_new_version_ = false;

  ProxyInfo proxy_info_;
  std::unique_ptr<ProxyResolutionRequest> proxy_resolution_request_;
  std::unique_ptr<HostResolver::ResolveHostRequest> resolve_host_request_;

  std::unique_ptr<DatagramClientSocket> socket_;
  std::unique_ptr<quic::QuicConnection> connection_;
  std::unique_ptr<quic::QuicTransportClientSession> session_;
  std::unique_ptr<QuicChromiumPacketReader> packet_reader_;
  std::unique_ptr<QuicEventLogger> event_logger_;

  base::WeakPtrFactory<QuicTransportClient> weak_factory_{this};
};

}  // namespace net

#endif  // NET_QUIC_QUIC_TRANSPORT_CLIENT_H_