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