1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 #include "spdk/string.h" 6 #include "jsonrpc_internal.h" 7 #include "spdk/util.h" 8 9 #define RPC_DEFAULT_PORT "5260" 10 11 static int 12 jsonrpc_client_send_request(struct spdk_jsonrpc_client *client) 13 { 14 ssize_t rc; 15 struct spdk_jsonrpc_client_request *request = client->request; 16 17 if (!request) { 18 return 0; 19 } 20 21 if (request->send_len > 0) { 22 rc = send(client->sockfd, request->send_buf + request->send_offset, 23 request->send_len, 0); 24 if (rc < 0) { 25 /* For EINTR we pretend that nothing was send. */ 26 if (errno == EINTR) { 27 rc = 0; 28 } else { 29 rc = -errno; 30 SPDK_ERRLOG("poll() failed (%d): %s\n", errno, spdk_strerror(errno)); 31 } 32 33 return rc; 34 } 35 36 request->send_offset += rc; 37 request->send_len -= rc; 38 } 39 40 if (request->send_len == 0) { 41 client->request = NULL; 42 spdk_jsonrpc_client_free_request(request); 43 } 44 45 return 0; 46 } 47 48 static int 49 recv_buf_expand(struct spdk_jsonrpc_client *client) 50 { 51 uint8_t *new_buf; 52 53 if (client->recv_buf_size * 2 > SPDK_JSONRPC_SEND_BUF_SIZE_MAX) { 54 return -ENOSPC; 55 } 56 57 new_buf = realloc(client->recv_buf, client->recv_buf_size * 2); 58 if (new_buf == NULL) { 59 SPDK_ERRLOG("Resizing recv_buf failed (current size %zu, new size %zu)\n", 60 client->recv_buf_size, client->recv_buf_size * 2); 61 return -ENOMEM; 62 } 63 64 client->recv_buf = new_buf; 65 client->recv_buf_size *= 2; 66 67 return 0; 68 } 69 70 static int 71 jsonrpc_client_resp_ready_count(struct spdk_jsonrpc_client *client) 72 { 73 return client->resp != NULL && client->resp->ready ? 1 : 0; 74 } 75 76 static int 77 jsonrpc_client_recv(struct spdk_jsonrpc_client *client) 78 { 79 ssize_t rc; 80 81 if (client->recv_buf == NULL) { 82 client->recv_buf = malloc(SPDK_JSONRPC_SEND_BUF_SIZE_INIT); 83 if (!client->recv_buf) { 84 rc = errno; 85 SPDK_ERRLOG("malloc() failed (%d): %s\n", (int)rc, spdk_strerror(rc)); 86 return -rc; 87 } 88 client->recv_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT; 89 client->recv_offset = 0; 90 } else if (client->recv_offset == client->recv_buf_size - 1) { 91 rc = recv_buf_expand(client); 92 if (rc) { 93 return rc; 94 } 95 } 96 97 rc = recv(client->sockfd, client->recv_buf + client->recv_offset, 98 client->recv_buf_size - client->recv_offset - 1, 0); 99 if (rc < 0) { 100 /* For EINTR we pretend that nothing was received. */ 101 if (errno == EINTR) { 102 return 0; 103 } else { 104 rc = -errno; 105 SPDK_ERRLOG("recv() failed (%d): %s\n", errno, spdk_strerror(errno)); 106 return rc; 107 } 108 } else if (rc == 0) { 109 return -EIO; 110 } 111 112 client->recv_offset += rc; 113 client->recv_buf[client->recv_offset] = '\0'; 114 115 /* Check to see if we have received a full JSON value. */ 116 return jsonrpc_parse_response(client); 117 } 118 119 static int 120 jsonrpc_client_poll(struct spdk_jsonrpc_client *client, int timeout) 121 { 122 int rc; 123 struct pollfd pfd = { .fd = client->sockfd, .events = POLLIN | POLLOUT }; 124 125 rc = poll(&pfd, 1, timeout); 126 if (rc == -1) { 127 if (errno == EINTR) { 128 /* For EINTR we pretend that nothing was received nor send. */ 129 rc = 0; 130 } else { 131 rc = -errno; 132 SPDK_ERRLOG("poll() failed (%d): %s\n", errno, spdk_strerror(errno)); 133 } 134 } else if (rc > 0) { 135 rc = 0; 136 137 if (pfd.revents & POLLOUT) { 138 rc = jsonrpc_client_send_request(client); 139 } 140 141 if (rc == 0 && (pfd.revents & POLLIN)) { 142 rc = jsonrpc_client_recv(client); 143 /* Incomplete message in buffer isn't an error. */ 144 if (rc == -EAGAIN) { 145 rc = 0; 146 } 147 } 148 } 149 150 return rc ? rc : jsonrpc_client_resp_ready_count(client); 151 } 152 153 static int 154 jsonrpc_client_poll_connecting(struct spdk_jsonrpc_client *client, int timeout) 155 { 156 socklen_t rc_len; 157 int rc; 158 159 struct pollfd pfd = { 160 .fd = client->sockfd, 161 .events = POLLOUT 162 }; 163 164 rc = poll(&pfd, 1, timeout); 165 if (rc == 0) { 166 return -ENOTCONN; 167 } else if (rc == -1) { 168 if (errno != EINTR) { 169 SPDK_ERRLOG("poll() failed (%d): %s\n", errno, spdk_strerror(errno)); 170 goto err; 171 } 172 173 /* We are still not connected. Caller will have to call us again. */ 174 return -ENOTCONN; 175 } else if (pfd.revents & ~POLLOUT) { 176 /* We only poll for POLLOUT */ 177 goto err; 178 } else if ((pfd.revents & POLLOUT) == 0) { 179 /* Is this even possible to get here? */ 180 return -ENOTCONN; 181 } 182 183 rc_len = sizeof(int); 184 /* connection might fail so need to check SO_ERROR. */ 185 if (getsockopt(client->sockfd, SOL_SOCKET, SO_ERROR, &rc, &rc_len) == -1) { 186 goto err; 187 } 188 189 if (rc == 0) { 190 client->connected = true; 191 return 0; 192 } 193 194 err: 195 return -EIO; 196 } 197 198 static int 199 jsonrpc_client_connect(struct spdk_jsonrpc_client *client, int domain, int protocol, 200 struct sockaddr *server_addr, socklen_t addrlen) 201 { 202 int rc; 203 204 client->sockfd = socket(domain, SOCK_STREAM | SOCK_NONBLOCK, protocol); 205 if (client->sockfd < 0) { 206 rc = errno; 207 SPDK_ERRLOG("socket() failed\n"); 208 return -rc; 209 } 210 211 rc = connect(client->sockfd, server_addr, addrlen); 212 if (rc != 0) { 213 rc = errno; 214 if (rc != EINPROGRESS) { 215 SPDK_ERRLOG("could not connect to JSON-RPC server: %s\n", spdk_strerror(errno)); 216 goto err; 217 } 218 } else { 219 client->connected = true; 220 } 221 222 return -rc; 223 err: 224 close(client->sockfd); 225 client->sockfd = -1; 226 return -rc; 227 } 228 229 struct spdk_jsonrpc_client * 230 spdk_jsonrpc_client_connect(const char *addr, int addr_family) 231 { 232 struct spdk_jsonrpc_client *client = calloc(1, sizeof(struct spdk_jsonrpc_client)); 233 /* Unix Domain Socket */ 234 struct sockaddr_un addr_un = {}; 235 char *add_in = NULL; 236 int rc; 237 238 if (client == NULL) { 239 SPDK_ERRLOG("%s\n", spdk_strerror(errno)); 240 return NULL; 241 } 242 243 if (addr_family == AF_UNIX) { 244 addr_un.sun_family = AF_UNIX; 245 rc = snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), "%s", addr); 246 if (rc < 0 || (size_t)rc >= sizeof(addr_un.sun_path)) { 247 rc = -EINVAL; 248 SPDK_ERRLOG("RPC Listen address Unix socket path too long\n"); 249 goto err; 250 } 251 252 rc = jsonrpc_client_connect(client, AF_UNIX, 0, (struct sockaddr *)&addr_un, sizeof(addr_un)); 253 } else { 254 /* TCP/IP socket */ 255 struct addrinfo hints; 256 struct addrinfo *res; 257 char *host, *port; 258 259 add_in = strdup(addr); 260 if (!add_in) { 261 rc = -errno; 262 SPDK_ERRLOG("%s\n", spdk_strerror(errno)); 263 goto err; 264 } 265 266 rc = spdk_parse_ip_addr(add_in, &host, &port); 267 if (rc) { 268 SPDK_ERRLOG("Invalid listen address '%s'\n", addr); 269 goto err; 270 } 271 272 if (port == NULL) { 273 port = RPC_DEFAULT_PORT; 274 } 275 276 memset(&hints, 0, sizeof(hints)); 277 hints.ai_family = AF_UNSPEC; 278 hints.ai_socktype = SOCK_STREAM; 279 hints.ai_protocol = IPPROTO_TCP; 280 281 rc = getaddrinfo(host, port, &hints, &res); 282 if (rc != 0) { 283 SPDK_ERRLOG("Unable to look up RPC connect address '%s' (%d): %s\n", addr, rc, gai_strerror(rc)); 284 rc = -EINVAL; 285 goto err; 286 } 287 288 rc = jsonrpc_client_connect(client, res->ai_family, res->ai_protocol, res->ai_addr, 289 res->ai_addrlen); 290 freeaddrinfo(res); 291 } 292 293 err: 294 if (rc != 0 && rc != -EINPROGRESS) { 295 free(client); 296 client = NULL; 297 errno = -rc; 298 } 299 300 free(add_in); 301 return client; 302 } 303 304 void 305 spdk_jsonrpc_client_close(struct spdk_jsonrpc_client *client) 306 { 307 if (client->sockfd >= 0) { 308 close(client->sockfd); 309 } 310 311 free(client->recv_buf); 312 if (client->resp) { 313 spdk_jsonrpc_client_free_response(&client->resp->jsonrpc); 314 } 315 316 free(client); 317 } 318 319 struct spdk_jsonrpc_client_request * 320 spdk_jsonrpc_client_create_request(void) 321 { 322 struct spdk_jsonrpc_client_request *request; 323 324 request = calloc(1, sizeof(*request)); 325 if (request == NULL) { 326 return NULL; 327 } 328 329 /* memory malloc for send-buf */ 330 request->send_buf = malloc(SPDK_JSONRPC_SEND_BUF_SIZE_INIT); 331 if (!request->send_buf) { 332 SPDK_ERRLOG("memory malloc for send-buf failed\n"); 333 free(request); 334 return NULL; 335 } 336 request->send_buf_size = SPDK_JSONRPC_SEND_BUF_SIZE_INIT; 337 338 return request; 339 } 340 341 void 342 spdk_jsonrpc_client_free_request(struct spdk_jsonrpc_client_request *req) 343 { 344 free(req->send_buf); 345 free(req); 346 } 347 348 int 349 spdk_jsonrpc_client_poll(struct spdk_jsonrpc_client *client, int timeout) 350 { 351 if (client->connected) { 352 return jsonrpc_client_poll(client, timeout); 353 } else { 354 return jsonrpc_client_poll_connecting(client, timeout); 355 } 356 } 357 358 int 359 spdk_jsonrpc_client_send_request(struct spdk_jsonrpc_client *client, 360 struct spdk_jsonrpc_client_request *req) 361 { 362 if (client->request != NULL) { 363 return -ENOSPC; 364 } 365 366 client->request = req; 367 return 0; 368 } 369 370 struct spdk_jsonrpc_client_response * 371 spdk_jsonrpc_client_get_response(struct spdk_jsonrpc_client *client) 372 { 373 struct spdk_jsonrpc_client_response_internal *r; 374 375 r = client->resp; 376 if (r == NULL || r->ready == false) { 377 return NULL; 378 } 379 380 client->resp = NULL; 381 return &r->jsonrpc; 382 } 383 384 void 385 spdk_jsonrpc_client_free_response(struct spdk_jsonrpc_client_response *resp) 386 { 387 struct spdk_jsonrpc_client_response_internal *r; 388 389 if (!resp) { 390 return; 391 } 392 393 r = SPDK_CONTAINEROF(resp, struct spdk_jsonrpc_client_response_internal, jsonrpc); 394 free(r->buf); 395 free(r); 396 } 397