OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
| 7 #include <string.h> |
| 8 |
7 #include "native_client/src/trusted/reverse_service/reverse_service.h" | 9 #include "native_client/src/trusted/reverse_service/reverse_service.h" |
8 | 10 |
9 #include "native_client/src/include/nacl_compiler_annotations.h" | 11 #include "native_client/src/include/nacl_compiler_annotations.h" |
10 #include "native_client/src/include/nacl_scoped_ptr.h" | 12 #include "native_client/src/include/nacl_scoped_ptr.h" |
11 | 13 #include "native_client/src/include/portability_io.h" |
12 #include "native_client/src/shared/platform/nacl_log.h" | 14 #include "native_client/src/shared/platform/nacl_log.h" |
13 #include "native_client/src/shared/platform/nacl_sync.h" | 15 #include "native_client/src/shared/platform/nacl_sync.h" |
14 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 16 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
15 #include "native_client/src/shared/platform/nacl_threads.h" | 17 #include "native_client/src/shared/platform/nacl_threads.h" |
16 #include "native_client/src/shared/srpc/nacl_srpc.h" | 18 #include "native_client/src/shared/srpc/nacl_srpc.h" |
17 | 19 |
| 20 #include "native_client/src/trusted/desc/nacl_desc_invalid.h" |
| 21 |
18 namespace { | 22 namespace { |
19 | 23 |
20 void Test(NaClSrpcRpc* rpc, | 24 void Test(NaClSrpcRpc* rpc, |
21 NaClSrpcArg** in_args, | 25 NaClSrpcArg** in_args, |
22 NaClSrpcArg** out_args, | 26 NaClSrpcArg** out_args, |
23 NaClSrpcClosure* done) { | 27 NaClSrpcClosure* done) { |
24 char *msg = in_args[0]->arrays.str; | 28 char *msg = in_args[0]->arrays.str; |
25 UNREFERENCED_PARAMETER(out_args); | 29 UNREFERENCED_PARAMETER(out_args); |
26 // use rpc->channel rather than rpc->channel->server_instance_data | 30 // use rpc->channel rather than rpc->channel->server_instance_data |
27 // to show that Test RPCs arrive in different channels. | 31 // to show that Test RPCs arrive in different channels. |
28 NaClLog(1, "Test: [%"NACL_PRIxPTR"] %s\n", | 32 NaClLog(1, "Test: [%"NACL_PRIxPTR"] %s\n", |
29 reinterpret_cast<uintptr_t>(rpc->channel), msg); | 33 reinterpret_cast<uintptr_t>(rpc->channel), msg); |
30 rpc->result = NACL_SRPC_RESULT_OK; | 34 rpc->result = NACL_SRPC_RESULT_OK; |
31 done->Run(done); | 35 done->Run(done); |
32 } | 36 } |
33 | 37 |
34 void AddChannel(NaClSrpcRpc* rpc, | 38 void AddChannel(NaClSrpcRpc* rpc, |
35 NaClSrpcArg** in_args, | 39 NaClSrpcArg** in_args, |
36 NaClSrpcArg** out_args, | 40 NaClSrpcArg** out_args, |
37 NaClSrpcClosure* done) { | 41 NaClSrpcClosure* done) { |
38 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( | 42 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( |
39 rpc->channel->server_instance_data); | 43 rpc->channel->server_instance_data); |
| 44 |
40 UNREFERENCED_PARAMETER(in_args); | 45 UNREFERENCED_PARAMETER(in_args); |
41 UNREFERENCED_PARAMETER(out_args); | 46 |
42 NaClLog(4, "Entered AddChannel\n"); | 47 NaClLog(4, "Entered AddChannel\n"); |
43 out_args[0]->u.bval = service->Start(); | 48 out_args[0]->u.bval = service->Start(); |
44 NaClLog(4, "Leaving AddChannel\n"); | 49 NaClLog(4, "Leaving AddChannel\n"); |
45 rpc->result = NACL_SRPC_RESULT_OK; | 50 rpc->result = NACL_SRPC_RESULT_OK; |
46 done->Run(done); | 51 done->Run(done); |
47 } | 52 } |
48 | 53 |
49 void RevLog(NaClSrpcRpc* rpc, | 54 void RevLog(NaClSrpcRpc* rpc, |
50 NaClSrpcArg** in_args, | 55 NaClSrpcArg** in_args, |
51 NaClSrpcArg** out_args, | 56 NaClSrpcArg** out_args, |
52 NaClSrpcClosure* done) { | 57 NaClSrpcClosure* done) { |
53 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( | 58 nacl::ReverseService* service = reinterpret_cast<nacl::ReverseService*>( |
54 rpc->channel->server_instance_data); | 59 rpc->channel->server_instance_data); |
55 UNREFERENCED_PARAMETER(out_args); | 60 UNREFERENCED_PARAMETER(out_args); |
56 char* message = in_args[0]->arrays.str; | 61 char* message = in_args[0]->arrays.str; |
57 | 62 |
58 if (NULL == service->reverse_interface()) { | 63 if (NULL == service->reverse_interface()) { |
59 NaClLog(1, "Log RPC, no reverse_interface. Message: %s\n", message); | 64 NaClLog(1, "Log RPC, no reverse_interface. Message: %s\n", message); |
60 } else { | 65 } else { |
61 service->reverse_interface()->Log(message); | 66 service->reverse_interface()->Log(message); |
62 } | 67 } |
63 done->Run(done); | 68 done->Run(done); |
64 } | 69 } |
65 | 70 |
| 71 // Manifest name service, internal APIs. |
| 72 // |
| 73 // Manifest file lookups result in read-only file descriptors with a |
| 74 // handle. When the descriptor is closed, the service runtime must |
| 75 // inform the plugin of this using the handle, so that the File object |
| 76 // reference can be closed (thereby allowing the browser to delete or |
| 77 // otherwise garbage collect the file). Files, being from the |
| 78 // manifest, cannot be deleted. The manifest is also a read-only |
| 79 // object, so no new entries can be made to it. |
| 80 // |
| 81 // Read-only proxies do not require quota support per se, since we do |
| 82 // not limit read bandwidth. Quota support is needed for storage |
| 83 // limits, though could also be used to limit write bandwidth (prevent |
| 84 // disk output saturation, limit malicious code's ability to cause |
| 85 // disk failures, especially with flash disks with limited write |
| 86 // cycles). |
| 87 |
| 88 // NACL_MANIFEST_LIST list::C -- enumerate all names in the manifest |
| 89 void ManifestListRpc(NaClSrpcRpc* rpc, |
| 90 NaClSrpcArg** in_args, |
| 91 NaClSrpcArg** out_args, |
| 92 NaClSrpcClosure* done) { |
| 93 UNREFERENCED_PARAMETER(in_args); |
| 94 // Placeholder. This RPC handler will be replaced with code that |
| 95 // actually do manifest listing. |
| 96 // |
| 97 // TODO(bsy) hook up to real manifest info |
| 98 out_args[0]->u.count = SNPRINTF(out_args[0]->arrays.carr, |
| 99 out_args[0]->u.count, |
| 100 "This is a reply from the manifest reverse" |
| 101 " service in the plugin."); |
| 102 rpc->result = NACL_SRPC_RESULT_OK; |
| 103 done->Run(done); |
| 104 } |
| 105 |
| 106 // NACL_MANIFEST_LOOKUP lookup:si:ihC -- look up by string name, |
| 107 // resulting in a handle (if name is in the preimage), a object proxy |
| 108 // handle, and an error code. |
| 109 void ManifestLookupRpc(NaClSrpcRpc* rpc, |
| 110 NaClSrpcArg** in_args, |
| 111 NaClSrpcArg** out_args, |
| 112 NaClSrpcClosure* done) { |
| 113 char* fname = in_args[0]->arrays.str; |
| 114 int flags = in_args[0]->u.ival; |
| 115 |
| 116 NaClLog(0, "ManifestLookupRpc: %s, %d\n", fname, flags); |
| 117 out_args[0]->u.ival = 0; // ok |
| 118 out_args[1]->u.hval = (struct NaClDesc*) NaClDescInvalidMake(); |
| 119 // Placeholder. This RPC handler will be replaced with code that |
| 120 // actually do lookups/URL fetches. |
| 121 // |
| 122 // TODO(bsy): hook up to real name resolution and return a real |
| 123 // descriptor. |
| 124 out_args[2]->u.count = 10; |
| 125 strncpy(out_args[2]->arrays.carr, "123456789", 10); |
| 126 rpc->result = NACL_SRPC_RESULT_OK; |
| 127 done->Run(done); |
| 128 } |
| 129 |
| 130 // NACL_MANIFEST_UNREF unref:C:i -- dereferences the file by object |
| 131 // proxy handle. The file descriptor should have been closed. |
| 132 void ManifestUnrefRpc(NaClSrpcRpc* rpc, |
| 133 NaClSrpcArg** in_args, |
| 134 NaClSrpcArg** out_args, |
| 135 NaClSrpcClosure* done) { |
| 136 char* proxy_handle = in_args[0]->arrays.carr; |
| 137 |
| 138 NaClLog(0, "ManifestUnrefRpc: %s\n", proxy_handle); |
| 139 // Placeholder. This RPC will be replaced by real code that |
| 140 // looks up the object proxy handle to close the Pepper file object. |
| 141 // |
| 142 // TODO(bsy): replace with real code. |
| 143 out_args[0]->u.ival = 0; // ok |
| 144 rpc->result = NACL_SRPC_RESULT_OK; |
| 145 done->Run(done); |
| 146 } |
| 147 |
66 } // namespace | 148 } // namespace |
67 | 149 |
68 namespace nacl { | 150 namespace nacl { |
69 | 151 |
70 // need NaClThreadIfFactoryFunction that keeps "this" to do counting | 152 // need NaClThreadIfFactoryFunction that keeps "this" to do counting |
71 | 153 |
72 struct ReverseCountingThreadInterface { | 154 struct ReverseCountingThreadInterface { |
73 struct NaClThreadInterface base NACL_IS_REFCOUNT_SUBCLASS; | 155 struct NaClThreadInterface base NACL_IS_REFCOUNT_SUBCLASS; |
74 nacl::ReverseService* rev; | 156 nacl::ReverseService* rev; |
75 }; | 157 }; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 NaClThreadInterfaceVtbl const kReverseThreadInterfaceVtbl = { | 259 NaClThreadInterfaceVtbl const kReverseThreadInterfaceVtbl = { |
178 { | 260 { |
179 ReverseThreadIfDtor, | 261 ReverseThreadIfDtor, |
180 }, | 262 }, |
181 NaClThreadInterfaceStartThread, | 263 NaClThreadInterfaceStartThread, |
182 ReverseThreadIfLaunchCallback, | 264 ReverseThreadIfLaunchCallback, |
183 ReverseThreadIfExit, | 265 ReverseThreadIfExit, |
184 }; | 266 }; |
185 | 267 |
186 NaClSrpcHandlerDesc const ReverseService::handlers[] = { | 268 NaClSrpcHandlerDesc const ReverseService::handlers[] = { |
187 { "test:s:", Test, }, | 269 { NACL_REVERSE_CONTROL_TEST, Test, }, |
188 { "revlog:s:", RevLog, }, | 270 { NACL_REVERSE_CONTROL_LOG, RevLog, }, |
189 { "add_channel::b", AddChannel, }, | 271 { NACL_REVERSE_CONTROL_ADD_CHANNEL, AddChannel, }, |
| 272 { NACL_MANIFEST_LIST, ManifestListRpc, }, |
| 273 { NACL_MANIFEST_LOOKUP, ManifestLookupRpc, }, |
| 274 { NACL_MANIFEST_UNREF, ManifestUnrefRpc, }, |
190 { NULL, NULL, }, | 275 { NULL, NULL, }, |
191 }; | 276 }; |
192 | 277 |
193 ReverseService::ReverseService(nacl::DescWrapper* conn_cap, | 278 ReverseService::ReverseService(nacl::DescWrapper* conn_cap, |
194 ReverseInterface* rif) | 279 ReverseInterface* rif) |
195 : service_socket_(NULL), | 280 : service_socket_(NULL), |
196 reverse_interface_(rif), | 281 reverse_interface_(rif), |
197 thread_count_(0) { | 282 thread_count_(0) { |
198 /* | 283 /* |
199 * We wait for service threads to exit before dtor'ing, so the | 284 * We wait for service threads to exit before dtor'ing, so the |
(...skipping 13 matching lines...) Expand all Loading... |
213 ReverseService::~ReverseService() { | 298 ReverseService::~ReverseService() { |
214 if (thread_count_ != 0) { | 299 if (thread_count_ != 0) { |
215 NaClLog(LOG_FATAL, "ReverseService dtor when thread count is nonzero\n"); | 300 NaClLog(LOG_FATAL, "ReverseService dtor when thread count is nonzero\n"); |
216 } | 301 } |
217 NaClCondVarDtor(&cv_); | 302 NaClCondVarDtor(&cv_); |
218 NaClMutexDtor(&mu_); | 303 NaClMutexDtor(&mu_); |
219 } | 304 } |
220 | 305 |
221 | 306 |
222 bool ReverseService::Start() { | 307 bool ReverseService::Start() { |
| 308 NaClLog(4, "Entered ReverseService::Start\n"); |
223 return service_socket_->StartService(reinterpret_cast<void*>(this)); | 309 return service_socket_->StartService(reinterpret_cast<void*>(this)); |
224 } | 310 } |
225 | 311 |
226 void ReverseService::WaitForServiceThreadsToExit() { | 312 void ReverseService::WaitForServiceThreadsToExit() { |
227 NaClLog(4, "ReverseService::WaitForServiceThreadsToExit\n"); | 313 NaClLog(4, "ReverseService::WaitForServiceThreadsToExit\n"); |
228 NaClXMutexLock(&mu_); | 314 NaClXMutexLock(&mu_); |
229 while (0 != thread_count_) { | 315 while (0 != thread_count_) { |
230 NaClXCondVarWait(&cv_, &mu_); | 316 NaClXCondVarWait(&cv_, &mu_); |
231 NaClLog(5, "ReverseService::WaitForServiceThreadsToExit: woke up\n"); | 317 NaClLog(5, "ReverseService::WaitForServiceThreadsToExit: woke up\n"); |
232 } | 318 } |
(...skipping 19 matching lines...) Expand all Loading... |
252 ("ReverseService::DecrThreadCount:" | 338 ("ReverseService::DecrThreadCount:" |
253 " Decrementing thread count when count is zero\n")); | 339 " Decrementing thread count when count is zero\n")); |
254 } | 340 } |
255 if (0 == --thread_count_) { | 341 if (0 == --thread_count_) { |
256 NaClXCondVarBroadcast(&cv_); | 342 NaClXCondVarBroadcast(&cv_); |
257 } | 343 } |
258 NaClXMutexUnlock(&mu_); | 344 NaClXMutexUnlock(&mu_); |
259 } | 345 } |
260 | 346 |
261 } // namespace nacl | 347 } // namespace nacl |
OLD | NEW |