1 // Copyright 2014 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 "extensions/browser/api/sockets_tcp_server/sockets_tcp_server_api.h" 6 7 #include "content/public/common/socket_permission_request.h" 8 #include "extensions/browser/api/socket/tcp_socket.h" 9 #include "extensions/browser/api/sockets_tcp_server/tcp_server_socket_event_dispatcher.h" 10 #include "extensions/common/api/sockets/sockets_manifest_data.h" 11 #include "extensions/common/permissions/permissions_data.h" 12 #include "extensions/common/permissions/socket_permission.h" 13 #include "net/base/net_errors.h" 14 15 using content::SocketPermissionRequest; 16 using extensions::ResumableTCPServerSocket; 17 using extensions::core_api::sockets_tcp_server::SocketInfo; 18 using extensions::core_api::sockets_tcp_server::SocketProperties; 19 20 namespace { 21 22 const char kSocketNotFoundError[] = "Socket not found"; 23 const char kPermissionError[] = "Does not have permission"; 24 const int kDefaultListenBacklog = SOMAXCONN; 25 26 linked_ptr<SocketInfo> CreateSocketInfo(int socket_id, 27 ResumableTCPServerSocket* socket) { 28 linked_ptr<SocketInfo> socket_info(new SocketInfo()); 29 // This represents what we know about the socket, and does not call through 30 // to the system. 31 socket_info->socket_id = socket_id; 32 if (!socket->name().empty()) { 33 socket_info->name.reset(new std::string(socket->name())); 34 } 35 socket_info->persistent = socket->persistent(); 36 socket_info->paused = socket->paused(); 37 38 // Grab the local address as known by the OS. 39 net::IPEndPoint localAddress; 40 if (socket->GetLocalAddress(&localAddress)) { 41 socket_info->local_address.reset( 42 new std::string(localAddress.ToStringWithoutPort())); 43 socket_info->local_port.reset(new int(localAddress.port())); 44 } 45 46 return socket_info; 47 } 48 49 void SetSocketProperties(ResumableTCPServerSocket* socket, 50 SocketProperties* properties) { 51 if (properties->name.get()) { 52 socket->set_name(*properties->name.get()); 53 } 54 if (properties->persistent.get()) { 55 socket->set_persistent(*properties->persistent.get()); 56 } 57 } 58 59 } // namespace 60 61 namespace extensions { 62 namespace core_api { 63 64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {} 65 66 scoped_ptr<SocketResourceManagerInterface> 67 TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() { 68 return scoped_ptr<SocketResourceManagerInterface>( 69 new SocketResourceManager<ResumableTCPServerSocket>()).Pass(); 70 } 71 72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket( 73 int socket_id) { 74 return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id)); 75 } 76 77 SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {} 78 79 SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {} 80 81 bool SocketsTcpServerCreateFunction::Prepare() { 82 params_ = sockets_tcp_server::Create::Params::Create(*args_); 83 EXTENSION_FUNCTION_VALIDATE(params_.get()); 84 return true; 85 } 86 87 void SocketsTcpServerCreateFunction::Work() { 88 ResumableTCPServerSocket* socket = 89 new ResumableTCPServerSocket(extension_->id()); 90 91 sockets_tcp_server::SocketProperties* properties = 92 params_.get()->properties.get(); 93 if (properties) { 94 SetSocketProperties(socket, properties); 95 } 96 97 sockets_tcp_server::CreateInfo create_info; 98 create_info.socket_id = AddSocket(socket); 99 results_ = sockets_tcp_server::Create::Results::Create(create_info); 100 } 101 102 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {} 103 104 SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {} 105 106 bool SocketsTcpServerUpdateFunction::Prepare() { 107 params_ = sockets_tcp_server::Update::Params::Create(*args_); 108 EXTENSION_FUNCTION_VALIDATE(params_.get()); 109 return true; 110 } 111 112 void SocketsTcpServerUpdateFunction::Work() { 113 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 114 if (!socket) { 115 error_ = kSocketNotFoundError; 116 return; 117 } 118 119 SetSocketProperties(socket, ¶ms_.get()->properties); 120 results_ = sockets_tcp_server::Update::Results::Create(); 121 } 122 123 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction() 124 : socket_event_dispatcher_(NULL) {} 125 126 SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {} 127 128 bool SocketsTcpServerSetPausedFunction::Prepare() { 129 params_ = core_api::sockets_tcp_server::SetPaused::Params::Create(*args_); 130 EXTENSION_FUNCTION_VALIDATE(params_.get()); 131 132 socket_event_dispatcher_ = 133 TCPServerSocketEventDispatcher::Get(browser_context()); 134 DCHECK(socket_event_dispatcher_) 135 << "There is no socket event dispatcher. " 136 "If this assertion is failing during a test, then it is likely that " 137 "TestExtensionSystem is failing to provide an instance of " 138 "TCPServerSocketEventDispatcher."; 139 return socket_event_dispatcher_ != NULL; 140 } 141 142 void SocketsTcpServerSetPausedFunction::Work() { 143 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 144 if (!socket) { 145 error_ = kSocketNotFoundError; 146 return; 147 } 148 149 if (socket->paused() != params_->paused) { 150 socket->set_paused(params_->paused); 151 if (socket->IsConnected() && !params_->paused) { 152 socket_event_dispatcher_->OnServerSocketResume(extension_->id(), 153 params_->socket_id); 154 } 155 } 156 157 results_ = sockets_tcp_server::SetPaused::Results::Create(); 158 } 159 160 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction() 161 : socket_event_dispatcher_(NULL) {} 162 163 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {} 164 165 bool SocketsTcpServerListenFunction::Prepare() { 166 params_ = core_api::sockets_tcp_server::Listen::Params::Create(*args_); 167 EXTENSION_FUNCTION_VALIDATE(params_.get()); 168 169 socket_event_dispatcher_ = 170 TCPServerSocketEventDispatcher::Get(browser_context()); 171 DCHECK(socket_event_dispatcher_) 172 << "There is no socket event dispatcher. " 173 "If this assertion is failing during a test, then it is likely that " 174 "TestExtensionSystem is failing to provide an instance of " 175 "TCPServerSocketEventDispatcher."; 176 return socket_event_dispatcher_ != NULL; 177 } 178 179 void SocketsTcpServerListenFunction::Work() { 180 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 181 if (!socket) { 182 error_ = kSocketNotFoundError; 183 return; 184 } 185 186 SocketPermissionRequest param( 187 SocketPermissionRequest::TCP_LISTEN, params_->address, params_->port); 188 if (!SocketsManifestData::CheckRequest(GetExtension(), param)) { 189 error_ = kPermissionError; 190 return; 191 } 192 193 int net_result = socket->Listen( 194 params_->address, 195 params_->port, 196 params_->backlog.get() ? *params_->backlog.get() : kDefaultListenBacklog, 197 &error_); 198 199 if (net_result != net::OK) 200 error_ = net::ErrorToString(net_result); 201 202 if (net_result == net::OK) { 203 socket_event_dispatcher_->OnServerSocketListen(extension_->id(), 204 params_->socket_id); 205 } 206 207 results_ = sockets_tcp_server::Listen::Results::Create(net_result); 208 } 209 210 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {} 211 212 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {} 213 214 bool SocketsTcpServerDisconnectFunction::Prepare() { 215 params_ = sockets_tcp_server::Disconnect::Params::Create(*args_); 216 EXTENSION_FUNCTION_VALIDATE(params_.get()); 217 return true; 218 } 219 220 void SocketsTcpServerDisconnectFunction::Work() { 221 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 222 if (!socket) { 223 error_ = kSocketNotFoundError; 224 return; 225 } 226 227 socket->Disconnect(); 228 results_ = sockets_tcp_server::Disconnect::Results::Create(); 229 } 230 231 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {} 232 233 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {} 234 235 bool SocketsTcpServerCloseFunction::Prepare() { 236 params_ = sockets_tcp_server::Close::Params::Create(*args_); 237 EXTENSION_FUNCTION_VALIDATE(params_.get()); 238 return true; 239 } 240 241 void SocketsTcpServerCloseFunction::Work() { 242 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 243 if (!socket) { 244 error_ = kSocketNotFoundError; 245 return; 246 } 247 248 RemoveSocket(params_->socket_id); 249 results_ = sockets_tcp_server::Close::Results::Create(); 250 } 251 252 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {} 253 254 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {} 255 256 bool SocketsTcpServerGetInfoFunction::Prepare() { 257 params_ = sockets_tcp_server::GetInfo::Params::Create(*args_); 258 EXTENSION_FUNCTION_VALIDATE(params_.get()); 259 return true; 260 } 261 262 void SocketsTcpServerGetInfoFunction::Work() { 263 ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id); 264 if (!socket) { 265 error_ = kSocketNotFoundError; 266 return; 267 } 268 269 linked_ptr<sockets_tcp_server::SocketInfo> socket_info = 270 CreateSocketInfo(params_->socket_id, socket); 271 results_ = sockets_tcp_server::GetInfo::Results::Create(*socket_info); 272 } 273 274 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {} 275 276 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {} 277 278 bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; } 279 280 void SocketsTcpServerGetSocketsFunction::Work() { 281 std::vector<linked_ptr<sockets_tcp_server::SocketInfo> > socket_infos; 282 base::hash_set<int>* resource_ids = GetSocketIds(); 283 if (resource_ids != NULL) { 284 for (base::hash_set<int>::iterator it = resource_ids->begin(); 285 it != resource_ids->end(); 286 ++it) { 287 int socket_id = *it; 288 ResumableTCPServerSocket* socket = GetTcpSocket(socket_id); 289 if (socket) { 290 socket_infos.push_back(CreateSocketInfo(socket_id, socket)); 291 } 292 } 293 } 294 results_ = sockets_tcp_server::GetSockets::Results::Create(socket_infos); 295 } 296 297 } // namespace core_api 298 } // namespace extensions 299