1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2016 Intel Corporation. All rights reserved.
3 * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4 */
5
6 #include "jsonrpc_internal.h"
7
8 #include "spdk/util.h"
9
10 static enum spdk_log_level g_rpc_log_level = SPDK_LOG_DISABLED;
11 static FILE *g_rpc_log_file = NULL;
12
13 struct jsonrpc_request {
14 const struct spdk_json_val *version;
15 const struct spdk_json_val *method;
16 const struct spdk_json_val *params;
17 const struct spdk_json_val *id;
18 };
19
20 void
spdk_jsonrpc_set_log_level(enum spdk_log_level level)21 spdk_jsonrpc_set_log_level(enum spdk_log_level level)
22 {
23 assert(level >= SPDK_LOG_DISABLED);
24 assert(level <= SPDK_LOG_DEBUG);
25 g_rpc_log_level = level;
26 }
27
28 void
spdk_jsonrpc_set_log_file(FILE * file)29 spdk_jsonrpc_set_log_file(FILE *file)
30 {
31 g_rpc_log_file = file;
32 }
33
34 static void
remove_newlines(char * text)35 remove_newlines(char *text)
36 {
37 int i = 0, j = 0;
38
39 while (text[i] != '\0') {
40 if (text[i] != '\n') {
41 text[j++] = text[i];
42 }
43 i++;
44 }
45 text[j] = '\0';
46 }
47
48 static void
jsonrpc_log(char * buf,const char * prefix)49 jsonrpc_log(char *buf, const char *prefix)
50 {
51 /* Some custom applications have enabled SPDK_JSON_PARSE_FLAG_ALLOW_COMMENTS
52 * to allow comments in JSON RPC objects. To keep backward compatibility of
53 * these applications, remove newlines only if JSON RPC logging is enabled.
54 */
55 if (g_rpc_log_level != SPDK_LOG_DISABLED || g_rpc_log_file != NULL) {
56 remove_newlines(buf);
57 }
58
59 if (g_rpc_log_level != SPDK_LOG_DISABLED) {
60 spdk_log(g_rpc_log_level, NULL, 0, NULL, "%s%s\n", prefix, buf);
61 }
62
63 if (g_rpc_log_file != NULL) {
64 spdk_flog(g_rpc_log_file, NULL, 0, NULL, "%s%s\n", prefix, buf);
65 }
66 }
67
68 static int
capture_val(const struct spdk_json_val * val,void * out)69 capture_val(const struct spdk_json_val *val, void *out)
70 {
71 const struct spdk_json_val **vptr = out;
72
73 *vptr = val;
74 return 0;
75 }
76
77 static const struct spdk_json_object_decoder jsonrpc_request_decoders[] = {
78 {"jsonrpc", offsetof(struct jsonrpc_request, version), capture_val, true},
79 {"method", offsetof(struct jsonrpc_request, method), capture_val},
80 {"params", offsetof(struct jsonrpc_request, params), capture_val, true},
81 {"id", offsetof(struct jsonrpc_request, id), capture_val, true},
82 };
83
84 static void
parse_single_request(struct spdk_jsonrpc_request * request,struct spdk_json_val * values)85 parse_single_request(struct spdk_jsonrpc_request *request, struct spdk_json_val *values)
86 {
87 struct jsonrpc_request req = {};
88 const struct spdk_json_val *params = NULL;
89
90 if (spdk_json_decode_object(values, jsonrpc_request_decoders,
91 SPDK_COUNTOF(jsonrpc_request_decoders),
92 &req)) {
93 goto invalid;
94 }
95
96 if (req.version && (req.version->type != SPDK_JSON_VAL_STRING ||
97 !spdk_json_strequal(req.version, "2.0"))) {
98 goto invalid;
99 }
100
101 if (!req.method || req.method->type != SPDK_JSON_VAL_STRING) {
102 goto invalid;
103 }
104
105 if (req.id) {
106 if (req.id->type == SPDK_JSON_VAL_STRING ||
107 req.id->type == SPDK_JSON_VAL_NUMBER ||
108 req.id->type == SPDK_JSON_VAL_NULL) {
109 request->id = req.id;
110 } else {
111 goto invalid;
112 }
113 }
114
115 if (req.params) {
116 /* null json value is as if there were no parameters */
117 if (req.params->type != SPDK_JSON_VAL_NULL) {
118 if (req.params->type != SPDK_JSON_VAL_ARRAY_BEGIN &&
119 req.params->type != SPDK_JSON_VAL_OBJECT_BEGIN) {
120 goto invalid;
121 }
122 params = req.params;
123 }
124 }
125
126 jsonrpc_server_handle_request(request, req.method, params);
127 return;
128
129 invalid:
130 jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
131 }
132
133 static int
jsonrpc_server_write_cb(void * cb_ctx,const void * data,size_t size)134 jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size)
135 {
136 struct spdk_jsonrpc_request *request = cb_ctx;
137 size_t new_size = request->send_buf_size;
138
139 while (new_size - request->send_len < size) {
140 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) {
141 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n",
142 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX);
143 return -1;
144 }
145
146 new_size *= 2;
147 }
148
149 if (new_size != request->send_buf_size) {
150 uint8_t *new_buf;
151
152 /* Add extra byte for the null terminator. */
153 new_buf = realloc(request->send_buf, new_size + 1);
154 if (new_buf == NULL) {
155 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n",
156 request->send_buf_size, new_size);
157 return -1;
158 }
159
160 request->send_buf = new_buf;
161 request->send_buf_size = new_size;
162 }
163
164 memcpy(request->send_buf + request->send_len, data, size);
165 request->send_len += size;
166
167 return 0;
168 }
169
170 int
jsonrpc_parse_request(struct spdk_jsonrpc_server_conn * conn,const void * json,size_t size)171 jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, const void *json, size_t size)
172 {
173 struct spdk_jsonrpc_request *request;
174 ssize_t rc;
175 size_t len;
176 void *end = NULL;
177
178 /* Check to see if we have received a full JSON value. It is safe to cast away const
179 * as we don't decode in place. */
180 rc = spdk_json_parse((void *)json, size, NULL, 0, &end, 0);
181 if (rc == SPDK_JSON_PARSE_INCOMPLETE) {
182 return 0;
183 }
184
185 request = calloc(1, sizeof(*request));
186 if (request == NULL) {
187 SPDK_DEBUGLOG(rpc, "Out of memory allocating request\n");
188 return -1;
189 }
190
191 pthread_spin_lock(&conn->queue_lock);
192 conn->outstanding_requests++;
193 STAILQ_INSERT_TAIL(&conn->outstanding_queue, request, link);
194 pthread_spin_unlock(&conn->queue_lock);
195
196 request->conn = conn;
197
198 len = end - json;
199 request->recv_buffer = malloc(len + 1);
200 if (request->recv_buffer == NULL) {
201 SPDK_ERRLOG("Failed to allocate buffer to copy request (%zu bytes)\n", len + 1);
202 jsonrpc_free_request(request);
203 return -1;
204 }
205
206 memcpy(request->recv_buffer, json, len);
207 request->recv_buffer[len] = '\0';
208
209 jsonrpc_log(request->recv_buffer, "request: ");
210
211 if (rc > 0 && rc <= SPDK_JSONRPC_MAX_VALUES) {
212 request->values_cnt = rc;
213 request->values = malloc(request->values_cnt * sizeof(request->values[0]));
214 if (request->values == NULL) {
215 SPDK_ERRLOG("Failed to allocate buffer for JSON values (%zu bytes)\n",
216 request->values_cnt * sizeof(request->values[0]));
217 jsonrpc_free_request(request);
218 return -1;
219 }
220 }
221
222 request->send_offset = 0;
223 request->send_len = 0;
224 request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT;
225 /* Add extra byte for the null terminator. */
226 request->send_buf = malloc(request->send_buf_size + 1);
227 if (request->send_buf == NULL) {
228 SPDK_ERRLOG("Failed to allocate send_buf (%zu bytes)\n", request->send_buf_size);
229 jsonrpc_free_request(request);
230 return -1;
231 }
232
233 request->response = spdk_json_write_begin(jsonrpc_server_write_cb, request, 0);
234 if (request->response == NULL) {
235 SPDK_ERRLOG("Failed to allocate response JSON write context.\n");
236 jsonrpc_free_request(request);
237 return -1;
238 }
239
240 if (rc <= 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
241 SPDK_DEBUGLOG(rpc, "JSON parse error\n");
242 jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
243
244 /*
245 * Can't recover from parse error (no guaranteed resync point in streaming JSON).
246 * Return an error to indicate that the connection should be closed.
247 */
248 return -1;
249 }
250
251 /* Decode a second time now that there is a full JSON value available. */
252 rc = spdk_json_parse(request->recv_buffer, size, request->values, request->values_cnt, &end,
253 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE);
254 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
255 SPDK_DEBUGLOG(rpc, "JSON parse error on second pass\n");
256 jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
257 return -1;
258 }
259
260 assert(end != NULL);
261
262 if (request->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
263 parse_single_request(request, request->values);
264 } else if (request->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) {
265 SPDK_DEBUGLOG(rpc, "Got batch array (not currently supported)\n");
266 jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
267 } else {
268 SPDK_DEBUGLOG(rpc, "top-level JSON value was not array or object\n");
269 jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
270 }
271
272 return len;
273 }
274
275 struct spdk_jsonrpc_server_conn *
spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request * request)276 spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request *request)
277 {
278 return request->conn;
279 }
280
281 /* Never return NULL */
282 static struct spdk_json_write_ctx *
begin_response(struct spdk_jsonrpc_request * request)283 begin_response(struct spdk_jsonrpc_request *request)
284 {
285 struct spdk_json_write_ctx *w = request->response;
286
287 spdk_json_write_object_begin(w);
288 spdk_json_write_named_string(w, "jsonrpc", "2.0");
289
290 spdk_json_write_name(w, "id");
291 if (request->id) {
292 spdk_json_write_val(w, request->id);
293 } else {
294 spdk_json_write_null(w);
295 }
296
297 return w;
298 }
299
300 static void
skip_response(struct spdk_jsonrpc_request * request)301 skip_response(struct spdk_jsonrpc_request *request)
302 {
303 request->send_len = 0;
304 spdk_json_write_end(request->response);
305 request->response = NULL;
306 jsonrpc_server_send_response(request);
307 }
308
309 static void
end_response(struct spdk_jsonrpc_request * request)310 end_response(struct spdk_jsonrpc_request *request)
311 {
312 spdk_json_write_object_end(request->response);
313 spdk_json_write_end(request->response);
314 request->response = NULL;
315
316 jsonrpc_server_write_cb(request, "\n", 1);
317 jsonrpc_server_send_response(request);
318 }
319
320 void
jsonrpc_free_request(struct spdk_jsonrpc_request * request)321 jsonrpc_free_request(struct spdk_jsonrpc_request *request)
322 {
323 struct spdk_jsonrpc_request *req;
324 struct spdk_jsonrpc_server_conn *conn;
325
326 if (!request) {
327 return;
328 }
329
330 /* We must send or skip response explicitly */
331 assert(request->response == NULL);
332
333 conn = request->conn;
334 if (conn != NULL) {
335 pthread_spin_lock(&conn->queue_lock);
336 conn->outstanding_requests--;
337 STAILQ_FOREACH(req, &conn->outstanding_queue, link) {
338 if (req == request) {
339 STAILQ_REMOVE(&conn->outstanding_queue,
340 req, spdk_jsonrpc_request, link);
341 break;
342 }
343 }
344 pthread_spin_unlock(&conn->queue_lock);
345 }
346 free(request->recv_buffer);
347 free(request->values);
348 free(request->send_buf);
349 free(request);
350 }
351
352 void
jsonrpc_complete_request(struct spdk_jsonrpc_request * request)353 jsonrpc_complete_request(struct spdk_jsonrpc_request *request)
354 {
355 jsonrpc_log(request->send_buf, "response: ");
356
357 jsonrpc_free_request(request);
358 }
359
360 struct spdk_json_write_ctx *
spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request * request)361 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
362 {
363 struct spdk_json_write_ctx *w = begin_response(request);
364
365 spdk_json_write_name(w, "result");
366 return w;
367 }
368
369 void
spdk_jsonrpc_end_result(struct spdk_jsonrpc_request * request,struct spdk_json_write_ctx * w)370 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
371 {
372 assert(w != NULL);
373 assert(w == request->response);
374
375 /* If there was no ID in request we skip response. */
376 if (request->id && request->id->type != SPDK_JSON_VAL_NULL) {
377 end_response(request);
378 } else {
379 skip_response(request);
380 }
381 }
382
383 void
spdk_jsonrpc_send_bool_response(struct spdk_jsonrpc_request * request,bool value)384 spdk_jsonrpc_send_bool_response(struct spdk_jsonrpc_request *request, bool value)
385 {
386 struct spdk_json_write_ctx *w;
387
388 w = spdk_jsonrpc_begin_result(request);
389 assert(w != NULL);
390 spdk_json_write_bool(w, value);
391 spdk_jsonrpc_end_result(request, w);
392 }
393
394 void
spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request * request,int error_code,const char * msg)395 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
396 int error_code, const char *msg)
397 {
398 struct spdk_json_write_ctx *w = begin_response(request);
399
400 spdk_json_write_named_object_begin(w, "error");
401 spdk_json_write_named_int32(w, "code", error_code);
402 spdk_json_write_named_string(w, "message", msg);
403 spdk_json_write_object_end(w);
404
405 end_response(request);
406 }
407
408 void
spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request * request,int error_code,const char * fmt,...)409 spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
410 int error_code, const char *fmt, ...)
411 {
412 struct spdk_json_write_ctx *w = begin_response(request);
413 va_list args;
414
415 spdk_json_write_named_object_begin(w, "error");
416 spdk_json_write_named_int32(w, "code", error_code);
417 va_start(args, fmt);
418 spdk_json_write_named_string_fmt_v(w, "message", fmt, args);
419 va_end(args);
420 spdk_json_write_object_end(w);
421
422 end_response(request);
423 }
424
425 SPDK_LOG_REGISTER_COMPONENT(rpc)
426