OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/p2p/ipc_socket_factory.h" | 5 #include "chrome/renderer/p2p/ipc_socket_factory.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
9 #include "chrome/renderer/p2p/socket_client.h" | 9 #include "chrome/renderer/p2p/socket_client.h" |
10 #include "chrome/renderer/p2p/socket_dispatcher.h" | 10 #include "chrome/renderer/p2p/socket_dispatcher.h" |
11 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" | 11 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 const size_t kIPv4AddressSize = 4; | 15 const size_t kIPv4AddressSize = 4; |
16 | 16 |
17 // Chromium and libjingle represent socket addresses differently. The | 17 // Chromium and libjingle represent socket addresses differently. The |
18 // following two functions are used to convert addresses from one | 18 // following two functions are used to convert addresses from one |
19 // representation to another. | 19 // representation to another. |
20 bool ChromeToLibjingleSocketAddress(const P2PSocketAddress& address_chrome, | 20 bool ChromeToLibjingleSocketAddress(const net::IPEndPoint& address_chrome, |
21 talk_base::SocketAddress* address_lj) { | 21 talk_base::SocketAddress* address_lj) { |
22 if (address_chrome.address.size() != kIPv4AddressSize) { | 22 if (address_chrome.GetFamily() != AF_INET) { |
23 LOG(ERROR) << "Only IPv4 addresses are supported."; | 23 LOG(ERROR) << "Only IPv4 addresses are supported."; |
24 return false; | 24 return false; |
25 } | 25 } |
26 uint32 ip_as_int = ntohl(*reinterpret_cast<const uint32*>( | 26 uint32 ip_as_int = ntohl(*reinterpret_cast<const uint32*>( |
27 &address_chrome.address[0])); | 27 &address_chrome.address()[0])); |
28 *address_lj = talk_base::SocketAddress(ip_as_int, address_chrome.port); | 28 *address_lj = talk_base::SocketAddress(ip_as_int, address_chrome.port()); |
29 return true; | 29 return true; |
30 } | 30 } |
31 | 31 |
32 bool LibjingleToChromeSocketAddress(const talk_base::SocketAddress& address_lj, | 32 bool LibjingleToIPEndPoint(const talk_base::SocketAddress& address_lj, |
33 P2PSocketAddress* address_chrome) { | 33 net::IPEndPoint* address_chrome) { |
34 uint32 ip = htonl(address_lj.ip()); | 34 uint32 ip = htonl(address_lj.ip()); |
35 address_chrome->address.resize(kIPv4AddressSize); | 35 net::IPAddressNumber address; |
36 memcpy(&address_chrome->address[0], &ip, kIPv4AddressSize); | 36 address.resize(kIPv4AddressSize); |
37 address_chrome->port = address_lj.port(); | 37 memcpy(&address[0], &ip, kIPv4AddressSize); |
| 38 *address_chrome = net::IPEndPoint(address, address_lj.port()); |
38 return true; | 39 return true; |
39 } | 40 } |
40 | 41 |
41 // IpcPacketSocket implements talk_base::AsyncPacketSocket interface | 42 // IpcPacketSocket implements talk_base::AsyncPacketSocket interface |
42 // using P2PSocketClient that works over IPC-channel. It must be used | 43 // using P2PSocketClient that works over IPC-channel. It must be used |
43 // on the thread it was created. | 44 // on the thread it was created. |
44 class IpcPacketSocket : public talk_base::AsyncPacketSocket, | 45 class IpcPacketSocket : public talk_base::AsyncPacketSocket, |
45 public P2PSocketClient::Delegate { | 46 public P2PSocketClient::Delegate { |
46 public: | 47 public: |
47 IpcPacketSocket(); | 48 IpcPacketSocket(); |
48 virtual ~IpcPacketSocket(); | 49 virtual ~IpcPacketSocket(); |
49 | 50 |
50 bool Init(P2PSocketType type, P2PSocketClient* client, | 51 bool Init(P2PSocketType type, P2PSocketClient* client, |
51 const talk_base::SocketAddress& address); | 52 const talk_base::SocketAddress& address); |
52 | 53 |
53 // talk_base::AsyncPacketSocket interface. | 54 // talk_base::AsyncPacketSocket interface. |
54 virtual talk_base::SocketAddress GetLocalAddress(bool* allocated) const; | 55 virtual talk_base::SocketAddress GetLocalAddress(bool* allocated) const; |
55 virtual talk_base::SocketAddress GetRemoteAddress() const; | 56 virtual talk_base::SocketAddress GetRemoteAddress() const; |
56 virtual int Send(const void *pv, size_t cb); | 57 virtual int Send(const void *pv, size_t cb); |
57 virtual int SendTo(const void *pv, size_t cb, | 58 virtual int SendTo(const void *pv, size_t cb, |
58 const talk_base::SocketAddress& addr); | 59 const talk_base::SocketAddress& addr); |
59 virtual int Close(); | 60 virtual int Close(); |
60 virtual talk_base::Socket::ConnState GetState() const; | 61 virtual talk_base::Socket::ConnState GetState() const; |
61 virtual int GetOption(talk_base::Socket::Option opt, int* value); | 62 virtual int GetOption(talk_base::Socket::Option opt, int* value); |
62 virtual int SetOption(talk_base::Socket::Option opt, int value); | 63 virtual int SetOption(talk_base::Socket::Option opt, int value); |
63 virtual int GetError() const; | 64 virtual int GetError() const; |
64 virtual void SetError(int error); | 65 virtual void SetError(int error); |
65 | 66 |
66 // P2PSocketClient::Delegate | 67 // P2PSocketClient::Delegate |
67 virtual void OnOpen(const P2PSocketAddress& address); | 68 virtual void OnOpen(const net::IPEndPoint& address); |
68 virtual void OnError(); | 69 virtual void OnError(); |
69 virtual void OnDataReceived(const P2PSocketAddress& address, | 70 virtual void OnDataReceived(const net::IPEndPoint& address, |
70 const std::vector<char>& data); | 71 const std::vector<char>& data); |
71 | 72 |
72 private: | 73 private: |
73 enum State { | 74 enum State { |
74 STATE_UNINITIALIZED, | 75 STATE_UNINITIALIZED, |
75 STATE_OPENING, | 76 STATE_OPENING, |
76 STATE_OPEN, | 77 STATE_OPEN, |
77 STATE_CLOSED, | 78 STATE_CLOSED, |
78 STATE_ERROR, | 79 STATE_ERROR, |
79 }; | 80 }; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 118 |
118 bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client, | 119 bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client, |
119 const talk_base::SocketAddress& address) { | 120 const talk_base::SocketAddress& address) { |
120 DCHECK_EQ(MessageLoop::current(), message_loop_); | 121 DCHECK_EQ(MessageLoop::current(), message_loop_); |
121 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 122 DCHECK_EQ(state_, STATE_UNINITIALIZED); |
122 | 123 |
123 client_ = client; | 124 client_ = client; |
124 remote_address_ = address; | 125 remote_address_ = address; |
125 state_ = STATE_OPENING; | 126 state_ = STATE_OPENING; |
126 | 127 |
127 P2PSocketAddress address_chrome; | 128 net::IPEndPoint address_chrome; |
128 if (!LibjingleToChromeSocketAddress(address, &address_chrome)) { | 129 if (!LibjingleToIPEndPoint(address, &address_chrome)) { |
129 return false; | 130 return false; |
130 } | 131 } |
131 | 132 |
132 client_->Init(type, address_chrome, this, | 133 client_->Init(type, address_chrome, this, |
133 base::MessageLoopProxy::CreateForCurrentThread()); | 134 base::MessageLoopProxy::CreateForCurrentThread()); |
134 | 135 |
135 return true; | 136 return true; |
136 } | 137 } |
137 | 138 |
138 // talk_base::AsyncPacketSocket interface. | 139 // talk_base::AsyncPacketSocket interface. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 case STATE_ERROR: | 171 case STATE_ERROR: |
171 return error_; | 172 return error_; |
172 case STATE_OPEN: | 173 case STATE_OPEN: |
173 // Continue sending the packet. | 174 // Continue sending the packet. |
174 break; | 175 break; |
175 } | 176 } |
176 | 177 |
177 const char* data_char = reinterpret_cast<const char*>(data); | 178 const char* data_char = reinterpret_cast<const char*>(data); |
178 std::vector<char> data_vector(data_char, data_char + data_size); | 179 std::vector<char> data_vector(data_char, data_char + data_size); |
179 | 180 |
180 P2PSocketAddress address_chrome; | 181 net::IPEndPoint address_chrome; |
181 if (!LibjingleToChromeSocketAddress(address, &address_chrome)) { | 182 if (!LibjingleToIPEndPoint(address, &address_chrome)) { |
182 // Just drop the packet if we failed to convert the address. | 183 // Just drop the packet if we failed to convert the address. |
183 return 0; | 184 return 0; |
184 } | 185 } |
185 | 186 |
186 client_->Send(address_chrome, data_vector); | 187 client_->Send(address_chrome, data_vector); |
187 | 188 |
188 // Fake successful send. The caller ignores result anyway. | 189 // Fake successful send. The caller ignores result anyway. |
189 return data_size; | 190 return data_size; |
190 } | 191 } |
191 | 192 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 int IpcPacketSocket::GetError() const { | 238 int IpcPacketSocket::GetError() const { |
238 DCHECK_EQ(MessageLoop::current(), message_loop_); | 239 DCHECK_EQ(MessageLoop::current(), message_loop_); |
239 return error_; | 240 return error_; |
240 } | 241 } |
241 | 242 |
242 void IpcPacketSocket::SetError(int error) { | 243 void IpcPacketSocket::SetError(int error) { |
243 DCHECK_EQ(MessageLoop::current(), message_loop_); | 244 DCHECK_EQ(MessageLoop::current(), message_loop_); |
244 error_ = error; | 245 error_ = error; |
245 } | 246 } |
246 | 247 |
247 void IpcPacketSocket::OnOpen(const P2PSocketAddress& address) { | 248 void IpcPacketSocket::OnOpen(const net::IPEndPoint& address) { |
248 DCHECK_EQ(MessageLoop::current(), message_loop_); | 249 DCHECK_EQ(MessageLoop::current(), message_loop_); |
249 | 250 |
250 if (!ChromeToLibjingleSocketAddress(address, &local_address_)) { | 251 if (!ChromeToLibjingleSocketAddress(address, &local_address_)) { |
251 // Always expect correct IPv4 address to be allocated. | 252 // Always expect correct IPv4 address to be allocated. |
252 NOTREACHED(); | 253 NOTREACHED(); |
253 } | 254 } |
254 SignalAddressReady(this, local_address_); | 255 SignalAddressReady(this, local_address_); |
255 address_initialized_ = true; | 256 address_initialized_ = true; |
256 state_ = STATE_OPEN; | 257 state_ = STATE_OPEN; |
257 } | 258 } |
258 | 259 |
259 void IpcPacketSocket::OnError() { | 260 void IpcPacketSocket::OnError() { |
260 DCHECK_EQ(MessageLoop::current(), message_loop_); | 261 DCHECK_EQ(MessageLoop::current(), message_loop_); |
261 state_ = STATE_ERROR; | 262 state_ = STATE_ERROR; |
262 error_ = ECONNABORTED; | 263 error_ = ECONNABORTED; |
263 } | 264 } |
264 | 265 |
265 void IpcPacketSocket::OnDataReceived(const P2PSocketAddress& address, | 266 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address, |
266 const std::vector<char>& data) { | 267 const std::vector<char>& data) { |
267 DCHECK_EQ(MessageLoop::current(), message_loop_); | 268 DCHECK_EQ(MessageLoop::current(), message_loop_); |
268 | 269 |
269 talk_base::SocketAddress address_lj; | 270 talk_base::SocketAddress address_lj; |
270 if (!ChromeToLibjingleSocketAddress(address, &address_lj)) { | 271 if (!ChromeToLibjingleSocketAddress(address, &address_lj)) { |
271 // We should always be able to convert address here because we | 272 // We should always be able to convert address here because we |
272 // don't expect IPv6 address on IPv4 connections. | 273 // don't expect IPv6 address on IPv4 connections. |
273 NOTREACHED(); | 274 NOTREACHED(); |
274 return; | 275 return; |
275 } | 276 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 314 |
314 talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket( | 315 talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket( |
315 const talk_base::SocketAddress& local_address, | 316 const talk_base::SocketAddress& local_address, |
316 const talk_base::SocketAddress& remote_address, | 317 const talk_base::SocketAddress& remote_address, |
317 const talk_base::ProxyInfo& proxy_info, | 318 const talk_base::ProxyInfo& proxy_info, |
318 const std::string& user_agent, bool ssl) { | 319 const std::string& user_agent, bool ssl) { |
319 // TODO(sergeyu): Implement this; | 320 // TODO(sergeyu): Implement this; |
320 NOTIMPLEMENTED(); | 321 NOTIMPLEMENTED(); |
321 return NULL; | 322 return NULL; |
322 } | 323 } |
OLD | NEW |