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