Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: chrome/renderer/p2p/ipc_socket_factory.cc

Issue 6673090: Move core renderer subdirectories to content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/p2p/ipc_socket_factory.h ('k') | chrome/renderer/p2p/socket_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #include "chrome/renderer/p2p/ipc_socket_factory.h"
6
7 #include "base/message_loop.h"
8 #include "base/message_loop_proxy.h"
9 #include "chrome/renderer/p2p/socket_client.h"
10 #include "chrome/renderer/p2p/socket_dispatcher.h"
11 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
12
13 namespace {
14
15 const size_t kIPv4AddressSize = 4;
16
17 // Chromium and libjingle represent socket addresses differently. The
18 // following two functions are used to convert addresses from one
19 // representation to another.
20 bool ChromeToLibjingleSocketAddress(const net::IPEndPoint& address_chrome,
21 talk_base::SocketAddress* address_lj) {
22 if (address_chrome.GetFamily() != AF_INET) {
23 LOG(ERROR) << "Only IPv4 addresses are supported.";
24 return false;
25 }
26 uint32 ip_as_int = ntohl(*reinterpret_cast<const uint32*>(
27 &address_chrome.address()[0]));
28 *address_lj = talk_base::SocketAddress(ip_as_int, address_chrome.port());
29 return true;
30 }
31
32 bool LibjingleToIPEndPoint(const talk_base::SocketAddress& address_lj,
33 net::IPEndPoint* address_chrome) {
34 uint32 ip = htonl(address_lj.ip());
35 net::IPAddressNumber address;
36 address.resize(kIPv4AddressSize);
37 memcpy(&address[0], &ip, kIPv4AddressSize);
38 *address_chrome = net::IPEndPoint(address, address_lj.port());
39 return true;
40 }
41
42 // IpcPacketSocket implements talk_base::AsyncPacketSocket interface
43 // using P2PSocketClient that works over IPC-channel. It must be used
44 // on the thread it was created.
45 class IpcPacketSocket : public talk_base::AsyncPacketSocket,
46 public P2PSocketClient::Delegate {
47 public:
48 IpcPacketSocket();
49 virtual ~IpcPacketSocket();
50
51 bool Init(P2PSocketType type, P2PSocketClient* client,
52 const talk_base::SocketAddress& address);
53
54 // talk_base::AsyncPacketSocket interface.
55 virtual talk_base::SocketAddress GetLocalAddress(bool* allocated) const;
56 virtual talk_base::SocketAddress GetRemoteAddress() const;
57 virtual int Send(const void *pv, size_t cb);
58 virtual int SendTo(const void *pv, size_t cb,
59 const talk_base::SocketAddress& addr);
60 virtual int Close();
61 virtual talk_base::Socket::ConnState GetState() const;
62 virtual int GetOption(talk_base::Socket::Option opt, int* value);
63 virtual int SetOption(talk_base::Socket::Option opt, int value);
64 virtual int GetError() const;
65 virtual void SetError(int error);
66
67 // P2PSocketClient::Delegate
68 virtual void OnOpen(const net::IPEndPoint& address);
69 virtual void OnError();
70 virtual void OnDataReceived(const net::IPEndPoint& address,
71 const std::vector<char>& data);
72
73 private:
74 enum State {
75 STATE_UNINITIALIZED,
76 STATE_OPENING,
77 STATE_OPEN,
78 STATE_CLOSED,
79 STATE_ERROR,
80 };
81
82 // Message loop on which this socket was created and being used.
83 MessageLoop* message_loop_;
84
85 // Corresponding P2P socket client.
86 scoped_refptr<P2PSocketClient> client_;
87
88 // Local address is allocated by the browser process, and the
89 // renderer side doesn't know the address until it receives OnOpen()
90 // event from the browser.
91 talk_base::SocketAddress local_address_;
92 bool address_initialized_;
93
94 // Remote address for client TCP connections.
95 talk_base::SocketAddress remote_address_;
96
97 // Current state of the object.
98 State state_;
99
100 // Current error code. Valid when state_ == STATE_ERROR.
101 int error_;
102
103 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket);
104 };
105
106 IpcPacketSocket::IpcPacketSocket()
107 : message_loop_(MessageLoop::current()),
108 address_initialized_(false),
109 state_(STATE_UNINITIALIZED), error_(0) {
110 }
111
112 IpcPacketSocket::~IpcPacketSocket() {
113 if (state_ == STATE_OPENING || state_ == STATE_OPEN ||
114 state_ == STATE_ERROR) {
115 Close();
116 }
117 }
118
119 bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client,
120 const talk_base::SocketAddress& address) {
121 DCHECK_EQ(MessageLoop::current(), message_loop_);
122 DCHECK_EQ(state_, STATE_UNINITIALIZED);
123
124 client_ = client;
125 remote_address_ = address;
126 state_ = STATE_OPENING;
127
128 net::IPEndPoint address_chrome;
129 if (!LibjingleToIPEndPoint(address, &address_chrome)) {
130 return false;
131 }
132
133 client_->Init(type, address_chrome, this,
134 base::MessageLoopProxy::CreateForCurrentThread());
135
136 return true;
137 }
138
139 // talk_base::AsyncPacketSocket interface.
140 talk_base::SocketAddress IpcPacketSocket::GetLocalAddress(
141 bool* allocated) const {
142 DCHECK_EQ(MessageLoop::current(), message_loop_);
143
144 *allocated = address_initialized_;
145 return local_address_;
146 }
147
148 talk_base::SocketAddress IpcPacketSocket::GetRemoteAddress() const {
149 DCHECK_EQ(MessageLoop::current(), message_loop_);
150
151 return remote_address_;
152 }
153
154 int IpcPacketSocket::Send(const void *data, size_t data_size) {
155 DCHECK_EQ(MessageLoop::current(), message_loop_);
156 return SendTo(data, data_size, remote_address_);
157 }
158
159 int IpcPacketSocket::SendTo(const void *data, size_t data_size,
160 const talk_base::SocketAddress& address) {
161 DCHECK_EQ(MessageLoop::current(), message_loop_);
162
163 switch (state_) {
164 case STATE_UNINITIALIZED:
165 NOTREACHED();
166 return EWOULDBLOCK;
167 case STATE_OPENING:
168 return EWOULDBLOCK;
169 case STATE_CLOSED:
170 return ENOTCONN;
171 case STATE_ERROR:
172 return error_;
173 case STATE_OPEN:
174 // Continue sending the packet.
175 break;
176 }
177
178 const char* data_char = reinterpret_cast<const char*>(data);
179 std::vector<char> data_vector(data_char, data_char + data_size);
180
181 net::IPEndPoint address_chrome;
182 if (!LibjingleToIPEndPoint(address, &address_chrome)) {
183 // Just drop the packet if we failed to convert the address.
184 return 0;
185 }
186
187 client_->Send(address_chrome, data_vector);
188
189 // Fake successful send. The caller ignores result anyway.
190 return data_size;
191 }
192
193 int IpcPacketSocket::Close() {
194 DCHECK_EQ(MessageLoop::current(), message_loop_);
195
196 client_->Close();
197 state_ = STATE_CLOSED;
198
199 return 0;
200 }
201
202 talk_base::Socket::ConnState IpcPacketSocket::GetState() const {
203 DCHECK_EQ(MessageLoop::current(), message_loop_);
204
205 switch (state_) {
206 case STATE_UNINITIALIZED:
207 NOTREACHED();
208 return talk_base::Socket::CS_CONNECTING;
209
210 case STATE_OPENING:
211 return talk_base::Socket::CS_CONNECTING;
212
213 case STATE_OPEN:
214 return talk_base::Socket::CS_CONNECTED;
215
216 case STATE_CLOSED:
217 case STATE_ERROR:
218 return talk_base::Socket::CS_CLOSED;
219 }
220
221 NOTREACHED();
222 return talk_base::Socket::CS_CLOSED;
223 }
224
225 int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) {
226 // We don't support socket options for IPC sockets.
227 return -1;
228 }
229
230 int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
231 // We don't support socket options for IPC sockets.
232 //
233 // TODO(sergeyu): Make sure we set proper socket options on the
234 // browser side.
235 return -1;
236 }
237
238 int IpcPacketSocket::GetError() const {
239 DCHECK_EQ(MessageLoop::current(), message_loop_);
240 return error_;
241 }
242
243 void IpcPacketSocket::SetError(int error) {
244 DCHECK_EQ(MessageLoop::current(), message_loop_);
245 error_ = error;
246 }
247
248 void IpcPacketSocket::OnOpen(const net::IPEndPoint& address) {
249 DCHECK_EQ(MessageLoop::current(), message_loop_);
250
251 if (!ChromeToLibjingleSocketAddress(address, &local_address_)) {
252 // Always expect correct IPv4 address to be allocated.
253 NOTREACHED();
254 }
255 SignalAddressReady(this, local_address_);
256 address_initialized_ = true;
257 state_ = STATE_OPEN;
258 }
259
260 void IpcPacketSocket::OnError() {
261 DCHECK_EQ(MessageLoop::current(), message_loop_);
262 state_ = STATE_ERROR;
263 error_ = ECONNABORTED;
264 }
265
266 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address,
267 const std::vector<char>& data) {
268 DCHECK_EQ(MessageLoop::current(), message_loop_);
269
270 talk_base::SocketAddress address_lj;
271 if (!ChromeToLibjingleSocketAddress(address, &address_lj)) {
272 // We should always be able to convert address here because we
273 // don't expect IPv6 address on IPv4 connections.
274 NOTREACHED();
275 return;
276 }
277
278 SignalReadPacket(this, &data[0], data.size(), address_lj);
279 }
280
281 } // namespace
282
283 IpcPacketSocketFactory::IpcPacketSocketFactory(
284 P2PSocketDispatcher* socket_dispatcher)
285 : socket_dispatcher_(socket_dispatcher) {
286 }
287
288 IpcPacketSocketFactory::~IpcPacketSocketFactory() {
289 }
290
291 talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateUdpSocket(
292 const talk_base::SocketAddress& local_address, int min_port, int max_port) {
293 talk_base::SocketAddress crome_address;
294 P2PSocketClient* socket_client = new P2PSocketClient(socket_dispatcher_);
295 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket());
296 // TODO(sergeyu): Respect local_address and port limits here (need
297 // to pass them over IPC channel to the browser).
298 if (!socket->Init(P2P_SOCKET_UDP, socket_client,
299 talk_base::SocketAddress())) {
300 return NULL;
301 }
302
303 // Socket increments reference count if Init() was successful.
304 return socket.release();
305 }
306
307 talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateServerTcpSocket(
308 const talk_base::SocketAddress& local_address, int min_port, int max_port,
309 bool listen, bool ssl) {
310 // TODO(sergeyu): Implement this;
311 NOTIMPLEMENTED();
312 return NULL;
313 }
314
315 talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket(
316 const talk_base::SocketAddress& local_address,
317 const talk_base::SocketAddress& remote_address,
318 const talk_base::ProxyInfo& proxy_info,
319 const std::string& user_agent, bool ssl) {
320 // TODO(sergeyu): Implement this;
321 NOTIMPLEMENTED();
322 return NULL;
323 }
OLDNEW
« no previous file with comments | « chrome/renderer/p2p/ipc_socket_factory.h ('k') | chrome/renderer/p2p/socket_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698