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_TRACELOG(SPDK_TRACE_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_TRACELOG(SPDK_TRACE_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 148 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 149 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error\n"); 150 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 151 152 /* 153 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 154 * Return an error to indicate that the connection should be closed. 155 */ 156 return -1; 157 } 158 159 /* Decode a second time now that there is a full JSON value available. */ 160 rc = spdk_json_parse(json, size, conn->values, SPDK_JSONRPC_MAX_VALUES, &end, 161 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 162 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 163 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error on second pass\n"); 164 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 165 return -1; 166 } 167 168 assert(end != NULL); 169 170 if (conn->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 171 parse_single_request(request, conn->values); 172 } else if (conn->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) { 173 SPDK_TRACELOG(SPDK_TRACE_RPC, "Got batch array (not currently supported)\n"); 174 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 175 } else { 176 SPDK_TRACELOG(SPDK_TRACE_RPC, "top-level JSON value was not array or object\n"); 177 spdk_jsonrpc_server_handle_error(request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 178 } 179 180 return end - json; 181 } 182 183 static int 184 spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size) 185 { 186 struct spdk_jsonrpc_request *request = cb_ctx; 187 188 if (SPDK_JSONRPC_SEND_BUF_SIZE - request->send_len < size) { 189 SPDK_ERRLOG("Not enough space in send buf\n"); 190 return -1; 191 } 192 193 memcpy(request->send_buf + request->send_len, data, size); 194 request->send_len += size; 195 196 return 0; 197 } 198 199 static struct spdk_json_write_ctx * 200 begin_response(struct spdk_jsonrpc_request *request) 201 { 202 struct spdk_json_write_ctx *w; 203 204 w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, request, 0); 205 if (w == NULL) { 206 return NULL; 207 } 208 209 spdk_json_write_object_begin(w); 210 spdk_json_write_name(w, "jsonrpc"); 211 spdk_json_write_string(w, "2.0"); 212 213 spdk_json_write_name(w, "id"); 214 spdk_json_write_val(w, &request->id); 215 216 return w; 217 } 218 219 static void 220 end_response(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 221 { 222 spdk_json_write_object_end(w); 223 spdk_json_write_end(w); 224 spdk_jsonrpc_server_write_cb(request, "\n", 1); 225 spdk_jsonrpc_server_send_response(request->conn, request); 226 } 227 228 void 229 spdk_jsonrpc_free_request(struct spdk_jsonrpc_request *request) 230 { 231 request->conn->outstanding_requests--; 232 free(request); 233 } 234 235 struct spdk_json_write_ctx * 236 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request) 237 { 238 struct spdk_json_write_ctx *w; 239 240 if (request->id.type == SPDK_JSON_VAL_INVALID) { 241 /* Notification - no response required */ 242 spdk_jsonrpc_free_request(request); 243 return NULL; 244 } 245 246 w = begin_response(request); 247 if (w == NULL) { 248 spdk_jsonrpc_free_request(request); 249 return NULL; 250 } 251 252 spdk_json_write_name(w, "result"); 253 254 return w; 255 } 256 257 void 258 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 259 { 260 assert(w != NULL); 261 262 end_response(request, w); 263 } 264 265 void 266 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request, 267 int error_code, const char *msg) 268 { 269 struct spdk_json_write_ctx *w; 270 271 if (request->id.type == SPDK_JSON_VAL_INVALID) { 272 /* For error responses, if id is missing, explicitly respond with "id": null. */ 273 request->id.type = SPDK_JSON_VAL_NULL; 274 } 275 276 w = begin_response(request); 277 if (w == NULL) { 278 free(request); 279 return; 280 } 281 282 spdk_json_write_name(w, "error"); 283 spdk_json_write_object_begin(w); 284 spdk_json_write_name(w, "code"); 285 spdk_json_write_int32(w, error_code); 286 spdk_json_write_name(w, "message"); 287 spdk_json_write_string(w, msg); 288 spdk_json_write_object_end(w); 289 290 end_response(request, w); 291 } 292 293 SPDK_LOG_REGISTER_TRACE_FLAG("rpc", SPDK_TRACE_RPC) 294