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 #include "spdk/string.h" 34 #include "jsonrpc_internal.h" 35 #include "spdk/util.h" 36 37 #define RPC_DEFAULT_PORT "5260" 38 39 static int 40 _spdk_jsonrpc_client_send_request(struct spdk_jsonrpc_client *client) 41 { 42 ssize_t rc; 43 struct spdk_jsonrpc_client_request *request = client->request; 44 45 if (!request) { 46 return 0; 47 } 48 49 /* Reset offset in request */ 50 request->send_offset = 0; 51 52 while (request->send_len > 0) { 53 rc = send(client->sockfd, request->send_buf + request->send_offset, 54 request->send_len, 0); 55 if (rc <= 0) { 56 if (rc < 0 && errno == EINTR) { 57 rc = 0; 58 } else { 59 return rc; 60 } 61 } 62 63 request->send_offset += rc; 64 request->send_len -= rc; 65 } 66 67 client->request = NULL; 68 69 spdk_jsonrpc_client_free_request(request); 70 return 0; 71 } 72 73 static int 74 recv_buf_expand(struct spdk_jsonrpc_client *client) 75 { 76 uint8_t *new_buf; 77 78 if (client->recv_buf_size * 2 > SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 79 return -ENOSPC; 80 } 81 82 new_buf = realloc(client->recv_buf, client->recv_buf_size * 2); 83 if (new_buf == NULL) { 84 SPDK_ERRLOG("Resizing recv_buf failed (current size %zu, new size %zu)\n", 85 client->recv_buf_size, client->recv_buf_size * 2); 86 return -ENOMEM; 87 } 88 89 client->recv_buf = new_buf; 90 client->recv_buf_size *= 2; 91 92 return 0; 93 } 94 95 static int 96 _spdk_jsonrpc_client_poll(struct spdk_jsonrpc_client *client) 97 { 98 ssize_t rc = 0; 99 size_t recv_avail; 100 101 _spdk_jsonrpc_client_send_request(client); 102 103 if (client->recv_buf == NULL) { 104 /* memory malloc for recv-buf */ 105 client->recv_buf = malloc(SPDK_JSONRPC_SEND_BUF_SIZE_INIT); 106 if (!client->recv_buf) { 107 rc = errno; 108 SPDK_ERRLOG("malloc() failed (%d): %s\n", (int)rc, spdk_strerror(rc)); 109 return -rc; 110 } 111 client->recv_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT; 112 client->recv_offset = 0; 113 } 114 115 recv_avail = client->recv_buf_size - client->recv_offset; 116 while (recv_avail > 0) { 117 rc = recv(client->sockfd, client->recv_buf + client->recv_offset, recv_avail - 1, 0); 118 if (rc < 0) { 119 if (errno == EINTR) { 120 continue; 121 } else { 122 return errno; 123 } 124 } else if (rc == 0) { 125 return -EIO; 126 } 127 128 client->recv_offset += rc; 129 recv_avail -= rc; 130 131 client->recv_buf[client->recv_offset] = '\0'; 132 133 /* Check to see if we have received a full JSON value. */ 134 rc = spdk_jsonrpc_parse_response(client); 135 if (rc == 0) { 136 /* Successfully parsed response */ 137 return 0; 138 } else if (rc && rc != -EAGAIN) { 139 SPDK_ERRLOG("jsonrpc parse request failed\n"); 140 return rc; 141 } 142 143 /* Expand receive buffer if larger one is needed */ 144 if (recv_avail == 1) { 145 rc = recv_buf_expand(client); 146 if (rc != 0) { 147 return rc; 148 } 149 recv_avail = client->recv_buf_size - client->recv_offset; 150 } 151 } 152 153 return 0; 154 } 155 156 static int 157 _spdk_jsonrpc_client_connect(struct spdk_jsonrpc_client *client, int domain, int protocol, 158 struct sockaddr *server_addr, socklen_t addrlen) 159 { 160 int rc; 161 162 client->sockfd = socket(domain, SOCK_STREAM, protocol); 163 if (client->sockfd < 0) { 164 rc = errno; 165 SPDK_ERRLOG("socket() failed\n"); 166 return -rc; 167 } 168 169 rc = connect(client->sockfd, server_addr, addrlen); 170 if (rc != 0) { 171 SPDK_ERRLOG("could not connect to JSON-RPC server: %s\n", spdk_strerror(errno)); 172 goto err; 173 } 174 175 return 0; 176 err: 177 close(client->sockfd); 178 client->sockfd = -1; 179 return -rc; 180 } 181 182 struct spdk_jsonrpc_client * 183 spdk_jsonrpc_client_connect(const char *addr, int addr_family) 184 { 185 struct spdk_jsonrpc_client *client = calloc(1, sizeof(struct spdk_jsonrpc_client)); 186 /* Unix Domain Socket */ 187 struct sockaddr_un addr_un = {}; 188 char *add_in = NULL; 189 int rc; 190 191 if (client == NULL) { 192 SPDK_ERRLOG("%s\n", spdk_strerror(errno)); 193 return NULL; 194 } 195 196 if (addr_family == AF_UNIX) { 197 addr_un.sun_family = AF_UNIX; 198 rc = snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), "%s", addr); 199 if (rc < 0 || (size_t)rc >= sizeof(addr_un.sun_path)) { 200 rc = -EINVAL; 201 SPDK_ERRLOG("RPC Listen address Unix socket path too long\n"); 202 goto err; 203 } 204 205 rc = _spdk_jsonrpc_client_connect(client, AF_UNIX, 0, (struct sockaddr *)&addr_un, sizeof(addr_un)); 206 } else { 207 /* TCP/IP socket */ 208 struct addrinfo hints; 209 struct addrinfo *res; 210 char *host, *port; 211 212 add_in = strdup(addr); 213 if (!add_in) { 214 rc = -errno; 215 SPDK_ERRLOG("%s\n", spdk_strerror(errno)); 216 goto err; 217 } 218 219 rc = spdk_parse_ip_addr(add_in, &host, &port); 220 if (rc) { 221 SPDK_ERRLOG("Invalid listen address '%s'\n", addr); 222 goto err; 223 } 224 225 if (port == NULL) { 226 port = RPC_DEFAULT_PORT; 227 } 228 229 memset(&hints, 0, sizeof(hints)); 230 hints.ai_family = AF_UNSPEC; 231 hints.ai_socktype = SOCK_STREAM; 232 hints.ai_protocol = IPPROTO_TCP; 233 234 rc = getaddrinfo(host, port, &hints, &res); 235 if (rc != 0) { 236 SPDK_ERRLOG("Unable to look up RPC connnect address '%s' (%d): %s\n", addr, rc, gai_strerror(rc)); 237 rc = -EINVAL; 238 goto err; 239 } 240 241 rc = _spdk_jsonrpc_client_connect(client, res->ai_family, res->ai_protocol, res->ai_addr, 242 res->ai_addrlen); 243 freeaddrinfo(res); 244 } 245 246 err: 247 if (rc != 0) { 248 free(client); 249 client = NULL; 250 errno = -rc; 251 } 252 253 free(add_in); 254 return client; 255 } 256 257 void 258 spdk_jsonrpc_client_close(struct spdk_jsonrpc_client *client) 259 { 260 if (client->sockfd >= 0) { 261 close(client->sockfd); 262 } 263 264 free(client->recv_buf); 265 if (client->resp) { 266 spdk_jsonrpc_client_free_response(&client->resp->jsonrpc); 267 } 268 269 free(client); 270 } 271 272 struct spdk_jsonrpc_client_request * 273 spdk_jsonrpc_client_create_request(void) 274 { 275 struct spdk_jsonrpc_client_request *request; 276 277 request = calloc(1, sizeof(*request)); 278 if (request == NULL) { 279 return NULL; 280 } 281 282 /* memory malloc for send-buf */ 283 request->send_buf = malloc(SPDK_JSONRPC_SEND_BUF_SIZE_INIT); 284 if (!request->send_buf) { 285 SPDK_ERRLOG("memory malloc for send-buf failed\n"); 286 free(request); 287 return NULL; 288 } 289 request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT; 290 291 return request; 292 } 293 294 void 295 spdk_jsonrpc_client_free_request(struct spdk_jsonrpc_client_request *req) 296 { 297 free(req->send_buf); 298 free(req); 299 } 300 301 int 302 spdk_jsonrpc_client_recv_response(struct spdk_jsonrpc_client *client) 303 { 304 return _spdk_jsonrpc_client_poll(client); 305 } 306 307 int spdk_jsonrpc_client_send_request(struct spdk_jsonrpc_client *client, 308 struct spdk_jsonrpc_client_request *req) 309 { 310 if (client->request != NULL) { 311 return -ENOSPC; 312 } 313 314 client->request = req; 315 return 0; 316 } 317 318 struct spdk_jsonrpc_client_response * 319 spdk_jsonrpc_client_get_response(struct spdk_jsonrpc_client *client) 320 { 321 struct spdk_jsonrpc_client_response_internal *r; 322 323 r = client->resp; 324 if (r == NULL || r->ready == false) { 325 return NULL; 326 } 327 328 client->resp = NULL; 329 return &r->jsonrpc; 330 } 331 332 void 333 spdk_jsonrpc_client_free_response(struct spdk_jsonrpc_client_response *resp) 334 { 335 struct spdk_jsonrpc_client_response_internal *r; 336 337 if (!resp) { 338 return; 339 } 340 341 r = SPDK_CONTAINEROF(resp, struct spdk_jsonrpc_client_response_internal, jsonrpc); 342 free(r->buf); 343 free(r); 344 } 345