| 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 "content/renderer/p2p/ipc_socket_factory.h" | 5 #include "content/renderer/p2p/ipc_socket_factory.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
| 10 #include "content/renderer/p2p/socket_client.h" | 10 #include "content/renderer/p2p/socket_client.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 public: | 22 public: |
| 23 IpcPacketSocket(); | 23 IpcPacketSocket(); |
| 24 virtual ~IpcPacketSocket(); | 24 virtual ~IpcPacketSocket(); |
| 25 | 25 |
| 26 // Always takes ownership of client even if initialization fails. | 26 // Always takes ownership of client even if initialization fails. |
| 27 bool Init(P2PSocketType type, P2PSocketClient* client, | 27 bool Init(P2PSocketType type, P2PSocketClient* client, |
| 28 const talk_base::SocketAddress& local_address, | 28 const talk_base::SocketAddress& local_address, |
| 29 const talk_base::SocketAddress& remote_address); | 29 const talk_base::SocketAddress& remote_address); |
| 30 | 30 |
| 31 // talk_base::AsyncPacketSocket interface. | 31 // talk_base::AsyncPacketSocket interface. |
| 32 virtual bool GetLocalAddress(talk_base::SocketAddress* address) const; | 32 virtual talk_base::SocketAddress GetLocalAddress() const; |
| 33 virtual talk_base::SocketAddress GetRemoteAddress() const; | 33 virtual talk_base::SocketAddress GetRemoteAddress() const; |
| 34 virtual int Send(const void *pv, size_t cb); | 34 virtual int Send(const void *pv, size_t cb); |
| 35 virtual int SendTo(const void *pv, size_t cb, | 35 virtual int SendTo(const void *pv, size_t cb, |
| 36 const talk_base::SocketAddress& addr); | 36 const talk_base::SocketAddress& addr); |
| 37 virtual int Close(); | 37 virtual int Close(); |
| 38 virtual talk_base::Socket::ConnState GetState() const; | 38 virtual State GetState() const; |
| 39 virtual int GetOption(talk_base::Socket::Option opt, int* value); | 39 virtual int GetOption(talk_base::Socket::Option opt, int* value); |
| 40 virtual int SetOption(talk_base::Socket::Option opt, int value); | 40 virtual int SetOption(talk_base::Socket::Option opt, int value); |
| 41 virtual int GetError() const; | 41 virtual int GetError() const; |
| 42 virtual void SetError(int error); | 42 virtual void SetError(int error); |
| 43 | 43 |
| 44 // P2PSocketClient::Delegate implementation. | 44 // P2PSocketClient::Delegate implementation. |
| 45 virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE; | 45 virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE; |
| 46 virtual void OnIncomingTcpConnection(const net::IPEndPoint& address, | 46 virtual void OnIncomingTcpConnection(const net::IPEndPoint& address, |
| 47 P2PSocketClient* client) OVERRIDE; | 47 P2PSocketClient* client) OVERRIDE; |
| 48 virtual void OnError(); | 48 virtual void OnError(); |
| 49 virtual void OnDataReceived(const net::IPEndPoint& address, | 49 virtual void OnDataReceived(const net::IPEndPoint& address, |
| 50 const std::vector<char>& data) OVERRIDE; | 50 const std::vector<char>& data) OVERRIDE; |
| 51 | 51 |
| 52 private: | 52 private: |
| 53 enum State { | 53 enum InternalState { |
| 54 STATE_UNINITIALIZED, | 54 IS_UNINITIALIZED, |
| 55 STATE_OPENING, | 55 IS_OPENING, |
| 56 STATE_OPEN, | 56 IS_OPEN, |
| 57 STATE_CLOSED, | 57 IS_CLOSED, |
| 58 STATE_ERROR, | 58 IS_ERROR, |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 void InitAcceptedTcp(P2PSocketClient* client, | 61 void InitAcceptedTcp(P2PSocketClient* client, |
| 62 const talk_base::SocketAddress& local_address, | 62 const talk_base::SocketAddress& local_address, |
| 63 const talk_base::SocketAddress& remote_address); | 63 const talk_base::SocketAddress& remote_address); |
| 64 | 64 |
| 65 P2PSocketType type_; |
| 66 |
| 65 // Message loop on which this socket was created and being used. | 67 // Message loop on which this socket was created and being used. |
| 66 MessageLoop* message_loop_; | 68 MessageLoop* message_loop_; |
| 67 | 69 |
| 68 // Corresponding P2P socket client. | 70 // Corresponding P2P socket client. |
| 69 scoped_refptr<P2PSocketClient> client_; | 71 scoped_refptr<P2PSocketClient> client_; |
| 70 | 72 |
| 71 // Local address is allocated by the browser process, and the | 73 // Local address is allocated by the browser process, and the |
| 72 // renderer side doesn't know the address until it receives OnOpen() | 74 // renderer side doesn't know the address until it receives OnOpen() |
| 73 // event from the browser. | 75 // event from the browser. |
| 74 talk_base::SocketAddress local_address_; | 76 talk_base::SocketAddress local_address_; |
| 75 bool address_initialized_; | |
| 76 | 77 |
| 77 // Remote address for client TCP connections. | 78 // Remote address for client TCP connections. |
| 78 talk_base::SocketAddress remote_address_; | 79 talk_base::SocketAddress remote_address_; |
| 79 | 80 |
| 80 // Current state of the object. | 81 // Current state of the object. |
| 81 State state_; | 82 InternalState state_; |
| 82 | 83 |
| 83 // Current error code. Valid when state_ == STATE_ERROR. | 84 // Current error code. Valid when state_ == IS_ERROR. |
| 84 int error_; | 85 int error_; |
| 85 | 86 |
| 86 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); | 87 DISALLOW_COPY_AND_ASSIGN(IpcPacketSocket); |
| 87 }; | 88 }; |
| 88 | 89 |
| 89 IpcPacketSocket::IpcPacketSocket() | 90 IpcPacketSocket::IpcPacketSocket() |
| 90 : message_loop_(MessageLoop::current()), | 91 : message_loop_(MessageLoop::current()), |
| 91 address_initialized_(false), | 92 state_(IS_UNINITIALIZED), error_(0) { |
| 92 state_(STATE_UNINITIALIZED), error_(0) { | |
| 93 } | 93 } |
| 94 | 94 |
| 95 IpcPacketSocket::~IpcPacketSocket() { | 95 IpcPacketSocket::~IpcPacketSocket() { |
| 96 if (state_ == STATE_OPENING || state_ == STATE_OPEN || | 96 if (state_ == IS_OPENING || state_ == IS_OPEN || |
| 97 state_ == STATE_ERROR) { | 97 state_ == IS_ERROR) { |
| 98 Close(); | 98 Close(); |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 | 101 |
| 102 bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client, | 102 bool IpcPacketSocket::Init(P2PSocketType type, P2PSocketClient* client, |
| 103 const talk_base::SocketAddress& local_address, | 103 const talk_base::SocketAddress& local_address, |
| 104 const talk_base::SocketAddress& remote_address) { | 104 const talk_base::SocketAddress& remote_address) { |
| 105 DCHECK_EQ(MessageLoop::current(), message_loop_); | 105 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 106 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 106 DCHECK_EQ(state_, IS_UNINITIALIZED); |
| 107 | 107 |
| 108 type_ = type; |
| 108 client_ = client; | 109 client_ = client; |
| 109 local_address_ = local_address; | 110 local_address_ = local_address; |
| 110 remote_address_ = remote_address; | 111 remote_address_ = remote_address; |
| 111 state_ = STATE_OPENING; | 112 state_ = IS_OPENING; |
| 112 | 113 |
| 113 net::IPEndPoint local_endpoint; | 114 net::IPEndPoint local_endpoint; |
| 114 if (!jingle_glue::SocketAddressToIPEndPoint(local_address, &local_endpoint)) { | 115 if (!jingle_glue::SocketAddressToIPEndPoint(local_address, &local_endpoint)) { |
| 115 return false; | 116 return false; |
| 116 } | 117 } |
| 117 | 118 |
| 118 net::IPEndPoint remote_endpoint; | 119 net::IPEndPoint remote_endpoint; |
| 119 if (!jingle_glue::SocketAddressToIPEndPoint( | 120 if (!jingle_glue::SocketAddressToIPEndPoint( |
| 120 remote_address, &remote_endpoint)) { | 121 remote_address, &remote_endpoint)) { |
| 121 return false; | 122 return false; |
| 122 } | 123 } |
| 123 | 124 |
| 124 client_->Init(type, local_endpoint, remote_endpoint, this, | 125 client_->Init(type, local_endpoint, remote_endpoint, this, |
| 125 base::MessageLoopProxy::CreateForCurrentThread()); | 126 base::MessageLoopProxy::CreateForCurrentThread()); |
| 126 | 127 |
| 127 return true; | 128 return true; |
| 128 } | 129 } |
| 129 | 130 |
| 130 void IpcPacketSocket::InitAcceptedTcp( | 131 void IpcPacketSocket::InitAcceptedTcp( |
| 131 P2PSocketClient* client, | 132 P2PSocketClient* client, |
| 132 const talk_base::SocketAddress& local_address, | 133 const talk_base::SocketAddress& local_address, |
| 133 const talk_base::SocketAddress& remote_address) { | 134 const talk_base::SocketAddress& remote_address) { |
| 134 DCHECK_EQ(MessageLoop::current(), message_loop_); | 135 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 135 DCHECK_EQ(state_, STATE_UNINITIALIZED); | 136 DCHECK_EQ(state_, IS_UNINITIALIZED); |
| 136 | 137 |
| 137 client_ = client; | 138 client_ = client; |
| 138 local_address_ = local_address; | 139 local_address_ = local_address; |
| 139 remote_address_ = remote_address; | 140 remote_address_ = remote_address; |
| 140 state_ = STATE_OPEN; | 141 state_ = IS_OPEN; |
| 141 client_->set_delegate(this); | 142 client_->set_delegate(this); |
| 142 } | 143 } |
| 143 | 144 |
| 144 // talk_base::AsyncPacketSocket interface. | 145 // talk_base::AsyncPacketSocket interface. |
| 145 bool IpcPacketSocket::GetLocalAddress(talk_base::SocketAddress* address) const { | 146 talk_base::SocketAddress IpcPacketSocket::GetLocalAddress() const { |
| 146 DCHECK_EQ(MessageLoop::current(), message_loop_); | 147 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 147 | 148 return local_address_; |
| 148 if (!address_initialized_) | |
| 149 return false; | |
| 150 | |
| 151 *address = local_address_; | |
| 152 return true; | |
| 153 } | 149 } |
| 154 | 150 |
| 155 talk_base::SocketAddress IpcPacketSocket::GetRemoteAddress() const { | 151 talk_base::SocketAddress IpcPacketSocket::GetRemoteAddress() const { |
| 156 DCHECK_EQ(MessageLoop::current(), message_loop_); | 152 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 157 | |
| 158 return remote_address_; | 153 return remote_address_; |
| 159 } | 154 } |
| 160 | 155 |
| 161 int IpcPacketSocket::Send(const void *data, size_t data_size) { | 156 int IpcPacketSocket::Send(const void *data, size_t data_size) { |
| 162 DCHECK_EQ(MessageLoop::current(), message_loop_); | 157 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 163 return SendTo(data, data_size, remote_address_); | 158 return SendTo(data, data_size, remote_address_); |
| 164 } | 159 } |
| 165 | 160 |
| 166 int IpcPacketSocket::SendTo(const void *data, size_t data_size, | 161 int IpcPacketSocket::SendTo(const void *data, size_t data_size, |
| 167 const talk_base::SocketAddress& address) { | 162 const talk_base::SocketAddress& address) { |
| 168 DCHECK_EQ(MessageLoop::current(), message_loop_); | 163 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 169 | 164 |
| 170 switch (state_) { | 165 switch (state_) { |
| 171 case STATE_UNINITIALIZED: | 166 case IS_UNINITIALIZED: |
| 172 NOTREACHED(); | 167 NOTREACHED(); |
| 173 return EWOULDBLOCK; | 168 return EWOULDBLOCK; |
| 174 case STATE_OPENING: | 169 case IS_OPENING: |
| 175 return EWOULDBLOCK; | 170 return EWOULDBLOCK; |
| 176 case STATE_CLOSED: | 171 case IS_CLOSED: |
| 177 return ENOTCONN; | 172 return ENOTCONN; |
| 178 case STATE_ERROR: | 173 case IS_ERROR: |
| 179 return error_; | 174 return error_; |
| 180 case STATE_OPEN: | 175 case IS_OPEN: |
| 181 // Continue sending the packet. | 176 // Continue sending the packet. |
| 182 break; | 177 break; |
| 183 } | 178 } |
| 184 | 179 |
| 185 const char* data_char = reinterpret_cast<const char*>(data); | 180 const char* data_char = reinterpret_cast<const char*>(data); |
| 186 std::vector<char> data_vector(data_char, data_char + data_size); | 181 std::vector<char> data_vector(data_char, data_char + data_size); |
| 187 | 182 |
| 188 net::IPEndPoint address_chrome; | 183 net::IPEndPoint address_chrome; |
| 189 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { | 184 if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) { |
| 190 // Just drop the packet if we failed to convert the address. | 185 // Just drop the packet if we failed to convert the address. |
| 191 return 0; | 186 return 0; |
| 192 } | 187 } |
| 193 | 188 |
| 194 client_->Send(address_chrome, data_vector); | 189 client_->Send(address_chrome, data_vector); |
| 195 | 190 |
| 196 // Fake successful send. The caller ignores result anyway. | 191 // Fake successful send. The caller ignores result anyway. |
| 197 return data_size; | 192 return data_size; |
| 198 } | 193 } |
| 199 | 194 |
| 200 int IpcPacketSocket::Close() { | 195 int IpcPacketSocket::Close() { |
| 201 DCHECK_EQ(MessageLoop::current(), message_loop_); | 196 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 202 | 197 |
| 203 client_->Close(); | 198 client_->Close(); |
| 204 state_ = STATE_CLOSED; | 199 state_ = IS_CLOSED; |
| 205 | 200 |
| 206 return 0; | 201 return 0; |
| 207 } | 202 } |
| 208 | 203 |
| 209 talk_base::Socket::ConnState IpcPacketSocket::GetState() const { | 204 talk_base::AsyncPacketSocket::State IpcPacketSocket::GetState() const { |
| 210 DCHECK_EQ(MessageLoop::current(), message_loop_); | 205 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 211 | 206 |
| 212 switch (state_) { | 207 switch (state_) { |
| 213 case STATE_UNINITIALIZED: | 208 case IS_UNINITIALIZED: |
| 214 NOTREACHED(); | 209 NOTREACHED(); |
| 215 return talk_base::Socket::CS_CONNECTING; | 210 return STATE_CLOSED; |
| 216 | 211 |
| 217 case STATE_OPENING: | 212 case IS_OPENING: |
| 218 return talk_base::Socket::CS_CONNECTING; | 213 return STATE_BINDING; |
| 219 | 214 |
| 220 case STATE_OPEN: | 215 case IS_OPEN: |
| 221 return talk_base::Socket::CS_CONNECTED; | 216 if (type_ == P2P_SOCKET_TCP_CLIENT) { |
| 217 return STATE_CONNECTED; |
| 218 } else { |
| 219 return STATE_BOUND; |
| 220 } |
| 222 | 221 |
| 223 case STATE_CLOSED: | 222 case IS_CLOSED: |
| 224 case STATE_ERROR: | 223 case IS_ERROR: |
| 225 return talk_base::Socket::CS_CLOSED; | 224 return STATE_CLOSED; |
| 226 } | 225 } |
| 227 | 226 |
| 228 NOTREACHED(); | 227 NOTREACHED(); |
| 229 return talk_base::Socket::CS_CLOSED; | 228 return STATE_CLOSED; |
| 230 } | 229 } |
| 231 | 230 |
| 232 int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) { | 231 int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) { |
| 233 // We don't support socket options for IPC sockets. | 232 // We don't support socket options for IPC sockets. |
| 234 return -1; | 233 return -1; |
| 235 } | 234 } |
| 236 | 235 |
| 237 int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) { | 236 int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) { |
| 238 // We don't support socket options for IPC sockets. | 237 // We don't support socket options for IPC sockets. |
| 239 // | 238 // |
| (...skipping 15 matching lines...) Expand all Loading... |
| 255 void IpcPacketSocket::OnOpen(const net::IPEndPoint& address) { | 254 void IpcPacketSocket::OnOpen(const net::IPEndPoint& address) { |
| 256 DCHECK_EQ(MessageLoop::current(), message_loop_); | 255 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 257 | 256 |
| 258 if (!jingle_glue::IPEndPointToSocketAddress(address, &local_address_)) { | 257 if (!jingle_glue::IPEndPointToSocketAddress(address, &local_address_)) { |
| 259 // Always expect correct IPv4 address to be allocated. | 258 // Always expect correct IPv4 address to be allocated. |
| 260 NOTREACHED(); | 259 NOTREACHED(); |
| 261 OnError(); | 260 OnError(); |
| 262 return; | 261 return; |
| 263 } | 262 } |
| 264 SignalAddressReady(this, local_address_); | 263 SignalAddressReady(this, local_address_); |
| 265 address_initialized_ = true; | 264 if (type_ == P2P_SOCKET_TCP_CLIENT) |
| 266 state_ = STATE_OPEN; | 265 SignalConnect(this); |
| 266 state_ = IS_OPEN; |
| 267 } | 267 } |
| 268 | 268 |
| 269 void IpcPacketSocket::OnIncomingTcpConnection( | 269 void IpcPacketSocket::OnIncomingTcpConnection( |
| 270 const net::IPEndPoint& address, | 270 const net::IPEndPoint& address, |
| 271 P2PSocketClient* client) { | 271 P2PSocketClient* client) { |
| 272 DCHECK_EQ(MessageLoop::current(), message_loop_); | 272 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 273 | 273 |
| 274 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket()); | 274 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket()); |
| 275 | 275 |
| 276 talk_base::SocketAddress remote_address; | 276 talk_base::SocketAddress remote_address; |
| 277 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) { | 277 if (!jingle_glue::IPEndPointToSocketAddress(address, &remote_address)) { |
| 278 // Always expect correct IPv4 address to be allocated. | 278 // Always expect correct IPv4 address to be allocated. |
| 279 NOTREACHED(); | 279 NOTREACHED(); |
| 280 } | 280 } |
| 281 socket->InitAcceptedTcp(client, local_address_, remote_address); | 281 socket->InitAcceptedTcp(client, local_address_, remote_address); |
| 282 SignalNewConnection(this, socket.release()); | 282 SignalNewConnection(this, socket.release()); |
| 283 } | 283 } |
| 284 | 284 |
| 285 void IpcPacketSocket::OnError() { | 285 void IpcPacketSocket::OnError() { |
| 286 DCHECK_EQ(MessageLoop::current(), message_loop_); | 286 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 287 state_ = STATE_ERROR; | 287 state_ = IS_ERROR; |
| 288 error_ = ECONNABORTED; | 288 error_ = ECONNABORTED; |
| 289 } | 289 } |
| 290 | 290 |
| 291 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address, | 291 void IpcPacketSocket::OnDataReceived(const net::IPEndPoint& address, |
| 292 const std::vector<char>& data) { | 292 const std::vector<char>& data) { |
| 293 DCHECK_EQ(MessageLoop::current(), message_loop_); | 293 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 294 | 294 |
| 295 talk_base::SocketAddress address_lj; | 295 talk_base::SocketAddress address_lj; |
| 296 if (!jingle_glue::IPEndPointToSocketAddress(address, &address_lj)) { | 296 if (!jingle_glue::IPEndPointToSocketAddress(address, &address_lj)) { |
| 297 // We should always be able to convert address here because we | 297 // We should always be able to convert address here because we |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return NULL; | 354 return NULL; |
| 355 | 355 |
| 356 talk_base::SocketAddress crome_address; | 356 talk_base::SocketAddress crome_address; |
| 357 P2PSocketClient* socket_client = new P2PSocketClient(socket_dispatcher_); | 357 P2PSocketClient* socket_client = new P2PSocketClient(socket_dispatcher_); |
| 358 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket()); | 358 scoped_ptr<IpcPacketSocket> socket(new IpcPacketSocket()); |
| 359 if (!socket->Init(P2P_SOCKET_TCP_CLIENT, socket_client, local_address, | 359 if (!socket->Init(P2P_SOCKET_TCP_CLIENT, socket_client, local_address, |
| 360 remote_address)) | 360 remote_address)) |
| 361 return NULL; | 361 return NULL; |
| 362 return socket.release(); | 362 return socket.release(); |
| 363 } | 363 } |
| OLD | NEW |