xref: /spdk/lib/jsonrpc/jsonrpc_server.c (revision 877573897ad52be4fa8989f7617bd655b87e05c4)
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 		new_buf = realloc(request->send_buf, new_size);
102 		if (new_buf == NULL) {
103 			SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n",
104 				    request->send_buf_size, new_size);
105 			return -1;
106 		}
107 
108 		request->send_buf = new_buf;
109 		request->send_buf_size = new_size;
110 	}
111 
112 	memcpy(request->send_buf + request->send_len, data, size);
113 	request->send_len += size;
114 
115 	return 0;
116 }
117 
118 int
119 jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, const void *json, size_t size)
120 {
121 	struct spdk_jsonrpc_request *request;
122 	ssize_t rc;
123 	size_t len;
124 	void *end = NULL;
125 
126 	/* Check to see if we have received a full JSON value. It is safe to cast away const
127 	 * as we don't decode in place. */
128 	rc = spdk_json_parse((void *)json, size, NULL, 0, &end, 0);
129 	if (rc == SPDK_JSON_PARSE_INCOMPLETE) {
130 		return 0;
131 	}
132 
133 	request = calloc(1, sizeof(*request));
134 	if (request == NULL) {
135 		SPDK_DEBUGLOG(rpc, "Out of memory allocating request\n");
136 		return -1;
137 	}
138 
139 	conn->outstanding_requests++;
140 
141 	request->conn = conn;
142 
143 	len = end - json;
144 	request->recv_buffer = malloc(len + 1);
145 	if (request->recv_buffer == NULL) {
146 		SPDK_ERRLOG("Failed to allocate buffer to copy request (%zu bytes)\n", len + 1);
147 		jsonrpc_free_request(request);
148 		return -1;
149 	}
150 
151 	memcpy(request->recv_buffer, json, len);
152 	request->recv_buffer[len] = '\0';
153 
154 	if (rc > 0 && rc <= SPDK_JSONRPC_MAX_VALUES) {
155 		request->values_cnt = rc;
156 		request->values = malloc(request->values_cnt * sizeof(request->values[0]));
157 		if (request->values == NULL) {
158 			SPDK_ERRLOG("Failed to allocate buffer for JSON values (%zu bytes)\n",
159 				    request->values_cnt * sizeof(request->values[0]));
160 			jsonrpc_free_request(request);
161 			return -1;
162 		}
163 	}
164 
165 	request->send_offset = 0;
166 	request->send_len = 0;
167 	request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT;
168 	request->send_buf = malloc(request->send_buf_size);
169 	if (request->send_buf == NULL) {
170 		SPDK_ERRLOG("Failed to allocate send_buf (%zu bytes)\n", request->send_buf_size);
171 		jsonrpc_free_request(request);
172 		return -1;
173 	}
174 
175 	request->response = spdk_json_write_begin(jsonrpc_server_write_cb, request, 0);
176 	if (request->response == NULL) {
177 		SPDK_ERRLOG("Failed to allocate response JSON write context.\n");
178 		jsonrpc_free_request(request);
179 		return -1;
180 	}
181 
182 	if (rc <= 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
183 		SPDK_DEBUGLOG(rpc, "JSON parse error\n");
184 		jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
185 
186 		/*
187 		 * Can't recover from parse error (no guaranteed resync point in streaming JSON).
188 		 * Return an error to indicate that the connection should be closed.
189 		 */
190 		return -1;
191 	}
192 
193 	/* Decode a second time now that there is a full JSON value available. */
194 	rc = spdk_json_parse(request->recv_buffer, size, request->values, request->values_cnt, &end,
195 			     SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE);
196 	if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) {
197 		SPDK_DEBUGLOG(rpc, "JSON parse error on second pass\n");
198 		jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR);
199 		return -1;
200 	}
201 
202 	assert(end != NULL);
203 
204 	if (request->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) {
205 		parse_single_request(request, request->values);
206 	} else if (request->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) {
207 		SPDK_DEBUGLOG(rpc, "Got batch array (not currently supported)\n");
208 		jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
209 	} else {
210 		SPDK_DEBUGLOG(rpc, "top-level JSON value was not array or object\n");
211 		jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST);
212 	}
213 
214 	return len;
215 }
216 
217 struct spdk_jsonrpc_server_conn *
218 spdk_jsonrpc_get_conn(struct spdk_jsonrpc_request *request)
219 {
220 	return request->conn;
221 }
222 
223 /* Never return NULL */
224 static struct spdk_json_write_ctx *
225 begin_response(struct spdk_jsonrpc_request *request)
226 {
227 	struct spdk_json_write_ctx *w = request->response;
228 
229 	spdk_json_write_object_begin(w);
230 	spdk_json_write_named_string(w, "jsonrpc", "2.0");
231 
232 	spdk_json_write_name(w, "id");
233 	if (request->id) {
234 		spdk_json_write_val(w, request->id);
235 	} else {
236 		spdk_json_write_null(w);
237 	}
238 
239 	return w;
240 }
241 
242 static void
243 skip_response(struct spdk_jsonrpc_request *request)
244 {
245 	request->send_len = 0;
246 	spdk_json_write_end(request->response);
247 	request->response = NULL;
248 	jsonrpc_server_send_response(request);
249 }
250 
251 static void
252 end_response(struct spdk_jsonrpc_request *request)
253 {
254 	spdk_json_write_object_end(request->response);
255 	spdk_json_write_end(request->response);
256 	request->response = NULL;
257 
258 	jsonrpc_server_write_cb(request, "\n", 1);
259 	jsonrpc_server_send_response(request);
260 }
261 
262 void
263 jsonrpc_free_request(struct spdk_jsonrpc_request *request)
264 {
265 	if (!request) {
266 		return;
267 	}
268 
269 	/* We must send or skip response explicitly */
270 	assert(request->response == NULL);
271 
272 	request->conn->outstanding_requests--;
273 	free(request->recv_buffer);
274 	free(request->values);
275 	free(request->send_buf);
276 	free(request);
277 }
278 
279 struct spdk_json_write_ctx *
280 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request)
281 {
282 	struct spdk_json_write_ctx *w = begin_response(request);
283 
284 	spdk_json_write_name(w, "result");
285 	return w;
286 }
287 
288 void
289 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w)
290 {
291 	assert(w != NULL);
292 	assert(w == request->response);
293 
294 	/* If there was no ID in request we skip response. */
295 	if (request->id && request->id->type != SPDK_JSON_VAL_NULL) {
296 		end_response(request);
297 	} else {
298 		skip_response(request);
299 	}
300 }
301 
302 void
303 spdk_jsonrpc_send_bool_response(struct spdk_jsonrpc_request *request, bool value)
304 {
305 	struct spdk_json_write_ctx *w;
306 
307 	w = spdk_jsonrpc_begin_result(request);
308 	assert(w != NULL);
309 	spdk_json_write_bool(w, value);
310 	spdk_jsonrpc_end_result(request, w);
311 }
312 
313 void
314 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request,
315 				 int error_code, const char *msg)
316 {
317 	struct spdk_json_write_ctx *w = begin_response(request);
318 
319 	spdk_json_write_named_object_begin(w, "error");
320 	spdk_json_write_named_int32(w, "code", error_code);
321 	spdk_json_write_named_string(w, "message", msg);
322 	spdk_json_write_object_end(w);
323 
324 	end_response(request);
325 }
326 
327 void
328 spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request,
329 				     int error_code, const char *fmt, ...)
330 {
331 	struct spdk_json_write_ctx *w = begin_response(request);
332 	va_list args;
333 
334 	spdk_json_write_named_object_begin(w, "error");
335 	spdk_json_write_named_int32(w, "code", error_code);
336 	va_start(args, fmt);
337 	spdk_json_write_named_string_fmt_v(w, "message", fmt, args);
338 	va_end(args);
339 	spdk_json_write_object_end(w);
340 
341 	end_response(request);
342 }
343 
344 SPDK_LOG_REGISTER_COMPONENT(rpc)
345