| 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 |