• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CreateSocketInfo(int socket_id,ResumableTCPServerSocket * socket)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 
SetSocketProperties(ResumableTCPServerSocket * socket,SocketProperties * properties)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 
~TCPServerSocketAsyncApiFunction()64 TCPServerSocketAsyncApiFunction::~TCPServerSocketAsyncApiFunction() {}
65 
66 scoped_ptr<SocketResourceManagerInterface>
CreateSocketResourceManager()67 TCPServerSocketAsyncApiFunction::CreateSocketResourceManager() {
68   return scoped_ptr<SocketResourceManagerInterface>(
69              new SocketResourceManager<ResumableTCPServerSocket>()).Pass();
70 }
71 
GetTcpSocket(int socket_id)72 ResumableTCPServerSocket* TCPServerSocketAsyncApiFunction::GetTcpSocket(
73     int socket_id) {
74   return static_cast<ResumableTCPServerSocket*>(GetSocket(socket_id));
75 }
76 
SocketsTcpServerCreateFunction()77 SocketsTcpServerCreateFunction::SocketsTcpServerCreateFunction() {}
78 
~SocketsTcpServerCreateFunction()79 SocketsTcpServerCreateFunction::~SocketsTcpServerCreateFunction() {}
80 
Prepare()81 bool SocketsTcpServerCreateFunction::Prepare() {
82   params_ = sockets_tcp_server::Create::Params::Create(*args_);
83   EXTENSION_FUNCTION_VALIDATE(params_.get());
84   return true;
85 }
86 
Work()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 
SocketsTcpServerUpdateFunction()102 SocketsTcpServerUpdateFunction::SocketsTcpServerUpdateFunction() {}
103 
~SocketsTcpServerUpdateFunction()104 SocketsTcpServerUpdateFunction::~SocketsTcpServerUpdateFunction() {}
105 
Prepare()106 bool SocketsTcpServerUpdateFunction::Prepare() {
107   params_ = sockets_tcp_server::Update::Params::Create(*args_);
108   EXTENSION_FUNCTION_VALIDATE(params_.get());
109   return true;
110 }
111 
Work()112 void SocketsTcpServerUpdateFunction::Work() {
113   ResumableTCPServerSocket* socket = GetTcpSocket(params_->socket_id);
114   if (!socket) {
115     error_ = kSocketNotFoundError;
116     return;
117   }
118 
119   SetSocketProperties(socket, &params_.get()->properties);
120   results_ = sockets_tcp_server::Update::Results::Create();
121 }
122 
SocketsTcpServerSetPausedFunction()123 SocketsTcpServerSetPausedFunction::SocketsTcpServerSetPausedFunction()
124     : socket_event_dispatcher_(NULL) {}
125 
~SocketsTcpServerSetPausedFunction()126 SocketsTcpServerSetPausedFunction::~SocketsTcpServerSetPausedFunction() {}
127 
Prepare()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 
Work()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 
SocketsTcpServerListenFunction()160 SocketsTcpServerListenFunction::SocketsTcpServerListenFunction()
161     : socket_event_dispatcher_(NULL) {}
162 
~SocketsTcpServerListenFunction()163 SocketsTcpServerListenFunction::~SocketsTcpServerListenFunction() {}
164 
Prepare()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 
Work()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 
SocketsTcpServerDisconnectFunction()210 SocketsTcpServerDisconnectFunction::SocketsTcpServerDisconnectFunction() {}
211 
~SocketsTcpServerDisconnectFunction()212 SocketsTcpServerDisconnectFunction::~SocketsTcpServerDisconnectFunction() {}
213 
Prepare()214 bool SocketsTcpServerDisconnectFunction::Prepare() {
215   params_ = sockets_tcp_server::Disconnect::Params::Create(*args_);
216   EXTENSION_FUNCTION_VALIDATE(params_.get());
217   return true;
218 }
219 
Work()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 
SocketsTcpServerCloseFunction()231 SocketsTcpServerCloseFunction::SocketsTcpServerCloseFunction() {}
232 
~SocketsTcpServerCloseFunction()233 SocketsTcpServerCloseFunction::~SocketsTcpServerCloseFunction() {}
234 
Prepare()235 bool SocketsTcpServerCloseFunction::Prepare() {
236   params_ = sockets_tcp_server::Close::Params::Create(*args_);
237   EXTENSION_FUNCTION_VALIDATE(params_.get());
238   return true;
239 }
240 
Work()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 
SocketsTcpServerGetInfoFunction()252 SocketsTcpServerGetInfoFunction::SocketsTcpServerGetInfoFunction() {}
253 
~SocketsTcpServerGetInfoFunction()254 SocketsTcpServerGetInfoFunction::~SocketsTcpServerGetInfoFunction() {}
255 
Prepare()256 bool SocketsTcpServerGetInfoFunction::Prepare() {
257   params_ = sockets_tcp_server::GetInfo::Params::Create(*args_);
258   EXTENSION_FUNCTION_VALIDATE(params_.get());
259   return true;
260 }
261 
Work()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 
SocketsTcpServerGetSocketsFunction()274 SocketsTcpServerGetSocketsFunction::SocketsTcpServerGetSocketsFunction() {}
275 
~SocketsTcpServerGetSocketsFunction()276 SocketsTcpServerGetSocketsFunction::~SocketsTcpServerGetSocketsFunction() {}
277 
Prepare()278 bool SocketsTcpServerGetSocketsFunction::Prepare() { return true; }
279 
Work()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