1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_EXTENSIONS_API_SOCKET_SOCKET_API_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_SOCKET_SOCKET_API_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "base/memory/ref_counted.h" 10 #include "chrome/browser/extensions/api/api_function.h" 11 #include "chrome/browser/extensions/api/api_resource_manager.h" 12 #include "chrome/common/extensions/api/socket.h" 13 #include "extensions/browser/extension_function.h" 14 #include "net/base/address_list.h" 15 #include "net/dns/host_resolver.h" 16 #include "net/socket/tcp_client_socket.h" 17 18 #include <string> 19 20 class IOThread; 21 22 namespace net { 23 class IOBuffer; 24 } 25 26 namespace extensions { 27 28 class Socket; 29 30 // A simple interface to ApiResourceManager<Socket> or derived class. The goal 31 // of this interface is to allow Socket API functions to use distinct instances 32 // of ApiResourceManager<> depending on the type of socket (old version in 33 // "socket" namespace vs new version in "socket.xxx" namespaces). 34 class SocketResourceManagerInterface { 35 public: ~SocketResourceManagerInterface()36 virtual ~SocketResourceManagerInterface() {} 37 38 virtual bool SetProfile(Profile* profile) = 0; 39 virtual int Add(Socket *socket) = 0; 40 virtual Socket* Get(const std::string& extension_id, 41 int api_resource_id) = 0; 42 virtual void Remove(const std::string& extension_id, 43 int api_resource_id) = 0; 44 virtual base::hash_set<int>* GetResourceIds( 45 const std::string& extension_id) = 0; 46 }; 47 48 // Implementation of SocketResourceManagerInterface using an 49 // ApiResourceManager<T> instance (where T derives from Socket). 50 template<typename T> 51 class SocketResourceManager : public SocketResourceManagerInterface { 52 public: SocketResourceManager()53 SocketResourceManager() 54 : manager_(NULL) { 55 } 56 SetProfile(Profile * profile)57 virtual bool SetProfile(Profile* profile) OVERRIDE { 58 manager_ = ApiResourceManager<T>::Get(profile); 59 DCHECK(manager_) << "There is no socket manager. " 60 "If this assertion is failing during a test, then it is likely that " 61 "TestExtensionSystem is failing to provide an instance of " 62 "ApiResourceManager<Socket>."; 63 return manager_ != NULL; 64 } 65 Add(Socket * socket)66 virtual int Add(Socket *socket) OVERRIDE { 67 // Note: Cast needed here, because "T" may be a subclass of "Socket". 68 return manager_->Add(static_cast<T*>(socket)); 69 } 70 Get(const std::string & extension_id,int api_resource_id)71 virtual Socket* Get(const std::string& extension_id, 72 int api_resource_id) OVERRIDE { 73 return manager_->Get(extension_id, api_resource_id); 74 } 75 Remove(const std::string & extension_id,int api_resource_id)76 virtual void Remove(const std::string& extension_id, 77 int api_resource_id) OVERRIDE { 78 manager_->Remove(extension_id, api_resource_id); 79 } 80 GetResourceIds(const std::string & extension_id)81 virtual base::hash_set<int>* GetResourceIds( 82 const std::string& extension_id) OVERRIDE { 83 return manager_->GetResourceIds(extension_id); 84 } 85 86 private: 87 ApiResourceManager<T>* manager_; 88 }; 89 90 class SocketAsyncApiFunction : public AsyncApiFunction { 91 public: 92 SocketAsyncApiFunction(); 93 94 protected: 95 virtual ~SocketAsyncApiFunction(); 96 97 // AsyncApiFunction: 98 virtual bool PrePrepare() OVERRIDE; 99 virtual bool Respond() OVERRIDE; 100 101 virtual scoped_ptr<SocketResourceManagerInterface> 102 CreateSocketResourceManager(); 103 104 int AddSocket(Socket* socket); 105 Socket* GetSocket(int api_resource_id); 106 void RemoveSocket(int api_resource_id); 107 base::hash_set<int>* GetSocketIds(); 108 109 private: 110 scoped_ptr<SocketResourceManagerInterface> manager_; 111 }; 112 113 class SocketExtensionWithDnsLookupFunction : public SocketAsyncApiFunction { 114 protected: 115 SocketExtensionWithDnsLookupFunction(); 116 virtual ~SocketExtensionWithDnsLookupFunction(); 117 118 void StartDnsLookup(const std::string& hostname); 119 virtual void AfterDnsLookup(int lookup_result) = 0; 120 121 std::string resolved_address_; 122 123 private: 124 void OnDnsLookup(int resolve_result); 125 126 // This instance is widely available through BrowserProcess, but we need to 127 // acquire it on the UI thread and then use it on the IO thread, so we keep a 128 // plain pointer to it here as we move from thread to thread. 129 IOThread* io_thread_; 130 131 scoped_ptr<net::HostResolver::RequestHandle> request_handle_; 132 scoped_ptr<net::AddressList> addresses_; 133 }; 134 135 class SocketCreateFunction : public SocketAsyncApiFunction { 136 public: 137 DECLARE_EXTENSION_FUNCTION("socket.create", SOCKET_CREATE) 138 139 SocketCreateFunction(); 140 141 protected: 142 virtual ~SocketCreateFunction(); 143 144 // AsyncApiFunction: 145 virtual bool Prepare() OVERRIDE; 146 virtual void Work() OVERRIDE; 147 148 private: 149 FRIEND_TEST_ALL_PREFIXES(SocketUnitTest, Create); 150 enum SocketType { 151 kSocketTypeInvalid = -1, 152 kSocketTypeTCP, 153 kSocketTypeUDP 154 }; 155 156 scoped_ptr<api::socket::Create::Params> params_; 157 SocketType socket_type_; 158 }; 159 160 class SocketDestroyFunction : public SocketAsyncApiFunction { 161 public: 162 DECLARE_EXTENSION_FUNCTION("socket.destroy", SOCKET_DESTROY) 163 164 protected: ~SocketDestroyFunction()165 virtual ~SocketDestroyFunction() {} 166 167 // AsyncApiFunction: 168 virtual bool Prepare() OVERRIDE; 169 virtual void Work() OVERRIDE; 170 171 private: 172 int socket_id_; 173 }; 174 175 class SocketConnectFunction : public SocketExtensionWithDnsLookupFunction { 176 public: 177 DECLARE_EXTENSION_FUNCTION("socket.connect", SOCKET_CONNECT) 178 179 SocketConnectFunction(); 180 181 protected: 182 virtual ~SocketConnectFunction(); 183 184 // AsyncApiFunction: 185 virtual bool Prepare() OVERRIDE; 186 virtual void AsyncWorkStart() OVERRIDE; 187 188 // SocketExtensionWithDnsLookupFunction: 189 virtual void AfterDnsLookup(int lookup_result) OVERRIDE; 190 191 private: 192 void StartConnect(); 193 void OnConnect(int result); 194 195 int socket_id_; 196 std::string hostname_; 197 int port_; 198 Socket* socket_; 199 }; 200 201 class SocketDisconnectFunction : public SocketAsyncApiFunction { 202 public: 203 DECLARE_EXTENSION_FUNCTION("socket.disconnect", SOCKET_DISCONNECT) 204 205 protected: ~SocketDisconnectFunction()206 virtual ~SocketDisconnectFunction() {} 207 208 // AsyncApiFunction: 209 virtual bool Prepare() OVERRIDE; 210 virtual void Work() OVERRIDE; 211 212 private: 213 int socket_id_; 214 }; 215 216 class SocketBindFunction : public SocketAsyncApiFunction { 217 public: 218 DECLARE_EXTENSION_FUNCTION("socket.bind", SOCKET_BIND) 219 220 protected: ~SocketBindFunction()221 virtual ~SocketBindFunction() {} 222 223 // AsyncApiFunction: 224 virtual bool Prepare() OVERRIDE; 225 virtual void Work() OVERRIDE; 226 227 private: 228 int socket_id_; 229 std::string address_; 230 int port_; 231 }; 232 233 class SocketListenFunction : public SocketAsyncApiFunction { 234 public: 235 DECLARE_EXTENSION_FUNCTION("socket.listen", SOCKET_LISTEN) 236 237 SocketListenFunction(); 238 239 protected: 240 virtual ~SocketListenFunction(); 241 242 // AsyncApiFunction: 243 virtual bool Prepare() OVERRIDE; 244 virtual void Work() OVERRIDE; 245 246 private: 247 scoped_ptr<api::socket::Listen::Params> params_; 248 }; 249 250 class SocketAcceptFunction : public SocketAsyncApiFunction { 251 public: 252 DECLARE_EXTENSION_FUNCTION("socket.accept", SOCKET_ACCEPT) 253 254 SocketAcceptFunction(); 255 256 protected: 257 virtual ~SocketAcceptFunction(); 258 259 // AsyncApiFunction: 260 virtual bool Prepare() OVERRIDE; 261 virtual void AsyncWorkStart() OVERRIDE; 262 263 private: 264 void OnAccept(int result_code, net::TCPClientSocket *socket); 265 scoped_ptr<api::socket::Accept::Params> params_; 266 }; 267 268 class SocketReadFunction : public SocketAsyncApiFunction { 269 public: 270 DECLARE_EXTENSION_FUNCTION("socket.read", SOCKET_READ) 271 272 SocketReadFunction(); 273 274 protected: 275 virtual ~SocketReadFunction(); 276 277 // AsyncApiFunction: 278 virtual bool Prepare() OVERRIDE; 279 virtual void AsyncWorkStart() OVERRIDE; 280 void OnCompleted(int result, scoped_refptr<net::IOBuffer> io_buffer); 281 282 private: 283 scoped_ptr<api::socket::Read::Params> params_; 284 }; 285 286 class SocketWriteFunction : public SocketAsyncApiFunction { 287 public: 288 DECLARE_EXTENSION_FUNCTION("socket.write", SOCKET_WRITE) 289 290 SocketWriteFunction(); 291 292 protected: 293 virtual ~SocketWriteFunction(); 294 295 // AsyncApiFunction: 296 virtual bool Prepare() OVERRIDE; 297 virtual void AsyncWorkStart() OVERRIDE; 298 void OnCompleted(int result); 299 300 private: 301 int socket_id_; 302 scoped_refptr<net::IOBuffer> io_buffer_; 303 size_t io_buffer_size_; 304 }; 305 306 class SocketRecvFromFunction : public SocketAsyncApiFunction { 307 public: 308 DECLARE_EXTENSION_FUNCTION("socket.recvFrom", SOCKET_RECVFROM) 309 310 SocketRecvFromFunction(); 311 312 protected: 313 virtual ~SocketRecvFromFunction(); 314 315 // AsyncApiFunction 316 virtual bool Prepare() OVERRIDE; 317 virtual void AsyncWorkStart() OVERRIDE; 318 void OnCompleted(int result, 319 scoped_refptr<net::IOBuffer> io_buffer, 320 const std::string& address, 321 int port); 322 323 private: 324 scoped_ptr<api::socket::RecvFrom::Params> params_; 325 }; 326 327 class SocketSendToFunction : public SocketExtensionWithDnsLookupFunction { 328 public: 329 DECLARE_EXTENSION_FUNCTION("socket.sendTo", SOCKET_SENDTO) 330 331 SocketSendToFunction(); 332 333 protected: 334 virtual ~SocketSendToFunction(); 335 336 // AsyncApiFunction: 337 virtual bool Prepare() OVERRIDE; 338 virtual void AsyncWorkStart() OVERRIDE; 339 void OnCompleted(int result); 340 341 // SocketExtensionWithDnsLookupFunction: 342 virtual void AfterDnsLookup(int lookup_result) OVERRIDE; 343 344 private: 345 void StartSendTo(); 346 347 int socket_id_; 348 scoped_refptr<net::IOBuffer> io_buffer_; 349 size_t io_buffer_size_; 350 std::string hostname_; 351 int port_; 352 Socket* socket_; 353 }; 354 355 class SocketSetKeepAliveFunction : public SocketAsyncApiFunction { 356 public: 357 DECLARE_EXTENSION_FUNCTION("socket.setKeepAlive", SOCKET_SETKEEPALIVE) 358 359 SocketSetKeepAliveFunction(); 360 361 protected: 362 virtual ~SocketSetKeepAliveFunction(); 363 364 // AsyncApiFunction: 365 virtual bool Prepare() OVERRIDE; 366 virtual void Work() OVERRIDE; 367 368 private: 369 scoped_ptr<api::socket::SetKeepAlive::Params> params_; 370 }; 371 372 class SocketSetNoDelayFunction : public SocketAsyncApiFunction { 373 public: 374 DECLARE_EXTENSION_FUNCTION("socket.setNoDelay", SOCKET_SETNODELAY) 375 376 SocketSetNoDelayFunction(); 377 378 protected: 379 virtual ~SocketSetNoDelayFunction(); 380 381 // AsyncApiFunction: 382 virtual bool Prepare() OVERRIDE; 383 virtual void Work() OVERRIDE; 384 385 private: 386 scoped_ptr<api::socket::SetNoDelay::Params> params_; 387 }; 388 389 class SocketGetInfoFunction : public SocketAsyncApiFunction { 390 public: 391 DECLARE_EXTENSION_FUNCTION("socket.getInfo", SOCKET_GETINFO) 392 393 SocketGetInfoFunction(); 394 395 protected: 396 virtual ~SocketGetInfoFunction(); 397 398 // AsyncApiFunction: 399 virtual bool Prepare() OVERRIDE; 400 virtual void Work() OVERRIDE; 401 402 private: 403 scoped_ptr<api::socket::GetInfo::Params> params_; 404 }; 405 406 class SocketGetNetworkListFunction : public AsyncExtensionFunction { 407 public: 408 DECLARE_EXTENSION_FUNCTION("socket.getNetworkList", SOCKET_GETNETWORKLIST) 409 410 protected: ~SocketGetNetworkListFunction()411 virtual ~SocketGetNetworkListFunction() {} 412 virtual bool RunImpl() OVERRIDE; 413 414 private: 415 void GetNetworkListOnFileThread(); 416 void HandleGetNetworkListError(); 417 void SendResponseOnUIThread(const net::NetworkInterfaceList& interface_list); 418 }; 419 420 class SocketJoinGroupFunction : public SocketAsyncApiFunction { 421 public: 422 DECLARE_EXTENSION_FUNCTION("socket.joinGroup", SOCKET_MULTICAST_JOIN_GROUP) 423 424 SocketJoinGroupFunction(); 425 426 protected: 427 virtual ~SocketJoinGroupFunction(); 428 429 // AsyncApiFunction 430 virtual bool Prepare() OVERRIDE; 431 virtual void Work() OVERRIDE; 432 433 private: 434 scoped_ptr<api::socket::JoinGroup::Params> params_; 435 }; 436 437 class SocketLeaveGroupFunction : public SocketAsyncApiFunction { 438 public: 439 DECLARE_EXTENSION_FUNCTION("socket.leaveGroup", SOCKET_MULTICAST_LEAVE_GROUP) 440 441 SocketLeaveGroupFunction(); 442 443 protected: 444 virtual ~SocketLeaveGroupFunction(); 445 446 // AsyncApiFunction 447 virtual bool Prepare() OVERRIDE; 448 virtual void Work() OVERRIDE; 449 450 private: 451 scoped_ptr<api::socket::LeaveGroup::Params> params_; 452 }; 453 454 class SocketSetMulticastTimeToLiveFunction : public SocketAsyncApiFunction { 455 public: 456 DECLARE_EXTENSION_FUNCTION("socket.setMulticastTimeToLive", 457 SOCKET_MULTICAST_SET_TIME_TO_LIVE) 458 459 SocketSetMulticastTimeToLiveFunction(); 460 461 protected: 462 virtual ~SocketSetMulticastTimeToLiveFunction(); 463 464 // AsyncApiFunction 465 virtual bool Prepare() OVERRIDE; 466 virtual void Work() OVERRIDE; 467 468 private: 469 scoped_ptr<api::socket::SetMulticastTimeToLive::Params> params_; 470 }; 471 472 class SocketSetMulticastLoopbackModeFunction : public SocketAsyncApiFunction { 473 public: 474 DECLARE_EXTENSION_FUNCTION("socket.setMulticastLoopbackMode", 475 SOCKET_MULTICAST_SET_LOOPBACK_MODE) 476 477 SocketSetMulticastLoopbackModeFunction(); 478 479 protected: 480 virtual ~SocketSetMulticastLoopbackModeFunction(); 481 482 // AsyncApiFunction 483 virtual bool Prepare() OVERRIDE; 484 virtual void Work() OVERRIDE; 485 486 private: 487 scoped_ptr<api::socket::SetMulticastLoopbackMode::Params> params_; 488 }; 489 490 class SocketGetJoinedGroupsFunction : public SocketAsyncApiFunction { 491 public: 492 DECLARE_EXTENSION_FUNCTION("socket.getJoinedGroups", 493 SOCKET_MULTICAST_GET_JOINED_GROUPS) 494 495 SocketGetJoinedGroupsFunction(); 496 497 protected: 498 virtual ~SocketGetJoinedGroupsFunction(); 499 500 // AsyncApiFunction 501 virtual bool Prepare() OVERRIDE; 502 virtual void Work() OVERRIDE; 503 504 private: 505 scoped_ptr<api::socket::GetJoinedGroups::Params> params_; 506 }; 507 } // namespace extensions 508 509 #endif // CHROME_BROWSER_EXTENSIONS_API_SOCKET_SOCKET_API_H_ 510