OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can be | |
4 * found in the LICENSE file. | |
5 */ | |
6 | |
7 /* | |
8 * SRPC-based test for simple rpc based access to name services. | |
9 */ | |
10 | |
11 #include <assert.h> | |
12 #include <stdio.h> | |
13 #include <stdlib.h> | |
14 #include <inttypes.h> | |
15 #include <sys/fcntl.h> | |
16 #include <string.h> | |
17 #include <unistd.h> | |
18 | |
19 #include "native_client/src/public/imc_syscalls.h" | |
20 #include "native_client/src/public/name_service.h" | |
21 #include "native_client/src/shared/srpc/nacl_srpc.h" | |
22 | |
23 #define RNG_OUTPUT_BYTES 1024 | |
24 | |
25 #define BYTES_PER_LINE 32 | |
26 #define BYTE_SPACING 4 | |
27 | |
28 struct StringBuffer { | |
29 size_t nbytes; | |
30 size_t insert; | |
31 char *buffer; | |
32 }; | |
33 | |
34 NaClSrpcChannel ns_channel; | |
35 | |
36 void StringBufferCtor(struct StringBuffer *sb) { | |
37 sb->nbytes = 1024; | |
38 sb->insert = 0; | |
39 sb->buffer = malloc(sb->nbytes); | |
40 if (NULL == sb->buffer) { | |
41 perror("StringBufferInit::malloc"); | |
42 abort(); | |
43 } | |
44 sb->buffer[0] = '\0'; | |
45 } | |
46 | |
47 void StringBufferDiscardOutput(struct StringBuffer *sb) { | |
48 sb->insert = 0; | |
49 sb->buffer[0] = '\0'; | |
50 } | |
51 | |
52 void StringBufferDtor(struct StringBuffer *sb) { | |
53 sb->nbytes = 0; | |
54 sb->insert = 0; | |
55 free(sb->buffer); | |
56 sb->buffer = NULL; | |
57 } | |
58 | |
59 void StringBufferPrintf(struct StringBuffer *sb, | |
60 char const *fmt, ...) | |
61 __attribute__((format(printf, 2, 3))); | |
62 | |
63 void StringBufferPrintf(struct StringBuffer *sb, | |
64 char const *fmt, ...) { | |
65 size_t space; | |
66 char *insert_pt; | |
67 va_list ap; | |
68 int written = 0; | |
69 char *new_buffer; | |
70 | |
71 va_start(ap, fmt); | |
72 vfprintf(stderr, fmt, ap); | |
73 va_end(ap); | |
74 | |
75 for (;;) { | |
76 space = sb->nbytes - sb->insert; | |
77 insert_pt = sb->buffer + sb->insert; | |
78 va_start(ap, fmt); | |
79 written = vsnprintf(insert_pt, space, fmt, ap); | |
80 va_end(ap); | |
81 if (written < space) { | |
82 sb->insert += written; | |
83 break; | |
84 } | |
85 /* insufficient space -- grow the buffer */ | |
86 new_buffer = realloc(sb->buffer, 2 * sb->nbytes); | |
87 if (NULL == new_buffer) { | |
88 /* give up */ | |
89 fprintf(stderr, "StringBufferPrintf: no memory\n"); | |
90 break; | |
91 } | |
92 sb->nbytes *= 2; | |
93 sb->buffer = new_buffer; | |
94 } | |
95 } | |
96 | |
97 void dump_output(struct StringBuffer *sb, int d, size_t nbytes) { | |
98 uint8_t *bytes; | |
99 int got; | |
100 int copied; | |
101 int ix; | |
102 | |
103 bytes = malloc(nbytes); | |
104 if (!bytes) { | |
105 perror("dump_output"); | |
106 fprintf(stderr, "No memory\n"); | |
107 return; | |
108 } | |
109 /* read output */ | |
110 for (got = 0; got < nbytes; got += copied) { | |
111 copied = read(d, bytes + got, nbytes - got); | |
112 if (-1 == copied) { | |
113 perror("dump_output:read"); | |
114 fprintf(stderr, "read failure\n"); | |
115 break; | |
116 } | |
117 printf("read(%d, ..., %zd) -> %d\n", d, nbytes - got, copied); | |
118 } | |
119 /* hex dump it */ | |
120 for (ix = 0; ix < got; ++ix) { | |
121 if (0 == (ix & (BYTES_PER_LINE-1))) { | |
122 StringBufferPrintf(sb, "\n%04x:", ix); | |
123 } else if (0 == (ix & (BYTE_SPACING-1))) { | |
124 StringBufferPrintf(sb, " "); | |
125 } | |
126 StringBufferPrintf(sb, "%02x", bytes[ix]); | |
127 } | |
128 StringBufferPrintf(sb, "\n"); | |
129 | |
130 free(bytes); | |
131 } | |
132 | |
133 /* | |
134 * Dump RNG output into a string. | |
135 */ | |
136 void RngDump(NaClSrpcRpc *rpc, | |
137 NaClSrpcArg **in_args, | |
138 NaClSrpcArg **out_args, | |
139 NaClSrpcClosure *done) { | |
140 struct StringBuffer sb; | |
141 NaClSrpcError rpc_result; | |
142 int status; | |
143 int rng; | |
144 | |
145 StringBufferCtor(&sb); | |
146 rpc_result = NaClSrpcInvokeBySignature(&ns_channel, NACL_NAME_SERVICE_LOOKUP, | |
147 "SecureRandom", O_RDONLY, | |
148 &status, &rng); | |
149 assert(NACL_SRPC_RESULT_OK == rpc_result); | |
150 printf("rpc status %d\n", status); | |
151 assert(NACL_NAME_SERVICE_SUCCESS == status); | |
152 printf("rng descriptor %d\n", rng); | |
153 | |
154 dump_output(&sb, rng, RNG_OUTPUT_BYTES); | |
155 out_args[0]->arrays.str = strdup(sb.buffer); | |
156 rpc->result = NACL_SRPC_RESULT_OK; | |
157 done->Run(done); | |
158 close(rng); | |
159 StringBufferDtor(&sb); | |
160 } | |
161 | |
162 void ManifestTest(NaClSrpcRpc *rpc, | |
163 NaClSrpcArg **in_args, | |
164 NaClSrpcArg **out_args, | |
165 NaClSrpcClosure *done) { | |
166 struct StringBuffer sb; | |
167 NaClSrpcError rpc_result; | |
168 int status; | |
169 int manifest; | |
170 int manifest_conn; | |
171 struct NaClSrpcChannel manifest_channel; | |
172 | |
173 /* just get the descriptor for now */ | |
174 StringBufferCtor(&sb); | |
175 if (NACL_SRPC_RESULT_OK != | |
176 (rpc_result = | |
177 NaClSrpcInvokeBySignature(&ns_channel, NACL_NAME_SERVICE_LOOKUP, | |
178 "ManifestNameService", O_RDWR, | |
jvoung (off chromium)
2015/01/09 17:36:40
I see a couple of chrome side tests that also use
Mark Seaborn
2015/01/10 07:00:36
Thanks for catching that. Done: https://coderevie
| |
179 &status, &manifest))) { | |
180 StringBufferPrintf(&sb, "nameservice lookup RPC failed (%d)\n", rpc_result); | |
181 goto done; | |
182 } | |
183 StringBufferPrintf(&sb, "Got manifest descriptor %d\n", manifest); | |
184 if (-1 == manifest) { | |
185 fprintf(stderr, "nameservice lookup failed, status %d\n", status); | |
186 goto done; | |
187 } | |
188 /* connect to manifest name server */ | |
189 | |
190 manifest_conn = imc_connect(manifest); | |
191 StringBufferPrintf(&sb, "got manifest connection %d\n", manifest_conn); | |
192 if (-1 == manifest_conn) { | |
193 StringBufferPrintf(&sb, "could not connect\n"); | |
194 goto done; | |
195 } | |
196 close(manifest); | |
197 if (!NaClSrpcClientCtor(&manifest_channel, manifest_conn)) { | |
198 StringBufferPrintf(&sb, "could not build srpc client\n"); | |
199 goto done; | |
200 } | |
201 StringBufferDiscardOutput(&sb); | |
202 StringBufferPrintf(&sb, "ManifestTest: basic connectivity ok\n"); | |
203 | |
204 done: | |
205 out_args[0]->arrays.str = strdup(sb.buffer); | |
206 rpc->result = NACL_SRPC_RESULT_OK; | |
207 done->Run(done); | |
208 StringBufferDtor(&sb); | |
209 } | |
210 | |
211 const struct NaClSrpcHandlerDesc srpc_methods[] = { | |
212 /* Export the methods as taking no arguments and returning a string. */ | |
213 { "rngdump::s", RngDump }, | |
214 { "manifest_test::s", ManifestTest }, | |
215 { NULL, NULL }, | |
216 }; | |
217 | |
218 int main(void) { | |
219 int ns; | |
220 int connected_socket; | |
221 | |
222 if (!NaClSrpcModuleInit()) { | |
223 return 1; | |
224 } | |
225 ns = -1; | |
226 nacl_nameservice(&ns); | |
227 assert(-1 != ns); | |
228 | |
229 connected_socket = imc_connect(ns); | |
230 assert(-1 != connected_socket); | |
231 if (!NaClSrpcClientCtor(&ns_channel, connected_socket)) { | |
232 fprintf(stderr, "Srpc client channel ctor failed\n"); | |
233 return 1; | |
234 } | |
235 close(ns); | |
236 | |
237 if (!NaClSrpcAcceptClientConnection(srpc_methods)) { | |
238 return 1; | |
239 } | |
240 NaClSrpcModuleFini(); | |
241 return 0; | |
242 } | |
OLD | NEW |