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 QuicSession subclass.  This class owns the underlying
6// 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_CLIENT_SESSION_H_
11#define NET_QUIC_QUIC_CLIENT_SESSION_H_
12
13#include <string>
14
15#include "base/containers/hash_tables.h"
16#include "base/memory/scoped_ptr.h"
17#include "net/base/completion_callback.h"
18#include "net/quic/quic_connection_logger.h"
19#include "net/quic/quic_crypto_client_stream.h"
20#include "net/quic/quic_reliable_client_stream.h"
21#include "net/quic/quic_session.h"
22
23namespace net {
24
25class DatagramClientSocket;
26class QuicConnectionHelper;
27class QuicCryptoClientStreamFactory;
28class QuicDefaultPacketWriter;
29class QuicStreamFactory;
30class SSLInfo;
31
32namespace test {
33class QuicClientSessionPeer;
34}  // namespace test
35
36class NET_EXPORT_PRIVATE QuicClientSession : public QuicSession {
37 public:
38  // An interface for observing events on a session.
39  class NET_EXPORT_PRIVATE Observer {
40   public:
41    virtual ~Observer() {}
42    virtual void OnCryptoHandshakeConfirmed() = 0;
43    virtual void OnSessionClosed(int error) = 0;
44  };
45
46  // A helper class used to manage a request to create a stream.
47  class NET_EXPORT_PRIVATE StreamRequest {
48   public:
49    StreamRequest();
50    ~StreamRequest();
51
52    // Starts a request to create a stream.  If OK is returned, then
53    // |stream| will be updated with the newly created stream.  If
54    // ERR_IO_PENDING is returned, then when the request is eventuallly
55    // complete |callback| will be called.
56    int StartRequest(const base::WeakPtr<QuicClientSession>& session,
57                     QuicReliableClientStream** stream,
58                     const CompletionCallback& callback);
59
60    // Cancels any pending stream creation request. May be called
61    // repeatedly.
62    void CancelRequest();
63
64   private:
65    friend class QuicClientSession;
66
67    // Called by |session_| for an asynchronous request when the stream
68    // request has finished successfully.
69    void OnRequestCompleteSuccess(QuicReliableClientStream* stream);
70
71    // Called by |session_| for an asynchronous request when the stream
72    // request has finished with an error. Also called with ERR_ABORTED
73    // if |session_| is destroyed while the stream request is still pending.
74    void OnRequestCompleteFailure(int rv);
75
76    base::WeakPtr<QuicClientSession> session_;
77    CompletionCallback callback_;
78    QuicReliableClientStream** stream_;
79
80    DISALLOW_COPY_AND_ASSIGN(StreamRequest);
81  };
82
83  // Constructs a new session which will own |connection| and |helper|, but
84  // not |stream_factory|, which must outlive this session.
85  // TODO(rch): decouple the factory from the session via a Delegate interface.
86  QuicClientSession(QuicConnection* connection,
87                    scoped_ptr<DatagramClientSocket> socket,
88                    scoped_ptr<QuicDefaultPacketWriter> writer,
89                    QuicStreamFactory* stream_factory,
90                    QuicCryptoClientStreamFactory* crypto_client_stream_factory,
91                    const std::string& server_hostname,
92                    const QuicConfig& config,
93                    QuicCryptoClientConfig* crypto_config,
94                    NetLog* net_log);
95
96  virtual ~QuicClientSession();
97
98  void AddObserver(Observer* observer);
99  void RemoveObserver(Observer* observer);
100
101  // Attempts to create a new stream.  If the stream can be
102  // created immediately, returns OK.  If the open stream limit
103  // has been reached, returns ERR_IO_PENDING, and |request|
104  // will be added to the stream requets queue and will
105  // be completed asynchronously.
106  // TODO(rch): remove |stream| from this and use setter on |request|
107  // and fix in spdy too.
108  int TryCreateStream(StreamRequest* request,
109                      QuicReliableClientStream** stream);
110
111  // Cancels the pending stream creation request.
112  void CancelRequest(StreamRequest* request);
113
114  // QuicSession methods:
115  virtual bool OnStreamFrames(
116      const std::vector<QuicStreamFrame>& frames) OVERRIDE;
117  virtual QuicReliableClientStream* CreateOutgoingDataStream() OVERRIDE;
118  virtual QuicCryptoClientStream* GetCryptoStream() OVERRIDE;
119  virtual void CloseStream(QuicStreamId stream_id) OVERRIDE;
120  virtual void SendRstStream(QuicStreamId id,
121                             QuicRstStreamErrorCode error) OVERRIDE;
122  virtual void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) OVERRIDE;
123  virtual void OnCryptoHandshakeMessageSent(
124      const CryptoHandshakeMessage& message) OVERRIDE;
125  virtual void OnCryptoHandshakeMessageReceived(
126      const CryptoHandshakeMessage& message) OVERRIDE;
127  virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
128
129  // QuicConnectionVisitorInterface methods:
130  virtual void OnConnectionClosed(QuicErrorCode error, bool from_peer) OVERRIDE;
131  virtual void OnSuccessfulVersionNegotiation(
132      const QuicVersion& version) OVERRIDE;
133
134  // Performs a crypto handshake with the server.
135  int CryptoConnect(bool require_confirmation,
136                    const CompletionCallback& callback);
137
138  // Causes the QuicConnectionHelper to start reading from the socket
139  // and passing the data along to the QuicConnection.
140  void StartReading();
141
142  // Close the session because of |error| and notifies the factory
143  // that this session has been closed, which will delete the session.
144  void CloseSessionOnError(int error);
145
146  base::Value* GetInfoAsValue(const HostPortPair& pair) const;
147
148  const BoundNetLog& net_log() const { return net_log_; }
149
150  base::WeakPtr<QuicClientSession> GetWeakPtr();
151
152  // Returns the number of client hello messages that have been sent on the
153  // crypto stream. If the handshake has completed then this is one greater
154  // than the number of round-trips needed for the handshake.
155  int GetNumSentClientHellos() const;
156
157 protected:
158  // QuicSession methods:
159  virtual QuicDataStream* CreateIncomingDataStream(QuicStreamId id) OVERRIDE;
160
161 private:
162  friend class test::QuicClientSessionPeer;
163
164  typedef std::set<Observer*> ObserverSet;
165  typedef std::list<StreamRequest*> StreamRequestQueue;
166
167  QuicReliableClientStream* CreateOutgoingReliableStreamImpl();
168  // A completion callback invoked when a read completes.
169  void OnReadComplete(int result);
170
171  void OnClosedStream();
172
173  // A Session may be closed via any of three methods:
174  // OnConnectionClosed - called by the connection when the connection has been
175  //     closed, perhaps due to a timeout or a protocol error.
176  // CloseSessionOnError - called from the owner of the session,
177  //     the QuicStreamFactory, when there is an error.
178  // OnReadComplete - when there is a read error.
179  // This method closes all stream and performs any necessary cleanup.
180  void CloseSessionOnErrorInner(int net_error, QuicErrorCode quic_error);
181
182  void CloseAllStreams(int net_error);
183  void CloseAllObservers(int net_error);
184
185  // Notifies the factory that this session is going away and no more streams
186  // should be created from it.  This needs to be called before closing any
187  // streams, because closing a stream may cause a new stream to be created.
188  void NotifyFactoryOfSessionGoingAway();
189
190  // Posts a task to notify the factory that this session has been closed.
191  void NotifyFactoryOfSessionClosedLater();
192
193  // Notifies the factory that this session has been closed which will
194  // delete |this|.
195  void NotifyFactoryOfSessionClosed();
196
197  bool require_confirmation_;
198  scoped_ptr<QuicCryptoClientStream> crypto_stream_;
199  QuicStreamFactory* stream_factory_;
200  scoped_ptr<DatagramClientSocket> socket_;
201  scoped_ptr<QuicDefaultPacketWriter> writer_;
202  scoped_refptr<IOBufferWithSize> read_buffer_;
203  ObserverSet observers_;
204  StreamRequestQueue stream_requests_;
205  bool read_pending_;
206  CompletionCallback callback_;
207  size_t num_total_streams_;
208  BoundNetLog net_log_;
209  QuicConnectionLogger logger_;
210  // Number of packets read in the current read loop.
211  size_t num_packets_read_;
212  base::WeakPtrFactory<QuicClientSession> weak_factory_;
213
214  DISALLOW_COPY_AND_ASSIGN(QuicClientSession);
215};
216
217}  // namespace net
218
219#endif  // NET_QUIC_QUIC_CLIENT_SESSION_H_
220