xref: /spdk/lib/jsonrpc/jsonrpc_server.c (revision 1078198e78653b2f39414c1566740018d76ee73d)
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