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 "spdk/util.h" 35 #include "jsonrpc_internal.h" 36 37 struct jsonrpc_response { 38 const struct spdk_json_val *version; 39 const struct spdk_json_val *id; 40 const struct spdk_json_val *result; 41 }; 42 43 static int 44 capture_string(const struct spdk_json_val *val, void *out) 45 { 46 const struct spdk_json_val **vptr = out; 47 48 if (spdk_json_strequal(val, "2.0") != true) { 49 return SPDK_JSON_PARSE_INVALID; 50 } 51 52 *vptr = val; 53 return 0; 54 } 55 56 static int 57 capture_id(const struct spdk_json_val *val, void *out) 58 { 59 const struct spdk_json_val **vptr = out; 60 61 if (val->type != SPDK_JSON_VAL_STRING && val->type != SPDK_JSON_VAL_NUMBER) { 62 return SPDK_JSON_PARSE_INVALID; 63 } 64 65 *vptr = val; 66 return 0; 67 } 68 69 static int 70 capture_any(const struct spdk_json_val *val, void *out) 71 { 72 const struct spdk_json_val **vptr = out; 73 74 *vptr = val; 75 return 0; 76 } 77 78 static const struct spdk_json_object_decoder jsonrpc_response_decoders[] = { 79 {"jsonrpc", offsetof(struct jsonrpc_response, version), capture_string}, 80 {"id", offsetof(struct jsonrpc_response, id), capture_id}, 81 {"result", offsetof(struct jsonrpc_response, result), capture_any}, 82 }; 83 84 static int 85 parse_single_response(struct spdk_json_val *values, 86 spdk_jsonrpc_client_response_parser parser_fn, 87 void *parser_ctx) 88 { 89 struct jsonrpc_response resp = {}; 90 91 if (spdk_json_decode_object(values, jsonrpc_response_decoders, 92 SPDK_COUNTOF(jsonrpc_response_decoders), 93 &resp)) { 94 return SPDK_JSON_PARSE_INVALID; 95 } 96 97 return parser_fn(parser_ctx, resp.result); 98 } 99 100 int 101 spdk_jsonrpc_parse_response(struct spdk_jsonrpc_client *client, void *json, size_t size) 102 { 103 ssize_t rc; 104 void *end = NULL; 105 106 /* Check to see if we have received a full JSON value. */ 107 rc = spdk_json_parse(json, size, NULL, 0, &end, 0); 108 if (rc == SPDK_JSON_PARSE_INCOMPLETE) { 109 return rc; 110 } 111 112 SPDK_DEBUGLOG(SPDK_LOG_RPC_CLIENT, "Json string is :\n%s\n", (char *)json); 113 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 114 SPDK_ERRLOG("JSON parse error\n"); 115 /* 116 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 117 * Return an error to indicate that the connection should be closed. 118 */ 119 return SPDK_JSON_PARSE_INVALID; 120 } 121 122 /* Decode a second time now that there is a full JSON value available. */ 123 rc = spdk_json_parse(json, size, client->values, SPDK_JSONRPC_MAX_VALUES, &end, 124 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 125 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 126 SPDK_ERRLOG("JSON parse error on second pass\n"); 127 return SPDK_JSON_PARSE_INVALID; 128 } 129 130 assert(end != NULL); 131 132 if (client->values[0].type != SPDK_JSON_VAL_OBJECT_BEGIN) { 133 SPDK_ERRLOG("top-level JSON value was not object\n"); 134 return SPDK_JSON_PARSE_INVALID; 135 } 136 137 rc = parse_single_response(client->values, client->parser_fn, client->parser_ctx); 138 139 return rc; 140 } 141 142 static int 143 jsonrpc_client_write_cb(void *cb_ctx, const void *data, size_t size) 144 { 145 struct spdk_jsonrpc_client_request *request = cb_ctx; 146 size_t new_size = request->send_buf_size; 147 148 while (new_size - request->send_len < size) { 149 if (new_size >= SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 150 SPDK_ERRLOG("Send buf exceeded maximum size (%zu)\n", 151 (size_t)SPDK_JSONRPC_SEND_BUF_SIZE_MAX); 152 return -ENOSPC; 153 } 154 155 new_size *= 2; 156 } 157 158 if (new_size != request->send_buf_size) { 159 uint8_t *new_buf; 160 161 new_buf = realloc(request->send_buf, new_size); 162 if (new_buf == NULL) { 163 SPDK_ERRLOG("Resizing send_buf failed (current size %zu, new size %zu)\n", 164 request->send_buf_size, new_size); 165 return -ENOMEM; 166 } 167 168 request->send_buf = new_buf; 169 request->send_buf_size = new_size; 170 } 171 172 memcpy(request->send_buf + request->send_len, data, size); 173 request->send_len += size; 174 175 return 0; 176 } 177 178 struct spdk_json_write_ctx * 179 spdk_jsonrpc_begin_request(struct spdk_jsonrpc_client_request *request, int32_t id, 180 const char *method) 181 { 182 struct spdk_json_write_ctx *w; 183 184 w = spdk_json_write_begin(jsonrpc_client_write_cb, request, 0); 185 if (w == NULL) { 186 return NULL; 187 } 188 189 spdk_json_write_object_begin(w); 190 spdk_json_write_named_string(w, "jsonrpc", "2.0"); 191 192 if (id >= 0) { 193 spdk_json_write_named_int32(w, "id", id); 194 } 195 196 if (method) { 197 spdk_json_write_named_string(w, "method", method); 198 } 199 200 return w; 201 } 202 203 void 204 spdk_jsonrpc_end_request(struct spdk_jsonrpc_client_request *request, struct spdk_json_write_ctx *w) 205 { 206 assert(w != NULL); 207 208 spdk_json_write_object_end(w); 209 spdk_json_write_end(w); 210 jsonrpc_client_write_cb(request, "\n", 1); 211 } 212 213 SPDK_LOG_REGISTER_COMPONENT("rpc_client", SPDK_LOG_RPC_CLIENT) 214