Index: src/trusted/manifest_name_service_proxy/manifest_proxy.c |
=================================================================== |
--- src/trusted/manifest_name_service_proxy/manifest_proxy.c (revision 0) |
+++ src/trusted/manifest_name_service_proxy/manifest_proxy.c (revision 0) |
@@ -0,0 +1,354 @@ |
+/* |
+ * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "native_client/src/trusted/manifest_name_service_proxy/manifest_proxy.h" |
+ |
+#include "native_client/src/shared/platform/nacl_log.h" |
+#include "native_client/src/shared/platform/nacl_sync.h" |
+#include "native_client/src/shared/platform/nacl_sync_checked.h" |
+#include "native_client/src/shared/srpc/nacl_srpc.h" |
+#include "native_client/src/trusted/reverse_service/manifest_rpc.h" |
+#include "native_client/src/trusted/reverse_service/reverse_control_rpc.h" |
+#include "native_client/src/trusted/service_runtime/include/sys/errno.h" |
+#include "native_client/src/trusted/service_runtime/include/sys/nacl_name_service.h" |
+#include "native_client/src/trusted/service_runtime/sel_ldr.h" |
+ |
+static void NaClManifestWaitForChannel_yield_mu( |
+ struct NaClManifestProxyConnection *self) { |
+ NaClLog(4, "Entered NaClManifestWaitForChannel_yield_mu\n"); |
+ NaClXMutexLock(&self->mu); |
+ NaClLog(4, "NaClManifestWaitForChannel_yield_mu: checking channel\n"); |
+ while (!self->channel_initialized) { |
+ NaClLog(4, "NaClManifestWaitForChannel_yield_mu: waiting\n"); |
+ NaClXCondVarWait(&self->cv, &self->mu); |
+ } |
+ NaClLog(4, "Leaving NaClManifestWaitForChannel_yield_mu\n"); |
+} |
+ |
+static void NaClManifestReleaseChannel_release_mu( |
+ struct NaClManifestProxyConnection *self) { |
+ NaClLog(4, "NaClManifestReleaseChannel_release_mu\n"); |
+ NaClXMutexUnlock(&self->mu); |
+} |
+ |
+static void NaClManifestNameServiceListRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ struct NaClManifestProxyConnection *proxy_conn = |
+ (struct NaClManifestProxyConnection *) rpc->channel->server_instance_data; |
+ uint32_t nbytes = out_args[0]->u.count; |
+ char *dest = out_args[0]->arrays.carr; |
+ NaClSrpcError srpc_error; |
+ |
+ UNREFERENCED_PARAMETER(in_args); |
+ NaClLog(4, |
+ "NaClManifestNameServiceListRpc, proxy_conn 0x%"NACL_PRIxPTR"\n", |
+ (uintptr_t) proxy_conn); |
+ |
+ NaClManifestWaitForChannel_yield_mu(proxy_conn); |
+ |
+ if (NACL_SRPC_RESULT_OK != |
+ (srpc_error = |
+ NaClSrpcInvokeBySignature(&proxy_conn->client_channel, |
+ NACL_MANIFEST_LIST, |
+ &nbytes, dest))) { |
+ NaClLog(1, |
+ ("Manifest list via channel 0x%"NACL_PRIxPTR" with RPC " |
+ NACL_MANIFEST_LIST" failed: %d\n"), |
+ (uintptr_t) &proxy_conn->client_channel, |
+ srpc_error); |
+ rpc->result = srpc_error; |
+ } else { |
+ out_args[0]->u.count = nbytes; |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ } |
+ (*done_cls->Run)(done_cls); |
+ NaClManifestReleaseChannel_release_mu(proxy_conn); |
+} |
+ |
+static void NaClManifestNameServiceInsertRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ |
+ UNREFERENCED_PARAMETER(in_args); |
+ NaClLog(4, "NaClManifestNameServiceInsertRpc\n"); |
+ out_args[0]->u.ival = NACL_NAME_SERVICE_PERMISSION_DENIED; |
+ /* cannot add names to the manifest! */ |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ (*done_cls->Run)(done_cls); |
+} |
+ |
+static void NaClManifestNameServiceLookupRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ struct NaClManifestProxyConnection *proxy_conn = |
+ (struct NaClManifestProxyConnection *) rpc->channel->server_instance_data; |
+ char *name = in_args[0]->arrays.str; |
+ int flags = in_args[1]->u.ival; |
+ int status; |
+ struct NaClDesc *desc; |
+ NaClSrpcError srpc_error; |
+ |
+ NaClLog(4, "NaClManifestNameServiceLookupRpc\n"); |
+ |
+ NaClManifestWaitForChannel_yield_mu(proxy_conn); |
+ |
+ if (NACL_SRPC_RESULT_OK != |
+ (srpc_error = |
+ NaClSrpcInvokeBySignature(&proxy_conn->client_channel, |
+ NACL_MANIFEST_LOOKUP, |
+ name, |
+ flags, |
+ &status, |
+ &desc))) { |
+ NaClLog(1, |
+ ("Manifest lookup via channel 0x%"NACL_PRIxPTR" with RPC " |
+ NACL_MANIFEST_LOOKUP" failed: %d\n"), |
+ (uintptr_t) &proxy_conn->client_channel, |
+ srpc_error); |
+ rpc->result = srpc_error; |
+ } else { |
+ out_args[0]->u.ival = status; |
+ out_args[1]->u.hval = desc; |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ } |
+ (*done_cls->Run)(done_cls); |
+ NaClManifestReleaseChannel_release_mu(proxy_conn); |
+} |
+ |
+static void NaClManifestNameServiceDeleteRpc( |
+ struct NaClSrpcRpc *rpc, |
+ struct NaClSrpcArg **in_args, |
+ struct NaClSrpcArg **out_args, |
+ struct NaClSrpcClosure *done_cls) { |
+ |
+ UNREFERENCED_PARAMETER(in_args); |
+ NaClLog(4, "NaClManifestNameServiceDeleteRpc\n"); |
+ out_args[0]->u.ival = NACL_NAME_SERVICE_PERMISSION_DENIED; |
+ rpc->result = NACL_SRPC_RESULT_OK; |
+ (*done_cls->Run)(done_cls); |
+} |
+ |
+struct NaClSrpcHandlerDesc const kNaClManifestProxyHandlers[] = { |
+ { NACL_NAME_SERVICE_LIST, NaClManifestNameServiceListRpc, }, |
+ { NACL_NAME_SERVICE_INSERT, NaClManifestNameServiceInsertRpc, }, |
+ { NACL_NAME_SERVICE_LOOKUP, NaClManifestNameServiceLookupRpc, }, |
+ { NACL_NAME_SERVICE_DELETE, NaClManifestNameServiceDeleteRpc, }, |
+ { (char const *) NULL, (NaClSrpcMethod) NULL, }, |
+}; |
+ |
+ |
+int NaClManifestProxyCtor(struct NaClManifestProxy *self, |
+ NaClThreadIfFactoryFunction thread_factory_fn, |
+ void *thread_factory_data, |
+ struct NaClApp *nap) { |
+ NaClLog(4, |
+ ("Entered NaClManifestProxyCtor: self 0x%"NACL_PRIxPTR |
+ ", nap 0x%"NACL_PRIxPTR"\n"), |
+ (uintptr_t) self, |
+ (uintptr_t) nap); |
+ if (!NaClSimpleServiceCtor(&self->base, |
+ kNaClManifestProxyHandlers, |
+ thread_factory_fn, |
+ thread_factory_data)) { |
+ return 0; |
+ } |
+ self->nap = nap; |
+ NACL_VTBL(NaClRefCount, self) = |
+ (struct NaClRefCountVtbl *) &kNaClManifestProxyVtbl; |
+ return 1; |
+} |
+ |
+void NaClManifestProxyDtor(struct NaClRefCount *vself) { |
+ struct NaClManifestProxy *self = |
+ (struct NaClManifestProxy *) vself; |
+ |
+ NACL_VTBL(NaClRefCount, self) = |
+ (struct NaClRefCountVtbl *) &kNaClSimpleServiceVtbl; |
+ (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); |
+} |
+ |
+int NaClManifestProxyConnectionCtor(struct NaClManifestProxyConnection *self, |
+ struct NaClManifestProxy *server, |
+ struct NaClDesc *conn) { |
+ NaClLog(4, |
+ "Entered NaClManifestProxyConnectionCtor, self 0x%"NACL_PRIxPTR"\n", |
+ (uintptr_t) self); |
+ if (!NaClSimpleServiceConnectionCtor( |
+ &self->base, |
+ (struct NaClSimpleService *) server, |
+ conn, |
+ (void *) self)) { |
+ NaClLog(4, |
+ ("NaClManifestProxyConnectionCtor: base class ctor" |
+ " NaClSimpleServiceConnectionCtor failed\n")); |
+ return 0; |
+ } |
+ NaClXMutexCtor(&self->mu); |
+ NaClXCondVarCtor(&self->cv); |
+ self->channel_initialized = 0; |
+ NACL_VTBL(NaClRefCount, self) = |
+ (struct NaClRefCountVtbl *) &kNaClManifestProxyConnectionVtbl; |
+ return 1; |
+} |
+ |
+void NaClManifestProxyConnectionRevHandleConnect( |
+ struct NaClManifestProxyConnection *self, |
+ struct NaClDesc *rev) { |
+ NaClLog(4, "Entered NaClManifestProxyConnectionRevHandleConnect\n"); |
+ NaClXMutexLock(&self->mu); |
+ if (self->channel_initialized) { |
+ NaClLog(LOG_FATAL, |
+ "NaClManifestProxyConnectionRevHandleConnect: double connect?\n"); |
+ } |
+ /* |
+ * If NaClSrpcClientCtor proves to take too long, we should spin off |
+ * another thread to do the initialization so that the reverse |
+ * client can accept additional reverse channels. |
+ */ |
+ NaClLog(4, |
+ "NaClManifestProxyConnectionRevHandleConnect: Creating SrpcClient\n"); |
+ if (NaClSrpcClientCtor(&self->client_channel, rev)) { |
+ NaClLog(4, |
+ ("NaClManifestProxyConnectionRevHandleConnect: SrpcClientCtor" |
+ " succeded, announcing.\n")); |
+ self->channel_initialized = 1; |
+ NaClXCondVarBroadcast(&self->cv); |
+ /* ownership of rev taken */ |
+ } else { |
+ NaClLog(4, |
+ ("NaClManifestProxyConnectionRevHandleConnect: NaClSrpcClientCtor" |
+ " failed\n")); |
+ } |
+ NaClXMutexUnlock(&self->mu); |
+ NaClLog(4, "Leaving NaClManifestProxyConnectionRevHandleConnect\n"); |
+} |
+ |
+void NaClManifestProxyConnectionDtor(struct NaClRefCount *vself) { |
+ struct NaClManifestProxyConnection *self = |
+ (struct NaClManifestProxyConnection *) vself; |
+ NaClLog(4, |
+ "Entered NaClManifestProxyConnectionDtor: self 0x%"NACL_PRIxPTR"\n", |
+ (uintptr_t) self); |
+ NaClSrpcDtor(&self->client_channel); |
+ NACL_VTBL(NaClSimpleServiceConnection, self) = |
+ &kNaClSimpleServiceConnectionVtbl; |
+ (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself); |
+} |
+ |
+/* |
+ * NaClManifestProxyConnection is a NaClSimpleServiceConnection |
+ */ |
+struct NaClSimpleServiceConnectionVtbl |
+ const kNaClManifestProxyConnectionVtbl = { |
+ { |
+ NaClManifestProxyConnectionDtor, |
+ }, |
+ NaClSimpleServiceConnectionServerLoop, |
+}; |
+ |
+static void NaClManifestReverseClientCallback( |
+ void *state, |
+ struct NaClThreadInterface *tif, |
+ struct NaClDesc *new_conn) { |
+ struct NaClManifestProxyConnection *mconn = |
+ (struct NaClManifestProxyConnection *) state; |
+ |
+ UNREFERENCED_PARAMETER(tif); |
+ NaClLog(4, "Entered NaClManifestReverseClientCallback\n"); |
+ NaClManifestProxyConnectionRevHandleConnect(mconn, new_conn); |
+} |
+ |
+int NaClManifestProxyConnectionFactory( |
+ struct NaClSimpleService *vself, |
+ struct NaClDesc *conn, |
+ struct NaClSimpleServiceConnection **out) { |
+ struct NaClManifestProxy *self = |
+ (struct NaClManifestProxy *) vself; |
+ struct NaClApp *nap = self->nap; |
+ struct NaClManifestProxyConnection *mconn; |
+ NaClSrpcError rpc_result; |
+ int bool_status; |
+ |
+ NaClLog(4, |
+ ("Entered NaClManifestProxyConnectionFactory, self 0x%"NACL_PRIxPTR |
+ "\n"), |
+ (uintptr_t) self); |
+ mconn = (struct NaClManifestProxyConnection *) malloc(sizeof *mconn); |
+ if (NULL == mconn) { |
+ NaClLog(4, "NaClManifestProxyConnectionFactory: no memory\n"); |
+ return -NACL_ABI_ENOMEM; |
+ } |
+ NaClLog(4, "NaClManifestProxyConnectionFactory: creating connection obj\n"); |
+ if (!NaClManifestProxyConnectionCtor(mconn, self, conn)) { |
+ free(mconn); |
+ return -NACL_ABI_EIO; |
+ } |
+ |
+ /* |
+ * Construct via NaClSecureReverseClientCtor with a callback to |
+ * process the new reverse connection -- which should be stored in |
+ * the mconn object. |
+ * |
+ * Make reverse RPC to obtain a new reverse RPC connection. |
+ */ |
+ NaClLog(4, "NaClManifestProxyConnectionFactory: locking reverse channel\n"); |
+ NaClLog(4, "NaClManifestProxyConnectionFactory: nap 0x%"NACL_PRIxPTR"\n", |
+ (uintptr_t) nap); |
+ NaClXMutexLock(&nap->mu); |
+ if (!nap->reverse_channel_initialized) { |
+ NaClLog(LOG_FATAL, |
+ "NaClManifestProxyConnectionFactory invoked w/o reverse channel\n"); |
+ } |
+ NaClLog(4, "NaClManifestProxyConnectionFactory: inserting handler\n"); |
+ if (!NaClSecureReverseClientInsertHandler(nap->reverse_client, |
+ NaClManifestReverseClientCallback, |
+ (void *) mconn)) { |
+ NaClLog(LOG_FATAL, |
+ ("NaClManifestProxyConnectionFactory:" |
+ " NaClSecureReverseClientInsertHandler failed\n")); |
+ } |
+ /* |
+ * NaClSrpcInvokeBySignature(""); tell plugin to connect and create |
+ * a reverse channel |
+ */ |
+ NaClLog(4, |
+ ("NaClManifestProxyConnectionFactory: making RPC" |
+ " to set up connection\n")); |
+ rpc_result = NaClSrpcInvokeBySignature(&nap->reverse_channel, |
+ NACL_REVERSE_CONTROL_ADD_CHANNEL, |
+ &bool_status); |
+ NaClLog(4, |
+ "NaClManifestProxyConnectionFactory: Start status %d\n", bool_status); |
+ |
+ NaClXMutexUnlock(&nap->mu); |
+ |
+ *out = (struct NaClSimpleServiceConnection *) mconn; |
+ return 0; |
+} |
+ |
+struct NaClSimpleServiceVtbl const kNaClManifestProxyVtbl = { |
+ { |
+ NaClManifestProxyDtor, |
+ }, |
+ NaClManifestProxyConnectionFactory, |
+ /* see name_service.c vtbl for connection factory and ownership */ |
+ /* |
+ * The NaClManifestProxyConnectionFactory creates a subclass of a |
+ * NaClSimpleServiceConnectionFactory object that uses the reverse |
+ * connection object nap->reverse_client to obtain a new RPC channel |
+ * with each manifest connection. |
+ */ |
+ NaClSimpleServiceAcceptConnection, |
+ NaClSimpleServiceAcceptAndSpawnHandler, |
+ NaClSimpleServiceRpcHandler, |
+}; |
Property changes on: src/trusted/manifest_name_service_proxy/manifest_proxy.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |