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}, 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 free(request); 152 return -1; 153 } 154 155 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 156 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error\n"); 157 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 158 159 /* 160 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 161 * Return an error to indicate that the connection should be closed. 162 */ 163 return -1; 164 } 165 166 /* Decode a second time now that there is a full JSON value available. */ 167 rc = spdk_json_parse(json, size, conn->values, SPDK_JSONRPC_MAX_VALUES, &end, 168 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 169 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 170 SPDK_DEBUGLOG(SPDK_LOG_RPC, "JSON parse error on second pass\n"); 171 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 172 return -1; 173 } 174 175 assert(end != NULL); 176 177 if (conn->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 178 parse_single_request(request, conn->values); 179 } else if (conn->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) { 180 SPDK_DEBUGLOG(SPDK_LOG_RPC, "Got batch array (not currently supported)\n"); 181 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 182 } else { 183 SPDK_DEBUGLOG(SPDK_LOG_RPC, "top-level JSON value was not array or object\n"); 184 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 185 } 186 187 return end - json; 188 } 189 190 static int 191 spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size) 192 { 193 struct spdk_jsonrpc_request *request = cb_ctx; 194 size_t new_size = request->send_buf_size; 195 196 while (new_size - request->send_len < size) { 197 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 198 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n", 199 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX); 200 return -1; 201 } 202 203 new_size *= 2; 204 } 205 206 if (new_size != request->send_buf_size) { 207 uint8_t *new_buf; 208 209 new_buf = realloc(request->send_buf, new_size); 210 if (new_buf == NULL) { 211 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n", 212 request->send_buf_size, new_size); 213 return -1; 214 } 215 216 request->send_buf = new_buf; 217 request->send_buf_size = new_size; 218 } 219 220 memcpy(request->send_buf + request->send_len, data, size); 221 request->send_len += size; 222 223 return 0; 224 } 225 226 static struct spdk_json_write_ctx * 227 begin_response(struct spdk_jsonrpc_request *request) 228 { 229 struct spdk_json_write_ctx *w; 230 231 w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0); 232 if (w == NULL) { 233 return NULL; 234 } 235 236 spdk_json_write_object_begin(w); 237 spdk_json_write_name(w, "jsonrpc"); 238 spdk_json_write_string(w, "2.0"); 239 240 spdk_json_write_name(w, "id"); 241 spdk_json_write_val(w, &request->id); 242 243 return w; 244 } 245 246 static void 247 end_response(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 248 { 249 spdk_json_write_object_end(w); 250 spdk_json_write_end(w); 251 spdk_jsonrpc_server_write_cb(request, "\n", 1); 252 spdk_jsonrpc_server_send_response(request->conn, request); 253 } 254 255 void 256 spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request) 257 { 258 request->conn->outstanding_requests--; 259 free(request->send_buf); 260 free(request); 261 } 262 263 struct spdk_json_write_ctx * 264 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request) 265 { 266 struct spdk_json_write_ctx *w; 267 268 if (request->id.type == SPDK_JSON_VAL_INVALID) { 269 /* Notification - no response required */ 270 spdk_jsonrpc_free_request(request); 271 return NULL; 272 } 273 274 w = begin_response(request); 275 if (w == NULL) { 276 spdk_jsonrpc_free_request(request); 277 return NULL; 278 } 279 280 spdk_json_write_name(w, "result"); 281 282 return w; 283 } 284 285 void 286 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 287 { 288 assert(w != NULL); 289 290 end_response(request, w); 291 } 292 293 void 294 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request, 295 int error_code, const char *msg) 296 { 297 struct spdk_json_write_ctx *w; 298 299 if (request->id.type == SPDK_JSON_VAL_INVALID) { 300 /* For error responses, if id is missing, explicitly respond with "id": null. */ 301 request->id.type = SPDK_JSON_VAL_NULL; 302 } 303 304 w = begin_response(request); 305 if (w == NULL) { 306 free(request); 307 return; 308 } 309 310 spdk_json_write_name(w, "error"); 311 spdk_json_write_object_begin(w); 312 spdk_json_write_name(w, "code"); 313 spdk_json_write_int32(w, error_code); 314 spdk_json_write_name(w, "message"); 315 spdk_json_write_string(w, msg); 316 spdk_json_write_object_end(w); 317 318 end_response(request, w); 319 } 320 321 void 322 spdk_jsonrpc_send_error_response_fmt(struct spdk_jsonrpc_request *request, 323 int error_code, const char *fmt, ...) 324 { 325 struct spdk_json_write_ctx *w; 326 va_list args; 327 328 if (request->id.type == SPDK_JSON_VAL_INVALID) { 329 /* For error responses, if id is missing, explicitly respond with "id": null. */ 330 request->id.type = SPDK_JSON_VAL_NULL; 331 } 332 333 w = begin_response(request); 334 if (w == NULL) { 335 free(request); 336 return; 337 } 338 339 spdk_json_write_name(w, "error"); 340 spdk_json_write_object_begin(w); 341 spdk_json_write_name(w, "code"); 342 spdk_json_write_int32(w, error_code); 343 spdk_json_write_name(w, "message"); 344 va_start(args, fmt); 345 spdk_json_write_string_fmt_v(w, fmt, args); 346 va_end(args); 347 spdk_json_write_object_end(w); 348 349 end_response(request, w); 350 } 351 352 SPDK_LOG_REGISTER_COMPONENT("rpc", SPDK_LOG_RPC) 353