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