Extensions: Move bluetooth APIs to extensions/.
[chromium-blink-merge.git] / extensions / browser / api / cast_channel / cast_socket.h
blob7bcd513bba76ea7554084dc3512c29ebf87d0ffa
1 // Copyright 2014 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.
5 #ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_
8 #include <queue>
9 #include <string>
11 #include "base/basictypes.h"
12 #include "base/callback.h"
13 #include "base/cancelable_callback.h"
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/timer/timer.h"
19 #include "extensions/browser/api/api_resource.h"
20 #include "extensions/browser/api/api_resource_manager.h"
21 #include "extensions/common/api/cast_channel.h"
22 #include "net/base/completion_callback.h"
23 #include "net/base/io_buffer.h"
24 #include "net/base/ip_endpoint.h"
25 #include "net/base/net_log.h"
27 namespace net {
28 class AddressList;
29 class CertVerifier;
30 class SSLClientSocket;
31 class StreamSocket;
32 class TCPClientSocket;
33 class TransportSecurityState;
36 namespace extensions {
37 namespace core_api {
38 namespace cast_channel {
40 class CastMessage;
42 // This class implements a channel between Chrome and a Cast device using a TCP
43 // socket with SSL. The channel may authenticate that the receiver is a genuine
44 // Cast device. All CastSocket objects must be used only on the IO thread.
46 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
47 // code.
48 class CastSocket : public ApiResource,
49 public base::SupportsWeakPtr<CastSocket> {
50 public:
51 // Object to be informed of incoming messages and errors.
52 class Delegate {
53 public:
54 // An error occurred on the channel.
55 // It is fine to delete the socket in this callback.
56 virtual void OnError(const CastSocket* socket, ChannelError error) = 0;
57 // A message was received on the channel.
58 // Do NOT delete the socket in this callback.
59 virtual void OnMessage(const CastSocket* socket,
60 const MessageInfo& message) = 0;
62 protected:
63 virtual ~Delegate() {}
66 // Creates a new CastSocket that connects to |ip_endpoint| with
67 // |channel_auth|. |owner_extension_id| is the id of the extension that opened
68 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE.
69 CastSocket(const std::string& owner_extension_id,
70 const net::IPEndPoint& ip_endpoint,
71 ChannelAuthType channel_auth,
72 CastSocket::Delegate* delegate,
73 net::NetLog* net_log,
74 const base::TimeDelta& connect_timeout);
75 virtual ~CastSocket();
77 // The IP endpoint for the destination of the channel.
78 const net::IPEndPoint& ip_endpoint() const { return ip_endpoint_; }
80 // The authentication level requested for the channel.
81 ChannelAuthType channel_auth() const { return channel_auth_; }
83 // Returns a cast:// or casts:// URL for the channel endpoint.
84 // For backwards compatibility.
85 std::string CastUrl() const;
87 // Channel id for the ApiResourceManager.
88 int id() const { return channel_id_; }
90 // Sets the channel id.
91 void set_id(int channel_id) { channel_id_ = channel_id; }
93 // Returns the state of the channel. Virtual for testing.
94 virtual ReadyState ready_state() const;
96 // Returns the last error that occurred on this channel, or
97 // CHANNEL_ERROR_NONE if no error has occurred. Virtual for testing.
98 virtual ChannelError error_state() const;
100 // Connects the channel to the peer. If successful, the channel will be in
101 // READY_STATE_OPEN.
102 // It is fine to delete the CastSocket object in |callback|.
103 virtual void Connect(const net::CompletionCallback& callback);
105 // Sends a message over a connected channel. The channel must be in
106 // READY_STATE_OPEN.
108 // Note that if an error occurs the following happens:
109 // 1. Completion callbacks for all pending writes are invoked with error.
110 // 2. Delegate::OnError is called once.
111 // 3. Castsocket is closed.
113 // DO NOT delete the CastSocket object in write completion callback.
114 // But it is fine to delete the socket in Delegate::OnError
115 virtual void SendMessage(const MessageInfo& message,
116 const net::CompletionCallback& callback);
118 // Closes the channel. On completion, the channel will be in
119 // READY_STATE_CLOSED.
120 // It is fine to delete the CastSocket object in |callback|.
121 virtual void Close(const net::CompletionCallback& callback);
123 protected:
124 // Message header struct. If fields are added, be sure to update
125 // header_size(). Protected to allow use of *_size() methods in unit tests.
126 struct MessageHeader {
127 MessageHeader();
128 // Sets the message size.
129 void SetMessageSize(size_t message_size);
130 // Prepends this header to |str|.
131 void PrependToString(std::string* str);
132 // Reads |header| from the beginning of |buffer|.
133 static void ReadFromIOBuffer(net::GrowableIOBuffer* buffer,
134 MessageHeader* header);
135 // Size (in bytes) of the message header.
136 static uint32 header_size() { return sizeof(uint32); }
138 // Maximum size (in bytes) of a message payload on the wire (does not
139 // include header).
140 static uint32 max_message_size() { return 65536; }
142 std::string ToString();
143 // The size of the following protocol message in bytes, in host byte order.
144 uint32 message_size;
147 private:
148 friend class ApiResourceManager<CastSocket>;
149 friend class CastSocketTest;
150 friend class TestCastSocket;
152 static const char* service_name() { return "CastSocketManager"; }
154 // Internal connection states.
155 enum ConnectionState {
156 CONN_STATE_NONE,
157 CONN_STATE_TCP_CONNECT,
158 CONN_STATE_TCP_CONNECT_COMPLETE,
159 CONN_STATE_SSL_CONNECT,
160 CONN_STATE_SSL_CONNECT_COMPLETE,
161 CONN_STATE_AUTH_CHALLENGE_SEND,
162 CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE,
163 CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE,
166 // Internal write states.
167 enum WriteState {
168 WRITE_STATE_NONE,
169 WRITE_STATE_WRITE,
170 WRITE_STATE_WRITE_COMPLETE,
171 WRITE_STATE_DO_CALLBACK,
172 WRITE_STATE_ERROR,
175 // Internal read states.
176 enum ReadState {
177 READ_STATE_NONE,
178 READ_STATE_READ,
179 READ_STATE_READ_COMPLETE,
180 READ_STATE_DO_CALLBACK,
181 READ_STATE_ERROR,
184 // Creates an instance of TCPClientSocket.
185 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket();
186 // Creates an instance of SSLClientSocket with the given underlying |socket|.
187 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket(
188 scoped_ptr<net::StreamSocket> socket);
189 // Extracts peer certificate from SSLClientSocket instance when the socket
190 // is in cert error state.
191 // Returns whether certificate is successfully extracted.
192 virtual bool ExtractPeerCert(std::string* cert);
193 // Verifies whether the challenge reply received from the peer is valid:
194 // 1. Signature in the reply is valid.
195 // 2. Certificate is rooted to a trusted CA.
196 virtual bool VerifyChallengeReply();
198 // Invoked by a cancelable closure when connection setup time
199 // exceeds the interval specified at |connect_timeout|.
200 void CancelConnect();
202 /////////////////////////////////////////////////////////////////////////////
203 // Following methods work together to implement the following flow:
204 // 1. Create a new TCP socket and connect to it
205 // 2. Create a new SSL socket and try connecting to it
206 // 3. If connection fails due to invalid cert authority, then extract the
207 // peer certificate from the error.
208 // 4. Whitelist the peer certificate and try #1 and #2 again.
209 // 5. If SSL socket is connected successfully, and if protocol is casts://
210 // then issue an auth challenge request.
211 // 6. Validate the auth challenge response.
213 // Main method that performs connection state transitions.
214 void DoConnectLoop(int result);
215 // Each of the below Do* method is executed in the corresponding
216 // connection state. For example when connection state is TCP_CONNECT
217 // DoTcpConnect is called, and so on.
218 int DoTcpConnect();
219 int DoTcpConnectComplete(int result);
220 int DoSslConnect();
221 int DoSslConnectComplete(int result);
222 int DoAuthChallengeSend();
223 int DoAuthChallengeSendComplete(int result);
224 int DoAuthChallengeReplyComplete(int result);
225 /////////////////////////////////////////////////////////////////////////////
227 /////////////////////////////////////////////////////////////////////////////
228 // Following methods work together to implement write flow.
230 // Main method that performs write flow state transitions.
231 void DoWriteLoop(int result);
232 // Each of the below Do* method is executed in the corresponding
233 // write state. For example when write state is WRITE_STATE_WRITE_COMPLETE
234 // DowriteComplete is called, and so on.
235 int DoWrite();
236 int DoWriteComplete(int result);
237 int DoWriteCallback();
238 int DoWriteError(int result);
239 /////////////////////////////////////////////////////////////////////////////
241 /////////////////////////////////////////////////////////////////////////////
242 // Following methods work together to implement read flow.
244 // Main method that performs write flow state transitions.
245 void DoReadLoop(int result);
246 // Each of the below Do* method is executed in the corresponding
247 // write state. For example when write state is READ_STATE_READ_COMPLETE
248 // DoReadComplete is called, and so on.
249 int DoRead();
250 int DoReadComplete(int result);
251 int DoReadCallback();
252 int DoReadError(int result);
253 /////////////////////////////////////////////////////////////////////////////
255 // Runs the external connection callback and resets it.
256 void DoConnectCallback(int result);
257 // Adds |message| to the write queue and starts the write loop if needed.
258 void SendCastMessageInternal(const CastMessage& message,
259 const net::CompletionCallback& callback);
260 void PostTaskToStartConnectLoop(int result);
261 void PostTaskToStartReadLoop();
262 void StartReadLoop();
263 // Parses the contents of header_read_buffer_ and sets current_message_size_
264 // to the size of the body of the message.
265 bool ProcessHeader();
266 // Parses the contents of body_read_buffer_ and sets current_message_ to
267 // the message received.
268 bool ProcessBody();
269 // Closes socket, updating the error state and signaling the delegate that
270 // |error| has occurred.
271 void CloseWithError(ChannelError error);
272 // Serializes the content of message_proto (with a header) to |message_data|.
273 static bool Serialize(const CastMessage& message_proto,
274 std::string* message_data);
276 virtual bool CalledOnValidThread() const;
278 virtual base::Timer* GetTimer();
280 base::ThreadChecker thread_checker_;
282 // The id of the channel.
283 int channel_id_;
285 // The IP endpoint that the the channel is connected to.
286 net::IPEndPoint ip_endpoint_;
287 // Receiver authentication requested for the channel.
288 ChannelAuthType channel_auth_;
289 // Delegate to inform of incoming messages and errors.
290 Delegate* delegate_;
292 // IOBuffer for reading the message header.
293 scoped_refptr<net::GrowableIOBuffer> header_read_buffer_;
294 // IOBuffer for reading the message body.
295 scoped_refptr<net::GrowableIOBuffer> body_read_buffer_;
296 // IOBuffer to currently read into.
297 scoped_refptr<net::GrowableIOBuffer> current_read_buffer_;
298 // The number of bytes in the current message body.
299 uint32 current_message_size_;
300 // Last message received on the socket.
301 scoped_ptr<CastMessage> current_message_;
303 // The NetLog for this service.
304 net::NetLog* net_log_;
305 // The NetLog source for this service.
306 net::NetLog::Source net_log_source_;
308 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket
309 // since in some cases the destructor of SSLClientSocket may call a method
310 // to cancel a cert verification request.
311 scoped_ptr<net::CertVerifier> cert_verifier_;
312 scoped_ptr<net::TransportSecurityState> transport_security_state_;
314 // Owned ptr to the underlying TCP socket.
315 scoped_ptr<net::TCPClientSocket> tcp_socket_;
316 // Owned ptr to the underlying SSL socket.
317 scoped_ptr<net::SSLClientSocket> socket_;
318 // Certificate of the peer. This field may be empty if the peer
319 // certificate is not yet fetched.
320 std::string peer_cert_;
321 // Reply received from the receiver to a challenge request.
322 scoped_ptr<CastMessage> challenge_reply_;
324 // Callback invoked when the socket is connected or fails to connect.
325 net::CompletionCallback connect_callback_;
327 // Duration to wait before timing out.
328 base::TimeDelta connect_timeout_;
329 // Timer invoked when the connection has timed out.
330 scoped_ptr<base::Timer> connect_timeout_timer_;
331 // Set when a timeout is triggered and the connection process has
332 // canceled.
333 bool is_canceled_;
335 // Connection flow state machine state.
336 ConnectionState connect_state_;
337 // Write flow state machine state.
338 WriteState write_state_;
339 // Read flow state machine state.
340 ReadState read_state_;
341 // The last error encountered by the channel.
342 ChannelError error_state_;
343 // The current status of the channel.
344 ReadyState ready_state_;
346 // Holds a message to be written to the socket. |callback| is invoked when the
347 // message is fully written or an error occurrs.
348 struct WriteRequest {
349 explicit WriteRequest(const net::CompletionCallback& callback);
350 ~WriteRequest();
351 // Sets the content of the request by serializing |message| into |io_buffer|
352 // and prepending the header. Must only be called once.
353 bool SetContent(const CastMessage& message_proto);
355 net::CompletionCallback callback;
356 scoped_refptr<net::DrainableIOBuffer> io_buffer;
358 // Queue of pending writes. The message at the front of the queue is the one
359 // being written.
360 std::queue<WriteRequest> write_queue_;
362 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestFullSecureConnectionFlowAsync);
363 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead);
364 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadHeaderParseError);
365 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany);
366 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestWriteErrorLargeMessage);
367 DISALLOW_COPY_AND_ASSIGN(CastSocket);
370 } // namespace cast_channel
371 } // namespace core_api
372 } // namespace extensions
374 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_