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