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
3 // found in the LICENSE file.
4 //
5 // A client specific quic::QuicSession subclass.  This class owns the underlying
6 // quic::QuicConnection and QuicConnectionHelper objects.  The connection stores
7 // a non-owning pointer to the helper so this session needs to ensure that
8 // the helper outlives the connection.
9 
10 #ifndef NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_
11 #define NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_
12 
13 #include <stddef.h>
14 
15 #include <list>
16 #include <memory>
17 #include <set>
18 #include <string>
19 #include <vector>
20 
21 #include "base/containers/mru_cache.h"
22 #include "base/macros.h"
23 #include "base/observer_list_types.h"
24 #include "base/time/time.h"
25 #include "base/timer/timer.h"
26 #include "net/base/completion_once_callback.h"
27 #include "net/base/load_timing_info.h"
28 #include "net/base/net_error_details.h"
29 #include "net/base/net_export.h"
30 #include "net/base/proxy_server.h"
31 #include "net/log/net_log_with_source.h"
32 #include "net/quic/quic_chromium_client_stream.h"
33 #include "net/quic/quic_chromium_packet_reader.h"
34 #include "net/quic/quic_chromium_packet_writer.h"
35 #include "net/quic/quic_connection_logger.h"
36 #include "net/quic/quic_connectivity_probing_manager.h"
37 #include "net/quic/quic_crypto_client_config_handle.h"
38 #include "net/quic/quic_http3_logger.h"
39 #include "net/quic/quic_session_key.h"
40 #include "net/socket/socket_performance_watcher.h"
41 #include "net/spdy/http2_priority_dependencies.h"
42 #include "net/spdy/multiplexed_session.h"
43 #include "net/spdy/server_push_delegate.h"
44 #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
45 #include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session_base.h"
46 #include "net/third_party/quiche/src/quic/core/quic_crypto_client_stream.h"
47 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
48 #include "net/third_party/quiche/src/quic/core/quic_server_id.h"
49 #include "net/third_party/quiche/src/quic/core/quic_time.h"
50 #include "net/traffic_annotation/network_traffic_annotation.h"
51 
52 namespace net {
53 
54 class CertVerifyResult;
55 class DatagramClientSocket;
56 class NetLog;
57 class QuicCryptoClientStreamFactory;
58 class QuicServerInfo;
59 class QuicStreamFactory;
60 class SSLConfigService;
61 class SSLInfo;
62 class TransportSecurityState;
63 
64 namespace test {
65 class QuicChromiumClientSessionPeer;
66 }  // namespace test
67 
68 // SETTINGS_MAX_HEADERS_LIST_SIZE, the maximum size of uncompressed QUIC headers
69 // that the server is allowed to send.
70 const size_t kQuicMaxHeaderListSize = 256 * 1024;
71 
72 // Result of a session migration attempt.
73 enum class MigrationResult {
74   SUCCESS,         // Migration succeeded.
75   NO_NEW_NETWORK,  // Migration failed since no new network was found.
76   FAILURE          // Migration failed for other reasons.
77 };
78 
79 // Mode of connection migration.
80 enum class ConnectionMigrationMode {
81   NO_MIGRATION,
82   NO_MIGRATION_ON_PATH_DEGRADING_V1,
83   FULL_MIGRATION_V1,
84   NO_MIGRATION_ON_PATH_DEGRADING_V2,
85   FULL_MIGRATION_V2
86 };
87 
88 // Cause of a migration.
89 enum MigrationCause {
90   UNKNOWN_CAUSE,
91   ON_NETWORK_CONNECTED,                       // No probing.
92   ON_NETWORK_DISCONNECTED,                    // No probing.
93   ON_WRITE_ERROR,                             // No probing.
94   ON_NETWORK_MADE_DEFAULT,                    // With probing.
95   ON_MIGRATE_BACK_TO_DEFAULT_NETWORK,         // With probing.
96   CHANGE_NETWORK_ON_PATH_DEGRADING,           // With probing.
97   CHANGE_PORT_ON_PATH_DEGRADING,              // With probing.
98   NEW_NETWORK_CONNECTED_POST_PATH_DEGRADING,  // With probing.
99   MIGRATION_CAUSE_MAX
100 };
101 
102 // Result of connection migration.
103 enum QuicConnectionMigrationStatus {
104   MIGRATION_STATUS_NO_MIGRATABLE_STREAMS,
105   MIGRATION_STATUS_ALREADY_MIGRATED,
106   MIGRATION_STATUS_INTERNAL_ERROR,
107   MIGRATION_STATUS_TOO_MANY_CHANGES,
108   MIGRATION_STATUS_SUCCESS,
109   MIGRATION_STATUS_NON_MIGRATABLE_STREAM,
110   MIGRATION_STATUS_NOT_ENABLED,
111   MIGRATION_STATUS_NO_ALTERNATE_NETWORK,
112   MIGRATION_STATUS_ON_PATH_DEGRADING_DISABLED,
113   MIGRATION_STATUS_DISABLED_BY_CONFIG,
114   MIGRATION_STATUS_PATH_DEGRADING_NOT_ENABLED,
115   MIGRATION_STATUS_TIMEOUT,
116   MIGRATION_STATUS_ON_WRITE_ERROR_DISABLED,
117   MIGRATION_STATUS_PATH_DEGRADING_BEFORE_HANDSHAKE_CONFIRMED,
118   MIGRATION_STATUS_IDLE_MIGRATION_TIMEOUT,
119   MIGRATION_STATUS_MAX
120 };
121 
122 // Result of a connectivity probing attempt.
123 enum class ProbingResult {
124   PENDING,                          // Probing started, pending result.
125   DISABLED_WITH_IDLE_SESSION,       // Probing disabled with idle session.
126   DISABLED_BY_CONFIG,               // Probing disabled by config.
127   DISABLED_BY_NON_MIGRABLE_STREAM,  // Probing disabled by special stream.
128   INTERNAL_ERROR,                   // Probing failed for internal reason.
129   FAILURE,                          // Probing failed for other reason.
130 };
131 
132 class NET_EXPORT_PRIVATE QuicChromiumClientSession
133     : public quic::QuicSpdyClientSessionBase,
134       public MultiplexedSession,
135       public QuicConnectivityProbingManager::Delegate,
136       public QuicChromiumPacketReader::Visitor,
137       public QuicChromiumPacketWriter::Delegate {
138  public:
139   class StreamRequest;
140 
141   // An interface that when implemented and added via
142   // AddConnectivityObserver(), provides notifications when connectivity
143   // quality changes.
144   class NET_EXPORT_PRIVATE ConnectivityObserver : public base::CheckedObserver {
145    public:
146     // Called when path degrading is detected on |network|.
147     virtual void OnSessionPathDegrading(
148         QuicChromiumClientSession* session,
149         NetworkChangeNotifier::NetworkHandle network) = 0;
150 
151     // Called when forward progress is made after path degrading on |network|.
152     virtual void OnSessionResumedPostPathDegrading(
153         QuicChromiumClientSession* session,
154         NetworkChangeNotifier::NetworkHandle network) = 0;
155 
156     // Called when |session| encounters write error on |network|.
157     // A write error may be caused by the change in the underlying network
158     // interface, and can be pre-emptive hints of connectivity quality changes
159     // based on the |error_code|.
160     virtual void OnSessionEncounteringWriteError(
161         QuicChromiumClientSession* session,
162         NetworkChangeNotifier::NetworkHandle network,
163         int error_code) = 0;
164 
165     // Called when |session| is closed by |source| with |error_code|
166     // and handshake has been confirmed.
167     virtual void OnSessionClosedAfterHandshake(
168         QuicChromiumClientSession* session,
169         NetworkChangeNotifier::NetworkHandle network,
170         quic::ConnectionCloseSource source,
171         quic::QuicErrorCode error_code) = 0;
172 
173     // Called when |this| is registered to monitor the connectivity of the
174     // |session|.
175     virtual void OnSessionRegistered(
176         QuicChromiumClientSession* session,
177         NetworkChangeNotifier::NetworkHandle network) = 0;
178 
179     // Called when |session| is removed.
180     virtual void OnSessionRemoved(QuicChromiumClientSession* session) = 0;
181   };
182 
183   // Wrapper for interacting with the session in a restricted fashion which
184   // hides the details of the underlying session's lifetime. All methods of
185   // the Handle are safe to use even after the underlying session is destroyed.
186   class NET_EXPORT_PRIVATE Handle
187       : public MultiplexedSessionHandle,
188         public quic::QuicClientPushPromiseIndex::Delegate {
189    public:
190     // Constructs a handle to |session| which was created via the alternative
191     // server |destination|.
192     Handle(const base::WeakPtr<QuicChromiumClientSession>& session,
193            const HostPortPair& destination);
194     Handle(const Handle& other) = delete;
195     ~Handle() override;
196 
197     // Returns true if the session is still connected.
198     bool IsConnected() const;
199 
200     // Returns true if the handshake has been confirmed.
201     bool OneRttKeysAvailable() const;
202 
203     // Starts a request to rendezvous with a promised a stream.  If OK is
204     // returned, then |push_stream_| will be updated with the promised
205     // stream.  If ERR_IO_PENDING is returned, then when the rendezvous is
206     // eventually completed |callback| will be called.
207     int RendezvousWithPromised(const spdy::Http2HeaderBlock& headers,
208                                CompletionOnceCallback callback);
209 
210     // Starts a request to create a stream.  If OK is returned, then
211     // |stream_| will be updated with the newly created stream.  If
212     // ERR_IO_PENDING is returned, then when the request is eventuallly
213     // complete |callback| will be called.
214     int RequestStream(bool requires_confirmation,
215                       CompletionOnceCallback callback,
216                       const NetworkTrafficAnnotationTag& traffic_annotation);
217 
218     // Releases |stream_| to the caller. Returns nullptr if the underlying
219     // QuicChromiumClientSession is closed.
220     std::unique_ptr<QuicChromiumClientStream::Handle> ReleaseStream();
221 
222     // Releases |push_stream_| to the caller.
223     std::unique_ptr<QuicChromiumClientStream::Handle> ReleasePromisedStream();
224 
225     // Sends Rst for the stream, and makes sure that future calls to
226     // IsClosedStream(id) return true, which ensures that any subsequent
227     // frames related to this stream will be ignored (modulo flow
228     // control accounting).
229     void ResetPromised(quic::QuicStreamId id,
230                        quic::QuicRstStreamErrorCode error_code);
231 
232     // Returns a new packet bundler while will cause writes to be batched up
233     // until a packet is full, or the last bundler is destroyed.
234     std::unique_ptr<quic::QuicConnection::ScopedPacketFlusher>
235     CreatePacketBundler();
236 
237     // Populates network error details for this session.
238     void PopulateNetErrorDetails(NetErrorDetails* details) const;
239 
240     // Returns the connection timing for the handshake of this session.
241     const LoadTimingInfo::ConnectTiming& GetConnectTiming();
242 
243     // Returns true if |other| is a handle to the same session as this handle.
244     bool SharesSameSession(const Handle& other) const;
245 
246     // Returns the QUIC version used by the session.
247     quic::ParsedQuicVersion GetQuicVersion() const;
248 
249     // Copies the remote udp address into |address| and returns a net error
250     // code.
251     int GetPeerAddress(IPEndPoint* address) const;
252 
253     // Copies the local udp address into |address| and returns a net error
254     // code.
255     int GetSelfAddress(IPEndPoint* address) const;
256 
257     // Returns the push promise index associated with the session.
258     quic::QuicClientPushPromiseIndex* GetPushPromiseIndex();
259 
260     // Returns the session's server ID.
server_id()261     quic::QuicServerId server_id() const { return server_id_; }
262 
263     // Returns the alternative server used for this session.
destination()264     HostPortPair destination() const { return destination_; }
265 
266     // Returns the session's net log.
net_log()267     const NetLogWithSource& net_log() const { return net_log_; }
268 
269     // Returns the session's connection migration mode.
connection_migration_mode()270     ConnectionMigrationMode connection_migration_mode() const {
271       return session_->connection_migration_mode();
272     }
273 
274     // quic::QuicClientPushPromiseIndex::Delegate implementation
275     bool CheckVary(const spdy::Http2HeaderBlock& client_request,
276                    const spdy::Http2HeaderBlock& promise_request,
277                    const spdy::Http2HeaderBlock& promise_response) override;
278     void OnRendezvousResult(quic::QuicSpdyStream* stream) override;
279 
280     // Returns true if the session's connection has sent or received any bytes.
281     bool WasEverUsed() const;
282 
283    private:
284     friend class QuicChromiumClientSession;
285     friend class QuicChromiumClientSession::StreamRequest;
286 
287     // Waits for the handshake to be confirmed and invokes |callback| when
288     // that happens. If the handshake has already been confirmed, returns OK.
289     // If the connection has already been closed, returns a net error. If the
290     // connection closes before the handshake is confirmed, |callback| will
291     // be invoked with an error.
292     int WaitForHandshakeConfirmation(CompletionOnceCallback callback);
293 
294     // Called when the handshake is confirmed.
295     void OnCryptoHandshakeConfirmed();
296 
297     // Called when the session is closed with a net error.
298     void OnSessionClosed(quic::ParsedQuicVersion quic_version,
299                          int net_error,
300                          quic::QuicErrorCode quic_error,
301                          bool port_migration_detected,
302                          LoadTimingInfo::ConnectTiming connect_timing,
303                          bool was_ever_used);
304 
305     // Called by |request| to create a stream.
306     int TryCreateStream(StreamRequest* request);
307 
308     // Called by |request| to cancel stream request.
309     void CancelRequest(StreamRequest* request);
310 
311     // Underlying session which may be destroyed before this handle.
312     base::WeakPtr<QuicChromiumClientSession> session_;
313 
314     HostPortPair destination_;
315 
316     // Stream request created by |RequestStream()|.
317     std::unique_ptr<StreamRequest> stream_request_;
318 
319     // Information saved from the session which can be used even after the
320     // session is destroyed.
321     NetLogWithSource net_log_;
322     bool was_handshake_confirmed_;
323     int net_error_;
324     quic::QuicErrorCode quic_error_;
325     bool port_migration_detected_;
326     quic::QuicServerId server_id_;
327     quic::ParsedQuicVersion quic_version_;
328     LoadTimingInfo::ConnectTiming connect_timing_;
329     quic::QuicClientPushPromiseIndex* push_promise_index_;
330 
331     // |quic::QuicClientPromisedInfo| owns this. It will be set when |Try()|
332     // is asynchronous, i.e. it returned quic::QUIC_PENDING, and remains valid
333     // until |OnRendezvouResult()| fires or |push_handle_->Cancel()| is
334     // invoked.
335     quic::QuicClientPushPromiseIndex::TryHandle* push_handle_;
336     CompletionOnceCallback push_callback_;
337     std::unique_ptr<QuicChromiumClientStream::Handle> push_stream_;
338 
339     bool was_ever_used_;
340   };
341 
342   // A helper class used to manage a request to create a stream.
343   class NET_EXPORT_PRIVATE StreamRequest {
344    public:
345     // Cancels any pending stream creation request and resets |stream_| if
346     // it has not yet been released.
347     ~StreamRequest();
348 
349     // Starts a request to create a stream.  If OK is returned, then
350     // |stream_| will be updated with the newly created stream.  If
351     // ERR_IO_PENDING is returned, then when the request is eventuallly
352     // complete |callback| will be called.
353     int StartRequest(CompletionOnceCallback callback);
354 
355     // Releases |stream_| to the caller.
356     std::unique_ptr<QuicChromiumClientStream::Handle> ReleaseStream();
357 
traffic_annotation()358     const NetworkTrafficAnnotationTag traffic_annotation() {
359       return traffic_annotation_;
360     }
361 
362    private:
363     friend class QuicChromiumClientSession;
364 
365     enum State {
366       STATE_NONE,
367       STATE_WAIT_FOR_CONFIRMATION,
368       STATE_WAIT_FOR_CONFIRMATION_COMPLETE,
369       STATE_REQUEST_STREAM,
370       STATE_REQUEST_STREAM_COMPLETE,
371     };
372 
373     // |session| must outlive this request.
374     StreamRequest(QuicChromiumClientSession::Handle* session,
375                   bool requires_confirmation,
376                   const NetworkTrafficAnnotationTag& traffic_annotation);
377 
378     void OnIOComplete(int rv);
379     void DoCallback(int rv);
380 
381     int DoLoop(int rv);
382     int DoWaitForConfirmation();
383     int DoWaitForConfirmationComplete(int rv);
384     int DoRequestStream();
385     int DoRequestStreamComplete(int rv);
386 
387     // Called by |session_| for an asynchronous request when the stream
388     // request has finished successfully.
389     void OnRequestCompleteSuccess(
390         std::unique_ptr<QuicChromiumClientStream::Handle> stream);
391 
392     // Called by |session_| for an asynchronous request when the stream
393     // request has finished with an error. Also called with ERR_ABORTED
394     // if |session_| is destroyed while the stream request is still pending.
395     void OnRequestCompleteFailure(int rv);
396 
397     QuicChromiumClientSession::Handle* session_;
398     const bool requires_confirmation_;
399     CompletionOnceCallback callback_;
400     std::unique_ptr<QuicChromiumClientStream::Handle> stream_;
401     // For tracking how much time pending stream requests wait.
402     base::TimeTicks pending_start_time_;
403     State next_state_;
404 
405     const NetworkTrafficAnnotationTag traffic_annotation_;
406 
407     base::WeakPtrFactory<StreamRequest> weak_factory_{this};
408 
409     DISALLOW_COPY_AND_ASSIGN(StreamRequest);
410   };
411 
412   // Constructs a new session which will own |connection|, but not
413   // |stream_factory|, which must outlive this session.
414   // TODO(rch): decouple the factory from the session via a Delegate interface.
415   //
416   // If |require_confirmation| is true, the returned session will wait for a
417   // successful QUIC handshake before vending any streams, to ensure that both
418   // the server and the current network support QUIC, as HTTP fallback can't
419   // trigger (or at least will take longer) after a QUIC stream has successfully
420   // been created.
421   QuicChromiumClientSession(
422       quic::QuicConnection* connection,
423       std::unique_ptr<DatagramClientSocket> socket,
424       QuicStreamFactory* stream_factory,
425       QuicCryptoClientStreamFactory* crypto_client_stream_factory,
426       const quic::QuicClock* clock,
427       TransportSecurityState* transport_security_state,
428       SSLConfigService* ssl_config_service,
429       std::unique_ptr<QuicServerInfo> server_info,
430       const QuicSessionKey& session_key,
431       bool require_confirmation,
432       quic::QuicStreamId max_allowed_push_id,
433       bool migrate_sesion_early_v2,
434       bool migrate_session_on_network_change_v2,
435       NetworkChangeNotifier::NetworkHandle default_network,
436       quic::QuicTime::Delta retransmittable_on_wire_timeout,
437       bool migrate_idle_session,
438       bool allow_port_migration,
439       base::TimeDelta idle_migration_period,
440       base::TimeDelta max_time_on_non_default_network,
441       int max_migrations_to_non_default_network_on_write_error,
442       int max_migrations_to_non_default_network_on_path_degrading,
443       int yield_after_packets,
444       quic::QuicTime::Delta yield_after_duration,
445       bool go_away_on_path_degrading,
446       bool headers_include_h2_stream_dependency,
447       int cert_verify_flags,
448       const quic::QuicConfig& config,
449       std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config,
450       const char* const connection_description,
451       base::TimeTicks dns_resolution_start_time,
452       base::TimeTicks dns_resolution_end_time,
453       std::unique_ptr<quic::QuicClientPushPromiseIndex> push_promise_index,
454       ServerPushDelegate* push_delegate,
455       const base::TickClock* tick_clock,
456       base::SequencedTaskRunner* task_runner,
457       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
458       NetLog* net_log);
459   ~QuicChromiumClientSession() override;
460 
461   void Initialize() override;
462 
463   void AddHandle(Handle* handle);
464   void RemoveHandle(Handle* handle);
465 
466   void AddConnectivityObserver(ConnectivityObserver* observer);
467   void RemoveConnectivityObserver(ConnectivityObserver* observer);
468 
469   // Returns the session's connection migration mode.
470   ConnectionMigrationMode connection_migration_mode() const;
471 
472   // Waits for the handshake to be confirmed and invokes |callback| when
473   // that happens. If the handshake has already been confirmed, returns OK.
474   // If the connection has already been closed, returns a net error. If the
475   // connection closes before the handshake is confirmed, |callback| will
476   // be invoked with an error.
477   int WaitForHandshakeConfirmation(CompletionOnceCallback callback);
478 
479   // Attempts to create a new stream.  If the stream can be
480   // created immediately, returns OK.  If the open stream limit
481   // has been reached, returns ERR_IO_PENDING, and |request|
482   // will be added to the stream requets queue and will
483   // be completed asynchronously.
484   // TODO(rch): remove |stream| from this and use setter on |request|
485   // and fix in spdy too.
486   int TryCreateStream(StreamRequest* request);
487 
488   // Cancels the pending stream creation request.
489   void CancelRequest(StreamRequest* request);
490 
491   // QuicChromiumPacketWriter::Delegate override.
492   int HandleWriteError(int error_code,
493                        scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer>
494                            last_packet) override;
495   void OnWriteError(int error_code) override;
496   // Called when the associated writer is unblocked. Write the cached |packet_|
497   // if |packet_| is set. May send a PING packet if
498   // |send_packet_after_migration_| is set and writer is not blocked after
499   // writing queued packets.
500   void OnWriteUnblocked() override;
501 
502   // QuicConnectivityProbingManager::Delegate override.
503   void OnProbeSucceeded(
504       NetworkChangeNotifier::NetworkHandle network,
505       const quic::QuicSocketAddress& peer_address,
506       const quic::QuicSocketAddress& self_address,
507       std::unique_ptr<DatagramClientSocket> socket,
508       std::unique_ptr<QuicChromiumPacketWriter> writer,
509       std::unique_ptr<QuicChromiumPacketReader> reader) override;
510 
511   void OnProbeFailed(NetworkChangeNotifier::NetworkHandle network,
512                      const quic::QuicSocketAddress& peer_address) override;
513 
514   bool OnSendConnectivityProbingPacket(
515       QuicChromiumPacketWriter* writer,
516       const quic::QuicSocketAddress& peer_address) override;
517 
518   // quic::QuicSpdySession methods:
519   size_t WriteHeadersOnHeadersStream(
520       quic::QuicStreamId id,
521       spdy::Http2HeaderBlock headers,
522       bool fin,
523       const spdy::SpdyStreamPrecedence& precedence,
524       quic::QuicReferenceCountedPointer<quic::QuicAckListenerInterface>
525           ack_listener) override;
526   void UnregisterStreamPriority(quic::QuicStreamId id, bool is_static) override;
527   void UpdateStreamPriority(
528       quic::QuicStreamId id,
529       const spdy::SpdyStreamPrecedence& new_precedence) override;
530   void OnHttp3GoAway(uint64_t id) override;
531 
532   // quic::QuicSession methods:
533   QuicChromiumClientStream* CreateOutgoingBidirectionalStream() override;
534   QuicChromiumClientStream* CreateOutgoingUnidirectionalStream() override;
535   const quic::QuicCryptoClientStream* GetCryptoStream() const override;
536   quic::QuicCryptoClientStream* GetMutableCryptoStream() override;
537   void SetDefaultEncryptionLevel(quic::EncryptionLevel level) override;
538   void OnTlsHandshakeComplete() override;
539   void OnNewEncryptionKeyAvailable(
540       quic::EncryptionLevel level,
541       std::unique_ptr<quic::QuicEncrypter> encrypter) override;
542   void OnCryptoHandshakeMessageSent(
543       const quic::CryptoHandshakeMessage& message) override;
544   void OnCryptoHandshakeMessageReceived(
545       const quic::CryptoHandshakeMessage& message) override;
546   void OnGoAway(const quic::QuicGoAwayFrame& frame) override;
547   void OnCanCreateNewOutgoingStream(bool unidirectional) override;
548   bool ValidateStatelessReset(
549       const quic::QuicSocketAddress& self_address,
550       const quic::QuicSocketAddress& peer_address) override;
551   void SendPing() override;
552 
553   // QuicSpdyClientSessionBase methods:
554   void OnConfigNegotiated() override;
555   void OnProofValid(
556       const quic::QuicCryptoClientConfig::CachedState& cached) override;
557   void OnProofVerifyDetailsAvailable(
558       const quic::ProofVerifyDetails& verify_details) override;
559 
560   // quic::QuicConnectionVisitorInterface methods:
561   void OnConnectionClosed(const quic::QuicConnectionCloseFrame& frame,
562                           quic::ConnectionCloseSource source) override;
563   void OnSuccessfulVersionNegotiation(
564       const quic::ParsedQuicVersion& version) override;
565   void OnPacketReceived(const quic::QuicSocketAddress& self_address,
566                         const quic::QuicSocketAddress& peer_address,
567                         bool is_connectivity_probe) override;
568   void OnPathDegrading() override;
569   void OnForwardProgressMadeAfterPathDegrading() override;
570   void OnKeyUpdate(quic::KeyUpdateReason reason) override;
571 
572   // QuicChromiumPacketReader::Visitor methods:
573   void OnReadError(int result, const DatagramClientSocket* socket) override;
574   bool OnPacket(const quic::QuicReceivedPacket& packet,
575                 const quic::QuicSocketAddress& local_address,
576                 const quic::QuicSocketAddress& peer_address) override;
577   void OnStreamClosed(quic::QuicStreamId stream_id) override;
578 
579   // MultiplexedSession methods:
580   bool GetRemoteEndpoint(IPEndPoint* endpoint) override;
581   bool GetSSLInfo(SSLInfo* ssl_info) const override;
582 
583   // Performs a crypto handshake with the server.
584   int CryptoConnect(CompletionOnceCallback callback);
585 
586   // Causes the QuicConnectionHelper to start reading from all sockets
587   // and passing the data along to the quic::QuicConnection.
588   void StartReading();
589 
590   // Close the session because of |net_error| and notifies the factory
591   // that this session has been closed, which will delete the session.
592   // |behavior| will suggest whether we should send connection close packets
593   // when closing the connection.
594   void CloseSessionOnError(int net_error,
595                            quic::QuicErrorCode quic_error,
596                            quic::ConnectionCloseBehavior behavior);
597 
598   // Close the session because of |net_error| and notifies the factory
599   // that this session has been closed later, which will delete the session.
600   // |behavior| will suggest whether we should send connection close packets
601   // when closing the connection.
602   void CloseSessionOnErrorLater(int net_error,
603                                 quic::QuicErrorCode quic_error,
604                                 quic::ConnectionCloseBehavior behavior);
605 
606   base::Value GetInfoAsValue(const std::set<HostPortPair>& aliases);
607 
net_log()608   const NetLogWithSource& net_log() const { return net_log_; }
609 
610   // Returns true if the stream factory disables gQUIC 0-RTT.
611   bool gquic_zero_rtt_disabled() const;
612 
613   // Returns a Handle to this session.
614   std::unique_ptr<QuicChromiumClientSession::Handle> CreateHandle(
615       const HostPortPair& destination);
616 
617   // Returns the number of client hello messages that have been sent on the
618   // crypto stream. If the handshake has completed then this is one greater
619   // than the number of round-trips needed for the handshake.
620   int GetNumSentClientHellos() const;
621 
622   // Returns true if |hostname| may be pooled onto this session.
623   // |other_session_key| specifies the seession key associated with |hostname|
624   // (its own hostname and port fields are ignored). If this is a secure QUIC
625   // session, then |hostname| must match the certificate presented during the
626   // handshake.
627   bool CanPool(const std::string& hostname,
628                const QuicSessionKey& other_session_key) const;
629 
server_id()630   const quic::QuicServerId& server_id() const {
631     return session_key_.server_id();
632   }
633 
quic_session_key()634   const QuicSessionKey& quic_session_key() const { return session_key_; }
635 
636   // Attempts to migrate session when |writer| encounters a write error.
637   // If |writer| is no longer actively used, abort migration.
638   void MigrateSessionOnWriteError(int error_code,
639                                   quic::QuicPacketWriter* writer);
640 
641   // Helper method that completes connection/server migration.
642   // Unblocks packet writer on network level. If the writer becomes unblocked
643   // then, OnWriteUnblocked() will be invoked to send packet after migration.
644   void WriteToNewSocket();
645 
646   // Migrates session over to use |peer_address| and |network|.
647   // If |network| is kInvalidNetworkHandle, default network is used. If the
648   // migration fails and |close_session_on_error| is true, session will be
649   // closed.
650   MigrationResult Migrate(NetworkChangeNotifier::NetworkHandle network,
651                           IPEndPoint peer_address,
652                           bool close_session_on_error);
653 
654   // Migrates session onto new socket, i.e., sets |writer| to be the new
655   // default writer and post a task to write to |socket|. |reader| *must*
656   // has been started reading from the socket. Returns true if
657   // socket was successfully added to the session and the session was
658   // successfully migrated to using the new socket. Returns true on
659   // successful migration, or false if number of migrations exceeds
660   // kMaxReadersPerQuicSession. Takes ownership of |socket|, |reader|,
661   // and |writer|.
662   bool MigrateToSocket(std::unique_ptr<DatagramClientSocket> socket,
663                        std::unique_ptr<QuicChromiumPacketReader> reader,
664                        std::unique_ptr<QuicChromiumPacketWriter> writer);
665 
666   // Called when NetworkChangeNotifier notifies observers of a newly
667   // connected network. Migrates this session to the newly connected
668   // network if the session has a pending migration.
669   void OnNetworkConnected(NetworkChangeNotifier::NetworkHandle network);
670 
671   // Called when NetworkChangeNotifier broadcasts to observers of
672   // |disconnected_network|.
673   void OnNetworkDisconnectedV2(
674       NetworkChangeNotifier::NetworkHandle disconnected_network);
675 
676   // Called when NetworkChangeNotifier broadcats to observers of a new default
677   // network. Migrates this session to |new_network| if appropriate.
678   void OnNetworkMadeDefault(NetworkChangeNotifier::NetworkHandle new_network);
679 
680   // Schedules a migration alarm to wait for a new network.
681   void OnNoNewNetwork();
682 
683   // Called when migration alarm fires. If migration has not occurred
684   // since alarm was set, closes session with error.
685   void OnMigrationTimeout(size_t num_sockets);
686 
687   // Populates network error details for this session.
688   void PopulateNetErrorDetails(NetErrorDetails* details) const;
689 
690   // Returns current default socket. This is the socket over which all
691   // QUIC packets are sent. This default socket can change, so do not store the
692   // returned socket.
693   const DatagramClientSocket* GetDefaultSocket() const;
694 
695   // Returns the network interface that is currently used to send packets.
696   // If NetworkHandle is not supported, always return
697   // NetworkChangeNotifier::kInvalidNetworkHandle.
698   NetworkChangeNotifier::NetworkHandle GetCurrentNetwork() const;
699 
700   bool IsAuthorized(const std::string& hostname) override;
701 
702   bool HandlePromised(quic::QuicStreamId associated_id,
703                       quic::QuicStreamId promised_id,
704                       const spdy::Http2HeaderBlock& headers) override;
705 
706   void DeletePromised(quic::QuicClientPromisedInfo* promised) override;
707 
708   void OnPushStreamTimedOut(quic::QuicStreamId stream_id) override;
709 
710   // Cancels the push if the push stream for |url| has not been claimed and is
711   // still active. Otherwise, no-op.
712   void CancelPush(const GURL& url);
713 
714   const LoadTimingInfo::ConnectTiming& GetConnectTiming();
715 
716   quic::ParsedQuicVersion GetQuicVersion() const;
717 
718   // Returns the estimate of dynamically allocated memory in bytes.
719   // See base/trace_event/memory_usage_estimator.h.
720   // TODO(xunjieli): It only tracks |packet_readers_|. Write a better estimate.
721   size_t EstimateMemoryUsage() const;
722 
723   // Looks for a push that matches the provided parameters.
724   quic::QuicClientPromisedInfo* GetPromised(const GURL& url,
725                                             const QuicSessionKey& session_key);
726 
require_confirmation()727   bool require_confirmation() const { return require_confirmation_; }
728 
729  protected:
730   // quic::QuicSession methods:
731   bool ShouldCreateIncomingStream(quic::QuicStreamId id) override;
732   bool ShouldCreateOutgoingBidirectionalStream() override;
733   bool ShouldCreateOutgoingUnidirectionalStream() override;
734 
735   QuicChromiumClientStream* CreateIncomingStream(
736       quic::QuicStreamId id) override;
737   QuicChromiumClientStream* CreateIncomingStream(
738       quic::PendingStream* pending) override;
739 
740  private:
741   friend class test::QuicChromiumClientSessionPeer;
742 
743   typedef std::set<Handle*> HandleSet;
744   typedef std::list<StreamRequest*> StreamRequestQueue;
745 
746   bool WasConnectionEverUsed();
747 
748   QuicChromiumClientStream* CreateOutgoingReliableStreamImpl(
749       const NetworkTrafficAnnotationTag& traffic_annotation);
750   QuicChromiumClientStream* CreateIncomingReliableStreamImpl(
751       quic::QuicStreamId id,
752       const NetworkTrafficAnnotationTag& traffic_annotation);
753   QuicChromiumClientStream* CreateIncomingReliableStreamImpl(
754       quic::PendingStream* pending,
755       const NetworkTrafficAnnotationTag& traffic_annotation);
756   // A completion callback invoked when a read completes.
757   void OnReadComplete(int result);
758 
759   void NotifyAllStreamsOfError(int net_error);
760   void CloseAllHandles(int net_error);
761   void CancelAllRequests(int net_error);
762   void NotifyRequestsOfConfirmation(int net_error);
763 
764   // Probe on <network, peer_address>.
765   // If <network, peer_addres> is identical to the current path, the probe
766   // is sent on a different port.
767   ProbingResult StartProbing(NetworkChangeNotifier::NetworkHandle network,
768                              const quic::QuicSocketAddress& peer_address);
769 
770   // Perform a few checks before StartProbing. If any of those checks fails,
771   // StartProbing will be skipped.
772   ProbingResult MaybeStartProbing(NetworkChangeNotifier::NetworkHandle network,
773                                   const quic::QuicSocketAddress& peer_address);
774 
775   // Helper method to perform a few checks and initiate connection migration
776   // attempt when path degrading is detected.
777   // Called when path is degrading and there is an alternate network or a new
778   // network is connected after path degrading.
779   void MaybeMigrateToAlternateNetworkOnPathDegrading();
780 
781   // Helper method to initiate a port migration on path degrading is detected.
782   void MaybeMigrateToDifferentPortOnPathDegrading();
783 
784   // Called when there is only one possible working network: |network|, If any
785   // error encountered, this session will be closed.
786   // When the migration succeeds:
787   //  - If no longer on the default network, set timer to migrate back to the
788   //    default network;
789   //  - If now on the default network, cancel timer to migrate back to default
790   //    network.
791   void MigrateNetworkImmediately(NetworkChangeNotifier::NetworkHandle network);
792 
793   void StartMigrateBackToDefaultNetworkTimer(base::TimeDelta delay);
794   void CancelMigrateBackToDefaultNetworkTimer();
795   void TryMigrateBackToDefaultNetwork(base::TimeDelta timeout);
796   void MaybeRetryMigrateBackToDefaultNetwork();
797 
798   // If migrate idle session is enabled, returns true and post a task to close
799   // the connection if session's idle time exceeds the |idle_migration_period_|.
800   // If migrate idle session is not enabled, returns true and posts a task to
801   // close the connection if session doesn't have outstanding streams.
802   bool CheckIdleTimeExceedsIdleMigrationPeriod();
803 
804   // Close non-migratable streams in both directions by sending reset stream to
805   // peer when connection migration attempts to migrate to the alternate
806   // network.
807   void ResetNonMigratableStreams();
808   void LogMetricsOnNetworkDisconnected();
809   void LogMetricsOnNetworkMadeDefault();
810   void LogMigrationResultToHistogram(QuicConnectionMigrationStatus status);
811   void LogHandshakeStatusOnMigrationSignal() const;
812   void HistogramAndLogMigrationFailure(QuicConnectionMigrationStatus status,
813                                        quic::QuicConnectionId connection_id,
814                                        const char* reason);
815   void HistogramAndLogMigrationSuccess(quic::QuicConnectionId connection_id);
816 
817   // Notifies the factory that this session is going away and no more streams
818   // should be created from it.  This needs to be called before closing any
819   // streams, because closing a stream may cause a new stream to be created.
820   void NotifyFactoryOfSessionGoingAway();
821 
822   // Posts a task to notify the factory that this session has been closed.
823   void NotifyFactoryOfSessionClosedLater();
824 
825   // Notifies the factory that this session has been closed which will
826   // delete |this|.
827   void NotifyFactoryOfSessionClosed();
828 
829   // Called when default encryption level switches to forward secure.
830   void OnCryptoHandshakeComplete();
831 
832   void LogZeroRttStats();
833 
834   QuicSessionKey session_key_;
835   bool require_confirmation_;
836   bool migrate_session_early_v2_;
837   bool migrate_session_on_network_change_v2_;
838   bool migrate_idle_session_;
839   bool allow_port_migration_;
840   // Session can be migrated if its idle time is within this period.
841   base::TimeDelta idle_migration_period_;
842   base::TimeDelta max_time_on_non_default_network_;
843   // Maximum allowed number of migrations to non-default network triggered by
844   // packet write error per default network.
845   int max_migrations_to_non_default_network_on_write_error_;
846   int current_migrations_to_non_default_network_on_write_error_;
847   // Maximum allowed number of migrations to non-default network triggered by
848   // path degrading per default network.
849   int max_migrations_to_non_default_network_on_path_degrading_;
850   int current_migrations_to_non_default_network_on_path_degrading_;
851   const quic::QuicClock* clock_;  // Unowned.
852   int yield_after_packets_;
853   quic::QuicTime::Delta yield_after_duration_;
854   bool go_away_on_path_degrading_;
855 
856   base::TimeTicks most_recent_path_degrading_timestamp_;
857   base::TimeTicks most_recent_network_disconnected_timestamp_;
858   const base::TickClock* tick_clock_;
859   base::TimeTicks most_recent_stream_close_time_;
860 
861   int most_recent_write_error_;
862   base::TimeTicks most_recent_write_error_timestamp_;
863 
864   std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_;
865 
866   std::unique_ptr<quic::QuicCryptoClientStream> crypto_stream_;
867   QuicStreamFactory* stream_factory_;
868   base::ObserverList<ConnectivityObserver> connectivity_observer_list_;
869   std::vector<std::unique_ptr<DatagramClientSocket>> sockets_;
870   TransportSecurityState* transport_security_state_;
871   SSLConfigService* ssl_config_service_;
872   std::unique_ptr<QuicServerInfo> server_info_;
873   std::unique_ptr<CertVerifyResult> cert_verify_result_;
874   std::string pinning_failure_log_;
875   bool pkp_bypassed_;
876   bool is_fatal_cert_error_;
877   HandleSet handles_;
878   StreamRequestQueue stream_requests_;
879   std::vector<CompletionOnceCallback> waiting_for_confirmation_callbacks_;
880   CompletionOnceCallback callback_;
881   size_t num_total_streams_;
882   base::SequencedTaskRunner* task_runner_;
883   NetLogWithSource net_log_;
884   std::vector<std::unique_ptr<QuicChromiumPacketReader>> packet_readers_;
885   LoadTimingInfo::ConnectTiming connect_timing_;
886   std::unique_ptr<QuicConnectionLogger> logger_;
887   std::unique_ptr<QuicHttp3Logger> http3_logger_;
888   // True when the session is going away, and streams may no longer be created
889   // on this session. Existing stream will continue to be processed.
890   bool going_away_;
891   // True when the session receives a go away from server due to port migration.
892   bool port_migration_detected_;
893   // Not owned. |push_delegate_| outlives the session and handles server pushes
894   // received by session.
895   ServerPushDelegate* push_delegate_;
896   // UMA histogram counters for streams pushed to this session.
897   int streams_pushed_count_;
898   int streams_pushed_and_claimed_count_;
899   uint64_t bytes_pushed_count_;
900   uint64_t bytes_pushed_and_unclaimed_count_;
901   // Stores the packet that witnesses socket write error. This packet will be
902   // written to an alternate socket when the migration completes and the
903   // alternate socket is unblocked.
904   scoped_refptr<QuicChromiumPacketWriter::ReusableIOBuffer> packet_;
905   // Stores the latest default network platform marks if migration is enabled.
906   // Otherwise, stores the network interface that is used by the connection.
907   NetworkChangeNotifier::NetworkHandle default_network_;
908   QuicConnectivityProbingManager probing_manager_;
909   int retry_migrate_back_count_;
910   base::OneShotTimer migrate_back_to_default_timer_;
911   MigrationCause current_migration_cause_;
912   // True if a packet needs to be sent when packet writer is unblocked to
913   // complete connection migration. The packet can be a cached packet if
914   // |packet_| is set, a queued packet, or a PING packet.
915   bool send_packet_after_migration_;
916   // True if migration is triggered, and there is no alternate network to
917   // migrate to.
918   bool wait_for_new_network_;
919   // True if read errors should be ignored. Set when migration on write error is
920   // posted and unset until the first packet is written after migration.
921   bool ignore_read_error_;
922 
923   // If true, client headers will include HTTP/2 stream dependency info derived
924   // from spdy::SpdyStreamPrecedence.
925   bool headers_include_h2_stream_dependency_;
926   Http2PriorityDependencies priority_dependency_state_;
927 
928   quic::QuicStreamId max_allowed_push_id_;
929 
930   bool attempted_zero_rtt_;
931 
932   size_t num_pings_sent_;
933 
934   size_t num_migrations_;
935 
936   // The reason for the last 1-RTT key update on the connection. Will be
937   // kInvalid if no key updates have occurred.
938   quic::KeyUpdateReason last_key_update_reason_;
939 
940   std::unique_ptr<quic::QuicClientPushPromiseIndex> push_promise_index_;
941 
942   base::WeakPtrFactory<QuicChromiumClientSession> weak_factory_{this};
943 
944   DISALLOW_COPY_AND_ASSIGN(QuicChromiumClientSession);
945 };
946 
947 }  // namespace net
948 
949 #endif  // NET_QUIC_QUIC_CHROMIUM_CLIENT_SESSION_H_
950