Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / extensions / browser / api / cast_channel / cast_socket.h
blob55d7b94356cd05b329511b30cad1656e5fa3ca7a
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/cancelable_callback.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/threading/thread_checker.h"
16 #include "base/timer/timer.h"
17 #include "extensions/browser/api/api_resource.h"
18 #include "extensions/browser/api/api_resource_manager.h"
19 #include "extensions/browser/api/cast_channel/cast_socket.h"
20 #include "extensions/browser/api/cast_channel/cast_transport.h"
21 #include "extensions/browser/api/cast_channel/logger_util.h"
22 #include "extensions/common/api/cast_channel.h"
23 #include "extensions/common/api/cast_channel/logging.pb.h"
24 #include "net/base/completion_callback.h"
25 #include "net/base/io_buffer.h"
26 #include "net/base/ip_endpoint.h"
27 #include "net/log/net_log.h"
29 namespace net {
30 class AddressList;
31 class CertVerifier;
32 class SSLClientSocket;
33 class StreamSocket;
34 class TCPClientSocket;
35 class TransportSecurityState;
38 namespace extensions {
39 namespace core_api {
40 namespace cast_channel {
41 class CastMessage;
42 class Logger;
43 struct LastErrors;
44 class MessageFramer;
46 // Cast device capabilities.
47 enum CastDeviceCapability {
48 NONE = 0,
49 VIDEO_OUT = 1 << 0,
50 VIDEO_IN = 1 << 1,
51 AUDIO_OUT = 1 << 2,
52 AUDIO_IN = 1 << 3,
53 DEV_MODE = 1 << 4
56 // Public interface of the CastSocket class.
57 class CastSocket : public ApiResource {
58 public:
59 explicit CastSocket(const std::string& owner_extension_id);
60 ~CastSocket() override {}
62 // Used by BrowserContextKeyedAPIFactory.
63 static const char* service_name() { return "CastSocketImplManager"; }
65 // Connects the channel to the peer. If successful, the channel will be in
66 // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|.
67 // Instead use Close().
68 // |callback| will be invoked with any ChannelError that occurred, or
69 // CHANNEL_ERROR_NONE if successful.
70 // |delegate| receives message receipt and error events.
71 // Ownership of |delegate| is transferred to this CastSocket.
72 virtual void Connect(scoped_ptr<CastTransport::Delegate> delegate,
73 base::Callback<void(ChannelError)> callback) = 0;
75 // Closes the channel if not already closed. On completion, the channel will
76 // be in READY_STATE_CLOSED.
78 // It is fine to delete this object in |callback|.
79 virtual void Close(const net::CompletionCallback& callback) = 0;
81 // The IP endpoint for the destination of the channel.
82 virtual const net::IPEndPoint& ip_endpoint() const = 0;
84 // Channel id generated by the ApiResourceManager.
85 virtual int id() const = 0;
87 // Sets the channel id generated by ApiResourceManager.
88 virtual void set_id(int id) = 0;
90 // The authentication level requested for the channel.
91 virtual ChannelAuthType channel_auth() const = 0;
93 // Returns a cast:// or casts:// URL for the channel endpoint.
94 // For backwards compatibility.
95 virtual std::string cast_url() const = 0;
97 // The ready state of the channel.
98 virtual ReadyState ready_state() const = 0;
100 // Returns the last error that occurred on this channel, or
101 // CHANNEL_ERROR_NONE if no error has occurred.
102 virtual ChannelError error_state() const = 0;
104 // True when keep-alive signaling is handled for this socket.
105 virtual bool keep_alive() const = 0;
107 // Marks a socket as invalid due to an error, and sends an OnError
108 // event to |delegate_|.
109 // The OnError event receipient is responsible for closing the socket in the
110 // event of an error.
111 // Setting the error state does not close the socket if it is open.
112 virtual void SetErrorState(ChannelError error_state) = 0;
114 // Returns a pointer to the socket's message transport layer. Can be used to
115 // send and receive CastMessages over the socket.
116 virtual CastTransport* transport() const = 0;
118 // Tells the ApiResourceManager to retain CastSocket objects even
119 // if their corresponding extension is suspended.
120 // (CastSockets are still deleted if the extension is removed entirely from
121 // the browser.)
122 bool IsPersistent() const override;
125 // This class implements a channel between Chrome and a Cast device using a TCP
126 // socket with SSL. The channel may authenticate that the receiver is a genuine
127 // Cast device. All CastSocketImpl objects must be used only on the IO thread.
129 // NOTE: Not called "CastChannel" to reduce confusion with the generated API
130 // code.
131 class CastSocketImpl : public CastSocket {
132 public:
133 // Creates a new CastSocket that connects to |ip_endpoint| with
134 // |channel_auth|. |owner_extension_id| is the id of the extension that opened
135 // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE.
136 // Parameters:
137 // |owner_extension_id|: ID of the extension calling the API.
138 // |ip_endpoint|: IP address of the remote host.
139 // |channel_auth|: Authentication method used for connecting to a Cast
140 // receiver.
141 // |net_log|: Log of socket events.
142 // |connect_timeout|: Connection timeout interval.
143 // |logger|: Log of cast channel events.
144 CastSocketImpl(const std::string& owner_extension_id,
145 const net::IPEndPoint& ip_endpoint,
146 ChannelAuthType channel_auth,
147 net::NetLog* net_log,
148 const base::TimeDelta& connect_timeout,
149 bool keep_alive,
150 const scoped_refptr<Logger>& logger,
151 uint64 device_capabilities);
153 // Ensures that the socket is closed.
154 ~CastSocketImpl() override;
156 // CastSocket interface.
157 void Connect(scoped_ptr<CastTransport::Delegate> delegate,
158 base::Callback<void(ChannelError)> callback) override;
159 CastTransport* transport() const override;
160 void Close(const net::CompletionCallback& callback) override;
161 const net::IPEndPoint& ip_endpoint() const override;
162 int id() const override;
163 void set_id(int channel_id) override;
164 ChannelAuthType channel_auth() const override;
165 std::string cast_url() const override;
166 ReadyState ready_state() const override;
167 ChannelError error_state() const override;
168 bool keep_alive() const override;
170 // Required by ApiResourceManager.
171 static const char* service_name() { return "CastSocketManager"; }
173 protected:
174 // CastTransport::Delegate methods for receiving handshake messages.
175 class AuthTransportDelegate : public CastTransport::Delegate {
176 public:
177 explicit AuthTransportDelegate(CastSocketImpl* socket);
179 // Gets the error state of the channel.
180 // Returns CHANNEL_ERROR_NONE if no errors are present.
181 ChannelError error_state() const;
183 // Gets recorded error details.
184 LastErrors last_errors() const;
186 // CastTransport::Delegate interface.
187 void OnError(ChannelError error_state) override;
188 void OnMessage(const CastMessage& message) override;
189 void Start() override;
191 private:
192 CastSocketImpl* socket_;
193 ChannelError error_state_;
194 LastErrors last_errors_;
197 // Replaces the internally-constructed transport object with one provided
198 // by the caller (e.g. a mock).
199 void SetTransportForTesting(scoped_ptr<CastTransport> transport);
201 // Verifies whether the socket complies with cast channel policy.
202 // Audio only channel policy mandates that a device declaring a video out
203 // capability must not have a certificate with audio only policy.
204 bool VerifyChannelPolicy(const AuthResult& result);
206 private:
207 FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestConnectAuthMessageCorrupted);
208 FRIEND_TEST_ALL_PREFIXES(CastSocketTest,
209 TestConnectChallengeReplyReceiveError);
210 FRIEND_TEST_ALL_PREFIXES(CastSocketTest,
211 TestConnectChallengeVerificationFails);
212 friend class AuthTransportDelegate;
213 friend class ApiResourceManager<CastSocketImpl>;
214 friend class CastSocketTest;
215 friend class TestCastSocket;
217 void SetErrorState(ChannelError error_state) override;
219 // Frees resources and cancels pending callbacks. |ready_state_| will be set
220 // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already
221 // READY_STATE_CLOSED.
222 void CloseInternal();
224 // Creates an instance of TCPClientSocket.
225 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket();
226 // Creates an instance of SSLClientSocket with the given underlying |socket|.
227 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket(
228 scoped_ptr<net::StreamSocket> socket);
229 // Extracts peer certificate from SSLClientSocket instance when the socket
230 // is in cert error state.
231 // Returns whether certificate is successfully extracted.
232 virtual bool ExtractPeerCert(std::string* cert);
233 // Verifies whether the challenge reply received from the peer is valid:
234 // 1. Signature in the reply is valid.
235 // 2. Certificate is rooted to a trusted CA.
236 virtual bool VerifyChallengeReply();
238 // Invoked by a cancelable closure when connection setup time
239 // exceeds the interval specified at |connect_timeout|.
240 void OnConnectTimeout();
242 /////////////////////////////////////////////////////////////////////////////
243 // Following methods work together to implement the following flow:
244 // 1. Create a new TCP socket and connect to it
245 // 2. Create a new SSL socket and try connecting to it
246 // 3. If connection fails due to invalid cert authority, then extract the
247 // peer certificate from the error.
248 // 4. Whitelist the peer certificate and try #1 and #2 again.
249 // 5. If SSL socket is connected successfully, and if protocol is casts://
250 // then issue an auth challenge request.
251 // 6. Validate the auth challenge response.
253 // Main method that performs connection state transitions.
254 void DoConnectLoop(int result);
255 // Each of the below Do* method is executed in the corresponding
256 // connection state. For example when connection state is TCP_CONNECT
257 // DoTcpConnect is called, and so on.
258 int DoTcpConnect();
259 int DoTcpConnectComplete(int result);
260 int DoSslConnect();
261 int DoSslConnectComplete(int result);
262 int DoAuthChallengeSend();
263 int DoAuthChallengeSendComplete(int result);
264 int DoAuthChallengeReplyComplete(int result);
265 /////////////////////////////////////////////////////////////////////////////
267 // Schedules asynchrous connection loop processing in the MessageLoop.
268 void PostTaskToStartConnectLoop(int result);
270 // Runs the external connection callback and resets it.
271 void DoConnectCallback();
273 virtual bool CalledOnValidThread() const;
275 virtual base::Timer* GetTimer();
277 void SetConnectState(proto::ConnectionState connect_state);
278 void SetReadyState(ReadyState ready_state);
280 base::ThreadChecker thread_checker_;
282 const std::string owner_extension_id_;
283 // The id of the channel.
284 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 // The NetLog for this service.
290 net::NetLog* net_log_;
291 // The NetLog source for this service.
292 net::NetLog::Source net_log_source_;
293 // True when keep-alive signaling should be handled for this socket.
294 bool keep_alive_;
296 // Shared logging object, used to log CastSocket events for diagnostics.
297 scoped_refptr<Logger> logger_;
299 // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket
300 // since in some cases the destructor of SSLClientSocket may call a method
301 // to cancel a cert verification request.
302 scoped_ptr<net::CertVerifier> cert_verifier_;
303 scoped_ptr<net::TransportSecurityState> transport_security_state_;
305 // Owned ptr to the underlying TCP socket.
306 scoped_ptr<net::TCPClientSocket> tcp_socket_;
308 // Owned ptr to the underlying SSL socket.
309 scoped_ptr<net::SSLClientSocket> socket_;
311 // Certificate of the peer. This field may be empty if the peer
312 // certificate is not yet fetched.
313 std::string peer_cert_;
315 // Reply received from the receiver to a challenge request.
316 scoped_ptr<CastMessage> challenge_reply_;
318 // Callback invoked when the socket is connected or fails to connect.
319 base::Callback<void(ChannelError)> connect_callback_;
321 // Callback invoked by |connect_timeout_timer_| to cancel the connection.
322 base::CancelableClosure connect_timeout_callback_;
324 // Duration to wait before timing out.
325 base::TimeDelta connect_timeout_;
327 // Timer invoked when the connection has timed out.
328 scoped_ptr<base::Timer> connect_timeout_timer_;
330 // Set when a timeout is triggered and the connection process has
331 // canceled.
332 bool is_canceled_;
334 // Capabilities declared by the cast device.
335 uint64 device_capabilities_;
337 // Connection flow state machine state.
338 proto::ConnectionState connect_state_;
340 // Write flow state machine state.
341 proto::WriteState write_state_;
343 // Read flow state machine state.
344 proto::ReadState read_state_;
346 // The last error encountered by the channel.
347 ChannelError error_state_;
349 // The current status of the channel.
350 ReadyState ready_state_;
352 // Task invoked to (re)start the connect loop. Canceled on entry to the
353 // connect loop.
354 base::CancelableClosure connect_loop_callback_;
356 // Task invoked to send the auth challenge. Canceled when the auth challenge
357 // has been sent.
358 base::CancelableClosure send_auth_challenge_callback_;
360 // Cast message formatting and parsing layer.
361 scoped_ptr<CastTransport> transport_;
363 // Caller's message read and error handling delegate.
364 scoped_ptr<CastTransport::Delegate> delegate_;
366 // Raw pointer to the auth handshake delegate. Used to get detailed error
367 // information.
368 AuthTransportDelegate* auth_delegate_;
370 DISALLOW_COPY_AND_ASSIGN(CastSocketImpl);
372 } // namespace cast_channel
373 } // namespace core_api
374 } // namespace extensions
376 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_