]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/jsonrpc/jsonrpc_server.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / lib / jsonrpc / jsonrpc_server.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright (c) Intel Corporation.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "jsonrpc_internal.h"
35
36 #include "spdk/util.h"
37
38 struct jsonrpc_request {
39 const struct spdk_json_val *version;
40 const struct spdk_json_val *method;
41 const struct spdk_json_val *params;
42 const struct spdk_json_val *id;
43 };
44
45 static int
46 capture_val(const struct spdk_json_val *val, void *out)
47 {
48 const struct spdk_json_val **vptr = out;
49
50 *vptr = val;
51 return 0;
52 }
53
54 static const struct spdk_json_object_decoder jsonrpc_request_decoders[] = {
55 {"jsonrpc", offsetof(struct jsonrpc_request, version), capture_val, true},
56 {"method", offsetof(struct jsonrpc_request, method), capture_val},
57 {"params", offsetof(struct jsonrpc_request, params), capture_val, true},
58 {"id", offsetof(struct jsonrpc_request, id), capture_val, true},
59 };
60
61 static void
62 parse_single_request(struct spdk_jsonrpc_request *request, struct spdk_json_val *values)
63 {
64 struct jsonrpc_request req = {};
65
66 if (spdk_json_decode_object(values, jsonrpc_request_decoders,
67 SPDK_COUNTOF(jsonrpc_request_decoders),
68 &req)) {
69 goto invalid;
70 }
71
72 if (req.version && (req.version->type != SPDK_JSON_VAL_STRING ||
73 !spdk_json_strequal(req.version, "2.0"))) {
74 goto invalid;
75 }
76
77 if (!req.method || req.method->type != SPDK_JSON_VAL_STRING) {
78 goto invalid;
79 }
80
81 if (req.id) {
82 if (req.id->type == SPDK_JSON_VAL_STRING ||
83 req.id->type == SPDK_JSON_VAL_NUMBER ||
84 req.id->type == SPDK_JSON_VAL_NULL) {
85 request->id = req.id;
86 } else {
87 goto invalid;
88 }
89 }
90
91 if (req.params) {
92 if (req.params->type != SPDK_JSON_VAL_ARRAY_BEGIN &&
93 req.params->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
94 goto invalid;
95 }
96 }
97
98 spdk_jsonrpc_server_handle_request(request, req.method, req.params);
99 return;
100
101 invalid:
102 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
103 }
104
105 int
106 spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, const void *json, size_t size)
107 {
108 struct spdk_jsonrpc_request *request;
109 ssize_t rc;
110 size_t len;
111 void *end = NULL;
112
113 /* Check to see if we have received a full JSON value. It is safe to cast away const
114 * as we don't decode in place. */
115 rc = spdk_json_parse((void *)json, size, NULL, 0, &end, 0);
116 if (rc == SPDK_JSON_PARSE_INCOMPLETE) {
117 return 0;
118 }
119
120 request = calloc(1, sizeof(*request));
121 if (request == NULL) {
122 SPDK_DEBUGLOG(SPDK_LOG_RPC, "Out of memory allocating request\n");
123 return -1;
124 }
125
126 conn->outstanding_requests++;
127
128 request->conn = conn;
129
130 len = end - json;
131 request->recv_buffer = malloc(len + 1);
132 if (request->recv_buffer == NULL) {
133 SPDK_ERRLOG("Failed to allocate buffer to copy request (%zu bytes)\n", len + 1);
134 spdk_jsonrpc_free_request(request);
135 return -1;
136 }
137
138 memcpy(request->recv_buffer, json, len);
139 request->recv_buffer[len] = '\0';
140
141 if (rc > 0 && rc <= SPDK_JSONRPC_MAX_VALUES) {
142 request->values_cnt = rc;
143 request->values = malloc(request->values_cnt * sizeof(request->values[0]));
144 if (request->values == NULL) {
145 SPDK_ERRLOG("Failed to allocate buffer for JSON values (%zu bytes)\n",
146 request->values_cnt * sizeof(request->values[0]));
147 spdk_jsonrpc_free_request(request);
148 return -1;
149 }
150 }
151
152 request->send_offset = 0;
153 request->send_len = 0;
154 request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT;
155 request->send_buf = malloc(request->send_buf_size);
156 if (request->send_buf == NULL) {
157 SPDK_ERRLOG("Failed to allocate send_buf (%zu bytes)\n", request->send_buf_size);
158 spdk_jsonrpc_free_request(request);
159 return -1;
160 }
161
162 if (rc <= 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
163 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n");
164 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
165
166 /*
167 * Can't recover from parse error (no guaranteed resync point in streaming JSON).
168 * Return an error to indicate that the connection should be closed.
169 */
170 return -1;
171 }
172
173 /* Decode a second time now that there is a full JSON value available. */
174 rc = spdk_json_parse(request->recv_buffer, size, request->values, request->values_cnt, &end,
175 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE);
176 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
177 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error on second pass\n");
178 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
179 return -1;
180 }
181
182 assert(end != NULL);
183
184 if (request->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
185 parse_single_request(request, request->values);
186 } else if (request->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) {
187 SPDK_DEBUGLOG(SPDK_LOG_RPC, "Got batch array (not currently supported)\n");
188 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
189 } else {
190 SPDK_DEBUGLOG(SPDK_LOG_RPC, "top-level JSON value was not array or object\n");
191 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
192 }
193
194 return len;
195 }
196
197 struct spdk_jsonrpc_server_conn *
198 spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request *request)
199 {
200 return request->conn;
201 }
202
203 static int
204 spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size)
205 {
206 struct spdk_jsonrpc_request *request = cb_ctx;
207 size_t new_size = request->send_buf_size;
208
209 while (new_size - request->send_len < size) {
210 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) {
211 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n",
212 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX);
213 return -1;
214 }
215
216 new_size *= 2;
217 }
218
219 if (new_size != request->send_buf_size) {
220 uint8_t *new_buf;
221
222 new_buf = realloc(request->send_buf, new_size);
223 if (new_buf == NULL) {
224 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n",
225 request->send_buf_size, new_size);
226 return -1;
227 }
228
229 request->send_buf = new_buf;
230 request->send_buf_size = new_size;
231 }
232
233 memcpy(request->send_buf + request->send_len, data, size);
234 request->send_len += size;
235
236 return 0;
237 }
238
239 static struct spdk_json_write_ctx *
240 begin_response(struct spdk_jsonrpc_request *request)
241 {
242 struct spdk_json_write_ctx *w;
243
244 w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0);
245 if (w == NULL) {
246 return NULL;
247 }
248
249 spdk_json_write_object_begin(w);
250 spdk_json_write_named_string(w, "jsonrpc", "2.0");
251
252 spdk_json_write_name(w, "id");
253 if (request->id) {
254 spdk_json_write_val(w, request->id);
255 } else {
256 spdk_json_write_null(w);
257 }
258
259 return w;
260 }
261
262 static void
263 skip_response(struct spdk_jsonrpc_request *request)
264 {
265 request->send_len = 0;
266 spdk_jsonrpc_server_send_response(request);
267 }
268
269 static void
270 end_response(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
271 {
272 spdk_json_write_object_end(w);
273 spdk_json_write_end(w);
274 spdk_jsonrpc_server_write_cb(request, "\n", 1);
275 spdk_jsonrpc_server_send_response(request);
276 }
277
278 void
279 spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request)
280 {
281 if (!request) {
282 return;
283 }
284
285 request->conn->outstanding_requests--;
286 free(request->recv_buffer);
287 free(request->values);
288 free(request->send_buf);
289 free(request);
290 }
291
292 struct spdk_json_write_ctx *
293 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
294 {
295 struct spdk_json_write_ctx *w;
296
297 if (request->id == NULL || request->id->type == SPDK_JSON_VAL_NULL) {
298 /* Notification - no response required */
299 skip_response(request);
300 return NULL;
301 }
302
303 w = begin_response(request);
304 if (w == NULL) {
305 skip_response(request);
306 return NULL;
307 }
308
309 spdk_json_write_name(w, "result");
310
311 return w;
312 }
313
314 void
315 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
316 {
317 assert(w != NULL);
318
319 end_response(request, w);
320 }
321
322 void
323 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
324 int error_code, const char *msg)
325 {
326 struct spdk_json_write_ctx *w;
327
328 w = begin_response(request);
329 if (w == NULL) {
330 skip_response(request);
331 return;
332 }
333
334 spdk_json_write_named_object_begin(w, "error");
335 spdk_json_write_named_int32(w, "code", error_code);
336 spdk_json_write_named_string(w, "message", msg);
337 spdk_json_write_object_end(w);
338
339 end_response(request, w);
340 }
341
342 void
343 spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
344 int error_code, const char *fmt, ...)
345 {
346 struct spdk_json_write_ctx *w;
347 va_list args;
348
349 w = begin_response(request);
350 if (w == NULL) {
351 skip_response(request);
352 return;
353 }
354
355 spdk_json_write_named_object_begin(w, "error");
356 spdk_json_write_named_int32(w, "code", error_code);
357 va_start(args, fmt);
358 spdk_json_write_named_string_fmt_v(w, "message", fmt, args);
359 va_end(args);
360 spdk_json_write_object_end(w);
361
362 end_response(request, w);
363 }
364
365 SPDK_LOG_REGISTER_COMPONENT("rpc", SPDK_LOG_RPC)