Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / cast_channel / cast_socket.h
1 // Copyright 2013 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 CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_
7
8 #include <queue>
9 #include <string>
10
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/threading/thread_checker.h"
17 #include "chrome/browser/extensions/api/api_resource.h"
18 #include "chrome/browser/extensions/api/api_resource_manager.h"
19 #include "chrome/common/extensions/api/cast_channel.h"
20 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h"
22 #include "net/base/ip_endpoint.h"
23 #include "net/base/net_log.h"
24 #include "url/gurl.h"
25
26 namespace net {
27 class AddressList;
28 class CertVerifier;
29 class SSLClientSocket;
30 class TCPClientSocket;
31 class TransportSecurityState;
32 }
33
34 namespace extensions {
35 namespace api {
36 namespace cast_channel {
37
38 class CastMessage;
39
40 // Size, in bytes, of the largest allowed message payload on the wire (without
41 // the header).
42 extern const uint32 kMaxMessageSize;
43
44 // This class implements a channel between Chrome and a Cast device using a TCP
45 // socket. The channel may be unauthenticated (cast://) or authenticated
46 // (casts://). All CastSocket objects must be used only on the IO thread.
47 //
48 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
49 // code.
50 class CastSocket : public ApiResource,
51                    public base::SupportsWeakPtr<CastSocket> {
52  public:
53   // Object to be informed of incoming messages and errors.
54   class Delegate {
55    public:
56     // An error occurred on the channel.
57     virtual void OnError(const CastSocket* socket,
58                          ChannelError error) = 0;
59     // A string message was received on the channel.
60     virtual void OnMessage(const CastSocket* socket,
61                            const MessageInfo& message) = 0;
62    protected:
63     virtual ~Delegate() {}
64   };
65
66   // Creates a new CastSocket to |url|. |owner_extension_id| is the id of the
67   // extension that opened the socket.
68   CastSocket(const std::string& owner_extension_id,
69              const GURL& url,
70              CastSocket::Delegate* delegate,
71              net::NetLog* net_log);
72   virtual ~CastSocket();
73
74   // The URL for the channel.
75   const GURL& url() const;
76
77   // Whether to perform receiver authentication.
78   bool auth_required() const { return auth_required_; }
79
80   // Channel id for the ApiResourceManager.
81   int id() const { return channel_id_; }
82
83   // Sets the channel id.
84   void set_id(int channel_id) { channel_id_ = channel_id; }
85
86   // Returns the state of the channel.
87   ReadyState ready_state() const { return ready_state_; }
88
89   // Returns the last error that occurred on this channel, or CHANNEL_ERROR_NONE
90   // if no error has occurred.
91   ChannelError error_state() const { return error_state_; }
92
93   // Connects the channel to the peer. If successful, the channel will be in
94   // READY_STATE_OPEN.
95   virtual void Connect(const net::CompletionCallback& callback);
96
97   // Sends a message over a connected channel. The channel must be in
98   // READY_STATE_OPEN.
99   virtual void SendMessage(const MessageInfo& message,
100                            const net::CompletionCallback& callback);
101
102   // Closes the channel. On completion, the channel will be in
103   // READY_STATE_CLOSED.
104   virtual void Close(const net::CompletionCallback& callback);
105
106   // Fills |channel_info| with the status of this channel.
107   virtual void FillChannelInfo(ChannelInfo* channel_info) const;
108
109  protected:
110   // Creates an instance of TCPClientSocket.
111   virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket();
112   // Creates an instance of SSLClientSocket.
113   virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket();
114   // Extracts peer certificate from SSLClientSocket instance when the socket
115   // is in cert error state.
116   // Returns whether certificate is successfully extracted.
117   virtual bool ExtractPeerCert(std::string* cert);
118   // Sends a challenge request to the receiver.
119   virtual int SendAuthChallenge();
120   // Reads auth challenge reply from the receiver.
121   virtual int ReadAuthChallengeReply();
122   // Verifies whether the challenge reply received from the peer is valid:
123   // 1. Signature in the reply is valid.
124   // 2. Certificate is rooted to a trusted CA.
125   virtual bool VerifyChallengeReply();
126
127   // Returns whether we are executing in a valid thread.
128   virtual bool CalledOnValidThread() const;
129
130  private:
131   friend class ApiResourceManager<CastSocket>;
132   friend class CastSocketTest;
133
134   static const char* service_name() {
135     return "CastSocketManager";
136   }
137
138   // Internal connection states.
139   enum ConnectionState {
140     CONN_STATE_NONE,
141     CONN_STATE_TCP_CONNECT,
142     CONN_STATE_TCP_CONNECT_COMPLETE,
143     CONN_STATE_SSL_CONNECT,
144     CONN_STATE_SSL_CONNECT_COMPLETE,
145     CONN_STATE_AUTH_CHALLENGE_SEND,
146     CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE,
147     CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE,
148   };
149
150   /////////////////////////////////////////////////////////////////////////////
151   // Following methods work together to implement the following flow:
152   // 1. Create a new TCP socket and connect to it
153   // 2. Create a new SSL socket and try connecting to it
154   // 3. If connection fails due to invalid cert authority, then extract the
155   //    peer certificate from the error.
156   // 4. Whitelist the peer certificate and try #1 and #2 again.
157   // 5. If SSL socket is connected successfully, and if protocol is casts://
158   //    then issue an auth challenge request.
159   // 6. Validate the auth challenge response.
160
161   // Main method that performs connection state transitions.
162   int DoConnectLoop(int result);
163   // Each of the below Do* method is executed in the corresponding
164   // connection state. For e.g. when connection state is TCP_CONNECT
165   // DoTcpConnect is called, and so on.
166   int DoTcpConnect();
167   int DoTcpConnectComplete(int result);
168   int DoSslConnect();
169   int DoSslConnectComplete(int result);
170   int DoAuthChallengeSend();
171   int DoAuthChallengeSendComplete(int result);
172   int DoAuthChallengeReplyComplete(int result);
173   /////////////////////////////////////////////////////////////////////////////
174
175   // Callback method for callbacks from underlying sockets.
176   void OnConnectComplete(int result);
177
178   // Callback method when a challenge request is sent or a reply is received.
179   void OnChallengeEvent(int result);
180
181   // Runs the external connection callback and resets it.
182   void DoConnectCallback(int result);
183
184   // Verifies that the URL is a valid cast:// or casts:// URL and sets url_ to
185   // the result.
186   bool ParseChannelUrl(const GURL& url);
187
188   // Sends the given |message| and invokes the given callback when done.
189   int SendMessageInternal(const CastMessage& message,
190                           const net::CompletionCallback& callback);
191
192   // Writes data to the socket from the WriteRequest at the head of the queue.
193   // Calls OnWriteData() on completion.
194   int WriteData();
195   void OnWriteData(int result);
196
197   // Reads data from the socket into one of the read buffers. Calls
198   // OnReadData() on completion.
199   int ReadData();
200   void OnReadData(int result);
201
202   // Processes the contents of header_read_buffer_ and returns true on success.
203   bool ProcessHeader();
204   // Processes the contents of body_read_buffer_ and returns true on success.
205   bool ProcessBody();
206   // Parses the message held in body_read_buffer_ and notifies |delegate_| if a
207   // message was extracted from the buffer.  Returns true on success.
208   bool ParseMessageFromBody();
209
210   // Serializes the content of message_proto (with a header) to |message_data|.
211   static bool Serialize(const CastMessage& message_proto,
212                         std::string* message_data);
213
214   // Closes the socket and sets |error_state_|. Also signals |error| via
215   // |delegate_|.
216   void CloseWithError(ChannelError error);
217
218   base::ThreadChecker thread_checker_;
219
220   // The id of the channel.
221   int channel_id_;
222
223   // The URL of the peer (cast:// or casts://).
224   GURL url_;
225   // Delegate to inform of incoming messages and errors.
226   Delegate* delegate_;
227   // True if we should perform receiver authentication.
228   bool auth_required_;
229   // The IP endpoint of the peer.
230   net::IPEndPoint ip_endpoint_;
231   // The last error encountered by the channel.
232   ChannelError error_state_;
233   // The current status of the channel.
234   ReadyState ready_state_;
235
236   // True when there is a write callback pending.
237   bool write_callback_pending_;
238   // True when there is a read callback pending.
239   bool read_callback_pending_;
240
241   // IOBuffer for reading the message header.
242   scoped_refptr<net::GrowableIOBuffer> header_read_buffer_;
243   // IOBuffer for reading the message body.
244   scoped_refptr<net::GrowableIOBuffer> body_read_buffer_;
245   // IOBuffer we are currently reading into.
246   scoped_refptr<net::GrowableIOBuffer> current_read_buffer_;
247   // The number of bytes in the current message body.
248   uint32 current_message_size_;
249
250   // The NetLog for this service.
251   net::NetLog* net_log_;
252   // The NetLog source for this service.
253   net::NetLog::Source net_log_source_;
254
255   // Next connection state to transition to.
256   ConnectionState next_state_;
257   // Owned ptr to the underlying TCP socket.
258   scoped_ptr<net::TCPClientSocket> tcp_socket_;
259   // Owned ptr to the underlying SSL socket.
260   scoped_ptr<net::SSLClientSocket> socket_;
261   // Certificate of the peer. This field may be empty if the peer
262   // certificate is not yet fetched.
263   std::string peer_cert_;
264   scoped_ptr<net::CertVerifier> cert_verifier_;
265   scoped_ptr<net::TransportSecurityState> transport_security_state_;
266   // Reply received from the receiver to a challenge request.
267   scoped_ptr<CastMessage> challenge_reply_;
268
269   // Callback invoked when the socket is connected.
270   net::CompletionCallback connect_callback_;
271
272   // Message header struct. If fields are added, be sure to update
273   // kMessageHeaderSize in the .cc.
274   struct MessageHeader {
275     MessageHeader();
276     // Sets the message size.
277     void SetMessageSize(size_t message_size);
278     // Prepends this header to |str|.
279     void PrependToString(std::string* str);
280     // Reads |header| from the beginning of |buffer|.
281     static void ReadFromIOBuffer(net::GrowableIOBuffer* buffer,
282                                  MessageHeader* header);
283     std::string ToString();
284     // The size of the following protocol message in bytes, in host byte order.
285     uint32 message_size;
286   };
287
288   // Holds a message to be written to the socket. |callback| is invoked when the
289   // message is fully written or an error occurrs.
290   struct WriteRequest {
291     explicit WriteRequest(const net::CompletionCallback& callback);
292     ~WriteRequest();
293     // Sets the content of the request by serializing |message| into |io_buffer|
294     // and prepending the header.  Must only be called once.
295     bool SetContent(const CastMessage& message_proto);
296
297     net::CompletionCallback callback;
298     scoped_refptr<net::DrainableIOBuffer> io_buffer;
299   };
300   // Queue of pending writes. The message at the front of the queue is the one
301   // being written.
302   std::queue<WriteRequest> write_queue_;
303
304   // Used to protect against DoConnectLoop() re-entrancy.
305   bool in_connect_loop_;
306
307   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestCastURLs);
308   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead);
309   FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany);
310   DISALLOW_COPY_AND_ASSIGN(CastSocket);
311 };
312
313 }  // namespace cast_channel
314 }  // namespace api
315 }  // namespace extensions
316
317 #endif  // CHROME_BROWSER_EXTENSIONS_API_CAST_CHANNEL_CAST_SOCKET_H_