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#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_
6#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "net/base/address_list.h"
14#include "net/base/completion_callback.h"
15#include "ppapi/c/pp_stdint.h"
16#include "ppapi/c/ppb_tcp_socket.h"
17
18struct PP_NetAddress_Private;
19
20namespace ppapi {
21class PPB_X509Certificate_Fields;
22class SocketOptionData;
23}
24
25namespace net {
26class DrainableIOBuffer;
27class IOBuffer;
28class SingleRequestHostResolver;
29class StreamSocket;
30class X509Certificate;
31}
32
33namespace content {
34class PepperMessageFilter;
35
36// PepperTCPSocket is used by PepperMessageFilter to handle requests from
37// the Pepper TCP socket API (PPB_TCPSocket and PPB_TCPSocket_Private).
38class PepperTCPSocket {
39 public:
40  PepperTCPSocket(PepperMessageFilter* manager,
41                  int32 routing_id,
42                  uint32 plugin_dispatcher_id,
43                  uint32 socket_id,
44                  bool private_api);
45
46  // Used for creation already connected sockets.  Takes ownership of
47  // |socket|.
48  PepperTCPSocket(PepperMessageFilter* manager,
49                  int32 routing_id,
50                  uint32 plugin_dispatcher_id,
51                  uint32 socket_id,
52                  net::StreamSocket* socket,
53                  bool private_api);
54  ~PepperTCPSocket();
55
56  int routing_id() { return routing_id_; }
57  bool private_api() const { return private_api_; }
58
59  void Connect(const std::string& host, uint16_t port);
60  void ConnectWithNetAddress(const PP_NetAddress_Private& net_addr);
61  void SSLHandshake(
62      const std::string& server_name,
63      uint16_t server_port,
64      const std::vector<std::vector<char> >& trusted_certs,
65      const std::vector<std::vector<char> >& untrusted_certs);
66  void Read(int32 bytes_to_read);
67  void Write(const std::string& data);
68  void SetOption(PP_TCPSocket_Option name,
69                 const ppapi::SocketOptionData& value);
70
71  void SendConnectACKError(int32_t error);
72
73  // Extracts the certificate field data from a |net::X509Certificate| into
74  // |PPB_X509Certificate_Fields|.
75  static bool GetCertificateFields(const net::X509Certificate& cert,
76                                   ppapi::PPB_X509Certificate_Fields* fields);
77  // Extracts the certificate field data from the DER representation of a
78  // certificate into |PPB_X509Certificate_Fields|.
79  static bool GetCertificateFields(const char* der,
80                                   uint32_t length,
81                                   ppapi::PPB_X509Certificate_Fields* fields);
82
83 private:
84  enum ConnectionState {
85    // Before a connection is successfully established (including a previous
86    // connect request failed).
87    BEFORE_CONNECT,
88    // There is a connect request that is pending.
89    CONNECT_IN_PROGRESS,
90    // A connection has been successfully established.
91    CONNECTED,
92    // There is an SSL handshake request that is pending.
93    SSL_HANDSHAKE_IN_PROGRESS,
94    // An SSL connection has been successfully established.
95    SSL_CONNECTED,
96    // An SSL handshake has failed.
97    SSL_HANDSHAKE_FAILED
98  };
99
100  void StartConnect(const net::AddressList& addresses);
101
102  void SendReadACKError(int32_t error);
103  void SendWriteACKError(int32_t error);
104  void SendSSLHandshakeACK(bool succeeded);
105  void SendSetOptionACK(int32_t result);
106
107  void OnResolveCompleted(int net_result);
108  void OnConnectCompleted(int net_result);
109  void OnSSLHandshakeCompleted(int net_result);
110  void OnReadCompleted(int net_result);
111  void OnWriteCompleted(int net_result);
112
113  bool IsConnected() const;
114  bool IsSsl() const;
115
116  // Actually does a write from |write_buffer_|; possibly called many times for
117  // each |Write()|.
118  void DoWrite();
119
120  PepperMessageFilter* manager_;
121  int32 routing_id_;
122  uint32 plugin_dispatcher_id_;
123  uint32 socket_id_;
124  bool private_api_;
125
126  ConnectionState connection_state_;
127  bool end_of_file_reached_;
128
129  scoped_ptr<net::SingleRequestHostResolver> resolver_;
130  net::AddressList address_list_;
131
132  scoped_ptr<net::StreamSocket> socket_;
133
134  scoped_refptr<net::IOBuffer> read_buffer_;
135
136  // |StreamSocket::Write()| may not always write the full buffer, but we would
137  // rather have our |Write()| do so whenever possible. To do this, we may have
138  // to call the former multiple times for each of the latter. This entails
139  // using a |DrainableIOBuffer|, which requires an underlying base |IOBuffer|.
140  scoped_refptr<net::IOBuffer> write_buffer_base_;
141  scoped_refptr<net::DrainableIOBuffer> write_buffer_;
142
143  DISALLOW_COPY_AND_ASSIGN(PepperTCPSocket);
144};
145
146}  // namespace content
147
148#endif  // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_
149