1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "jsonrpc_internal.h" 35 36 #include "spdk/util.h" 37 38 struct jsonrpc_request { 39 const struct spdk_json_val *version; 40 const struct spdk_json_val *method; 41 const struct spdk_json_val *params; 42 const struct spdk_json_val *id; 43 }; 44 45 static int 46 capture_val(const struct spdk_json_val *val, void *out) 47 { 48 const struct spdk_json_val **vptr = out; 49 50 *vptr = val; 51 return 0; 52 } 53 54 static const struct spdk_json_object_decoder jsonrpc_request_decoders[] = { 55 {"jsonrpc", offsetof(struct jsonrpc_request, version), capture_val, true}, 56 {"method", offsetof(struct jsonrpc_request, method), capture_val}, 57 {"params", offsetof(struct jsonrpc_request, params), capture_val, true}, 58 {"id", offsetof(struct jsonrpc_request, id), capture_val, true}, 59 }; 60 61 static void 62 parse_single_request(struct spdk_jsonrpc_request *request, struct spdk_json_val *values) 63 { 64 bool invalid = false; 65 struct jsonrpc_request req = {}; 66 67 if (spdk_json_decode_object(values, jsonrpc_request_decoders, 68 SPDK_COUNTOF(jsonrpc_request_decoders), 69 &req)) { 70 invalid = true; 71 goto done; 72 } 73 74 if (req.version && (req.version->type != SPDK_JSON_VAL_STRING || 75 !spdk_json_strequal(req.version, "2.0"))) { 76 invalid = true; 77 } 78 79 if (!req.method || req.method->type != SPDK_JSON_VAL_STRING) { 80 req.method = NULL; 81 invalid = true; 82 } 83 84 if (req.id) { 85 if (req.id->type == SPDK_JSON_VAL_STRING || 86 req.id->type == SPDK_JSON_VAL_NUMBER) { 87 /* Copy value into request */ 88 if (req.id->len <= SPDK_JSONRPC_ID_MAX_LEN) { 89 request->id.type = req.id->type; 90 request->id.len = req.id->len; 91 memcpy(request->id.start, req.id->start, req.id->len); 92 } else { 93 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON-RPC request id too long (%u)\n", 94 req.id->len); 95 invalid = true; 96 } 97 } else if (req.id->type == SPDK_JSON_VAL_NULL) { 98 request->id.type = SPDK_JSON_VAL_NULL; 99 } else { 100 invalid = true; 101 } 102 } 103 104 if (req.params) { 105 if (req.params->type != SPDK_JSON_VAL_ARRAY_BEGIN && 106 req.params->type != SPDK_JSON_VAL_OBJECT_BEGIN) { 107 req.params = NULL; 108 invalid = true; 109 } 110 } 111 112 done: 113 if (invalid) { 114 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 115 } else { 116 spdk_jsonrpc_server_handle_request(request, req.method, req.params); 117 } 118 } 119 120 int 121 spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, void *json, size_t size) 122 { 123 struct spdk_jsonrpc_request *request; 124 ssize_t rc; 125 void *end = NULL; 126 127 /* Check to see if we have received a full JSON value. */ 128 rc = spdk_json_parse(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(SPDK_LOG_RPC, "Out of memory allocating request\n"); 136 return -1; 137 } 138 139 conn->outstanding_requests++; 140 141 request->conn = conn; 142 request->id.start = request->id_data; 143 request->id.len = 0; 144 request->id.type = SPDK_JSON_VAL_INVALID; 145 request->send_offset = 0; 146 request->send_len = 0; 147 request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT; 148 request->send_buf = malloc(request->send_buf_size); 149 if (request->send_buf == NULL) { 150 SPDK_ERRLOG("Failed to allocate send_buf (%zu bytes)\n", request->send_buf_size); 151 conn->outstanding_requests--; 152 free(request); 153 return -1; 154 } 155 156 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 157 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n"); 158 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 159 160 /* 161 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 162 * Return an error to indicate that the connection should be closed. 163 */ 164 return -1; 165 } 166 167 /* Decode a second time now that there is a full JSON value available. */ 168 rc = spdk_json_parse(json, size, conn->values, SPDK_JSONRPC_MAX_VALUES, &end, 169 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 170 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 171 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error on second pass\n"); 172 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 173 return -1; 174 } 175 176 assert(end != NULL); 177 178 if (conn->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 179 parse_single_request(request, conn->values); 180 } else if (conn->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) { 181 SPDK_DEBUGLOG(SPDK_LOG_RPC, "Got batch array (not currently supported)\n"); 182 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 183 } else { 184 SPDK_DEBUGLOG(SPDK_LOG_RPC, "top-level JSON value was not array or object\n"); 185 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 186 } 187 188 return end - json; 189 } 190 191 static int 192 spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size) 193 { 194 struct spdk_jsonrpc_request *request = cb_ctx; 195 size_t new_size = request->send_buf_size; 196 197 while (new_size - request->send_len < size) { 198 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 199 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n", 200 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX); 201 return -1; 202 } 203 204 new_size *= 2; 205 } 206 207 if (new_size != request->send_buf_size) { 208 uint8_t *new_buf; 209 210 new_buf = realloc(request->send_buf, new_size); 211 if (new_buf == NULL) { 212 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n", 213 request->send_buf_size, new_size); 214 return -1; 215 } 216 217 request->send_buf = new_buf; 218 request->send_buf_size = new_size; 219 } 220 221 memcpy(request->send_buf + request->send_len, data, size); 222 request->send_len += size; 223 224 return 0; 225 } 226 227 static struct spdk_json_write_ctx * 228 begin_response(struct spdk_jsonrpc_request *request) 229 { 230 struct spdk_json_write_ctx *w; 231 232 w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0); 233 if (w == NULL) { 234 return NULL; 235 } 236 237 spdk_json_write_object_begin(w); 238 spdk_json_write_name(w, "jsonrpc"); 239 spdk_json_write_string(w, "2.0"); 240 241 spdk_json_write_name(w, "id"); 242 spdk_json_write_val(w, &request->id); 243 244 return w; 245 } 246 247 static void 248 skip_response(struct spdk_jsonrpc_request *request) 249 { 250 request->send_len = 0; 251 spdk_jsonrpc_server_send_response(request); 252 } 253 254 static void 255 end_response(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 256 { 257 spdk_json_write_object_end(w); 258 spdk_json_write_end(w); 259 spdk_jsonrpc_server_write_cb(request, "\n", 1); 260 spdk_jsonrpc_server_send_response(request); 261 } 262 263 void 264 spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request) 265 { 266 request->conn->outstanding_requests--; 267 free(request->send_buf); 268 free(request); 269 } 270 271 struct spdk_json_write_ctx * 272 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request) 273 { 274 struct spdk_json_write_ctx *w; 275 276 if (request->id.type == SPDK_JSON_VAL_INVALID) { 277 /* Notification - no response required */ 278 skip_response(request); 279 return NULL; 280 } 281 282 w = begin_response(request); 283 if (w == NULL) { 284 skip_response(request); 285 return NULL; 286 } 287 288 spdk_json_write_name(w, "result"); 289 290 return w; 291 } 292 293 void 294 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 295 { 296 assert(w != NULL); 297 298 end_response(request, w); 299 } 300 301 void 302 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request, 303 int error_code, const char *msg) 304 { 305 struct spdk_json_write_ctx *w; 306 307 if (request->id.type == SPDK_JSON_VAL_INVALID) { 308 /* For error responses, if id is missing, explicitly respond with "id": null. */ 309 request->id.type = SPDK_JSON_VAL_NULL; 310 } 311 312 w = begin_response(request); 313 if (w == NULL) { 314 skip_response(request); 315 return; 316 } 317 318 spdk_json_write_name(w, "error"); 319 spdk_json_write_object_begin(w); 320 spdk_json_write_name(w, "code"); 321 spdk_json_write_int32(w, error_code); 322 spdk_json_write_name(w, "message"); 323 spdk_json_write_string(w, msg); 324 spdk_json_write_object_end(w); 325 326 end_response(request, w); 327 } 328 329 void 330 spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request, 331 int error_code, const char *fmt, ...) 332 { 333 struct spdk_json_write_ctx *w; 334 va_list args; 335 336 if (request->id.type == SPDK_JSON_VAL_INVALID) { 337 /* For error responses, if id is missing, explicitly respond with "id": null. */ 338 request->id.type = SPDK_JSON_VAL_NULL; 339 } 340 341 w = begin_response(request); 342 if (w == NULL) { 343 skip_response(request); 344 return; 345 } 346 347 spdk_json_write_name(w, "error"); 348 spdk_json_write_object_begin(w); 349 spdk_json_write_name(w, "code"); 350 spdk_json_write_int32(w, error_code); 351 spdk_json_write_name(w, "message"); 352 va_start(args, fmt); 353 spdk_json_write_string_fmt_v(w, fmt, args); 354 va_end(args); 355 spdk_json_write_object_end(w); 356 357 end_response(request, w); 358 } 359 360 SPDK_LOG_REGISTER_COMPONENT("rpc", SPDK_LOG_RPC) 361