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 "jsonrpc_internal.h" 35 36 struct spdk_jsonrpc_server * 37 spdk_jsonrpc_server_listen(int domain, int protocol, 38 struct sockaddr *listen_addr, socklen_t addrlen, 39 spdk_jsonrpc_handle_request_fn handle_request) 40 { 41 struct spdk_jsonrpc_server *server; 42 int rc, val; 43 44 server = calloc(1, sizeof(struct spdk_jsonrpc_server)); 45 if (server == NULL) { 46 return NULL; 47 } 48 49 server->handle_request = handle_request; 50 51 server->sockfd = socket(domain, SOCK_STREAM, protocol); 52 if (server->sockfd < 0) { 53 SPDK_ERRLOG("socket() failed\n"); 54 free(server); 55 return NULL; 56 } 57 58 val = 1; 59 setsockopt(server->sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 60 if (protocol == IPPROTO_TCP) { 61 setsockopt(server->sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); 62 } 63 64 val = 1; 65 rc = ioctl(server->sockfd, FIONBIO, &val); 66 if (rc != 0) { 67 SPDK_ERRLOG("ioctl(FIONBIO) failed\n"); 68 close(server->sockfd); 69 free(server); 70 return NULL; 71 } 72 73 rc = bind(server->sockfd, listen_addr, addrlen); 74 if (rc != 0) { 75 SPDK_ERRLOG("could not bind JSON-RPC server: %s\n", strerror(errno)); 76 close(server->sockfd); 77 free(server); 78 return NULL; 79 } 80 81 rc = listen(server->sockfd, 512); 82 if (rc != 0) { 83 SPDK_ERRLOG("listen() failed, errno = %d\n", errno); 84 close(server->sockfd); 85 free(server); 86 return NULL; 87 } 88 89 /* Put listen socket in pollfds[0] */ 90 server->pollfds[0].fd = server->sockfd; 91 server->pollfds[0].events = POLLIN; 92 93 return server; 94 } 95 96 void 97 spdk_jsonrpc_server_shutdown(struct spdk_jsonrpc_server *server) 98 { 99 int i; 100 101 close(server->sockfd); 102 103 for (i = 0; i < server->num_conns; i++) { 104 close(server->conns[i].sockfd); 105 } 106 107 free(server); 108 } 109 110 static void 111 spdk_jsonrpc_server_conn_close(struct spdk_jsonrpc_server_conn *conn) 112 { 113 conn->closed = true; 114 115 /* Set the pollfd fd to a negative value so it is ignored by poll() */ 116 conn->pfd->fd = -1; 117 118 if (conn->sockfd >= 0) { 119 close(conn->sockfd); 120 conn->sockfd = -1; 121 } 122 } 123 124 static void 125 spdk_jsonrpc_server_conn_remove(struct spdk_jsonrpc_server_conn *conn) 126 { 127 struct spdk_jsonrpc_server *server = conn->server; 128 int conn_idx = conn - server->conns; 129 130 spdk_jsonrpc_server_conn_close(conn); 131 132 spdk_ring_free(conn->send_queue); 133 134 /* Swap conn with the last entry in conns */ 135 server->conns[conn_idx] = server->conns[server->num_conns - 1]; 136 server->num_conns--; 137 } 138 139 static int 140 spdk_jsonrpc_server_accept(struct spdk_jsonrpc_server *server) 141 { 142 struct spdk_jsonrpc_server_conn *conn; 143 struct pollfd *pfd; 144 int rc, conn_idx, nonblock; 145 146 rc = accept(server->sockfd, NULL, NULL); 147 if (rc >= 0) { 148 assert(server->num_conns < SPDK_JSONRPC_MAX_CONNS); 149 conn_idx = server->num_conns; 150 conn = &server->conns[conn_idx]; 151 conn->server = server; 152 conn->sockfd = rc; 153 conn->closed = false; 154 conn->recv_len = 0; 155 conn->outstanding_requests = 0; 156 conn->send_request = NULL; 157 conn->send_queue = spdk_ring_create(SPDK_RING_TYPE_SP_SC, 128, SPDK_ENV_SOCKET_ID_ANY); 158 if (conn->send_queue == NULL) { 159 SPDK_ERRLOG("send_queue allocation failed\n"); 160 close(conn->sockfd); 161 return -1; 162 } 163 164 nonblock = 1; 165 rc = ioctl(conn->sockfd, FIONBIO, &nonblock); 166 if (rc != 0) { 167 SPDK_ERRLOG("ioctl(FIONBIO) failed\n"); 168 close(conn->sockfd); 169 return -1; 170 } 171 172 /* Add connection to pollfds */ 173 pfd = &server->pollfds[conn_idx + 1]; 174 pfd->fd = conn->sockfd; 175 pfd->events = POLLIN | POLLOUT; 176 pfd->revents = 0; 177 conn->pfd = pfd; 178 179 server->num_conns++; 180 181 return 0; 182 } 183 184 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 185 return 0; 186 } 187 188 return -1; 189 } 190 191 void 192 spdk_jsonrpc_server_handle_request(struct spdk_jsonrpc_request *request, 193 const struct spdk_json_val *method, const struct spdk_json_val *params) 194 { 195 request->conn->server->handle_request(request, method, params); 196 } 197 198 void 199 spdk_jsonrpc_server_handle_error(struct spdk_jsonrpc_request *request, int error) 200 { 201 const char *msg; 202 203 switch (error) { 204 case SPDK_JSONRPC_ERROR_PARSE_ERROR: 205 msg = "Parse error"; 206 break; 207 208 case SPDK_JSONRPC_ERROR_INVALID_REQUEST: 209 msg = "Invalid request"; 210 break; 211 212 case SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND: 213 msg = "Method not found"; 214 break; 215 216 case SPDK_JSONRPC_ERROR_INVALID_PARAMS: 217 msg = "Invalid parameters"; 218 break; 219 220 case SPDK_JSONRPC_ERROR_INTERNAL_ERROR: 221 msg = "Internal error"; 222 break; 223 224 default: 225 msg = "Error"; 226 break; 227 } 228 229 spdk_jsonrpc_send_error_response(request, error, msg); 230 } 231 232 static int 233 spdk_jsonrpc_server_conn_recv(struct spdk_jsonrpc_server_conn *conn) 234 { 235 ssize_t rc; 236 size_t recv_avail = SPDK_JSONRPC_RECV_BUF_SIZE - conn->recv_len; 237 238 rc = recv(conn->sockfd, conn->recv_buf + conn->recv_len, recv_avail, 0); 239 if (rc == -1) { 240 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 241 return 0; 242 } 243 244 SPDK_TRACELOG(SPDK_TRACE_RPC, "recv() failed: %s\n", strerror(errno)); 245 return -1; 246 } 247 248 if (rc == 0) { 249 SPDK_TRACELOG(SPDK_TRACE_RPC, "remote closed connection\n"); 250 return -1; 251 } 252 253 conn->recv_len += rc; 254 255 rc = spdk_jsonrpc_parse_request(conn, conn->recv_buf, conn->recv_len); 256 if (rc < 0) { 257 SPDK_ERRLOG("jsonrpc parse request failed\n"); 258 return -1; 259 } 260 261 if (rc > 0) { 262 /* 263 * Successfully parsed a request - move any data past the end of the 264 * parsed request down to the beginning. 265 */ 266 assert((size_t)rc <= conn->recv_len); 267 memmove(conn->recv_buf, conn->recv_buf + rc, conn->recv_len - rc); 268 conn->recv_len -= rc; 269 } 270 271 return 0; 272 } 273 274 void 275 spdk_jsonrpc_server_send_response(struct spdk_jsonrpc_server_conn *conn, 276 struct spdk_jsonrpc_request *request) 277 { 278 /* Queue the response to be sent */ 279 spdk_ring_enqueue(conn->send_queue, (void **)&request, 1); 280 } 281 282 static int 283 spdk_jsonrpc_server_conn_send(struct spdk_jsonrpc_server_conn *conn) 284 { 285 struct spdk_jsonrpc_request *request; 286 ssize_t rc; 287 288 more: 289 if (conn->outstanding_requests == 0) { 290 return 0; 291 } 292 293 if (conn->send_request == NULL) { 294 if (spdk_ring_dequeue(conn->send_queue, (void **)&conn->send_request, 1) != 1) { 295 return 0; 296 } 297 } 298 299 request = conn->send_request; 300 if (request == NULL) { 301 /* Nothing to send right now */ 302 return 0; 303 } 304 305 rc = send(conn->sockfd, request->send_buf + request->send_offset, 306 request->send_len, 0); 307 if (rc < 0) { 308 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 309 return 0; 310 } 311 312 SPDK_TRACELOG(SPDK_TRACE_RPC, "send() failed: %s\n", strerror(errno)); 313 return -1; 314 } 315 316 request->send_offset += rc; 317 request->send_len -= rc; 318 319 if (request->send_len == 0) { 320 /* 321 * Full response has been sent. 322 * Free it and set send_request to NULL to move on to the next queued response. 323 */ 324 conn->send_request = NULL; 325 spdk_jsonrpc_free_request(request); 326 goto more; 327 } 328 329 return 0; 330 } 331 332 int 333 spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) 334 { 335 int rc, i; 336 struct pollfd *pfd; 337 struct spdk_jsonrpc_server_conn *conn; 338 339 for (i = 0; i < server->num_conns; i++) { 340 conn = &server->conns[i]; 341 342 if (conn->closed) { 343 struct spdk_jsonrpc_request *request; 344 345 /* 346 * The client closed the connection, but there may still be requests 347 * outstanding; we have no way to cancel outstanding requests, so wait until 348 * each outstanding request sends a response (which will be discarded, since 349 * the connection is closed). 350 */ 351 352 if (conn->send_request) { 353 spdk_jsonrpc_free_request(conn->send_request); 354 conn->send_request = NULL; 355 } 356 357 while (spdk_ring_dequeue(conn->send_queue, (void **)&request, 1) == 1) { 358 spdk_jsonrpc_free_request(request); 359 } 360 361 if (conn->outstanding_requests == 0) { 362 SPDK_TRACELOG(SPDK_TRACE_RPC, "all outstanding requests completed\n"); 363 spdk_jsonrpc_server_conn_remove(conn); 364 } 365 366 continue; 367 } 368 } 369 370 rc = poll(server->pollfds, server->num_conns + 1, 0); 371 372 if (rc < 0) { 373 if (errno == EINTR) { 374 return 0; 375 } 376 377 SPDK_ERRLOG("jsonrpc poll() failed\n"); 378 return -1; 379 } 380 381 if (rc == 0) { 382 /* No sockets are ready */ 383 return 0; 384 } 385 386 /* Check listen socket */ 387 if (server->num_conns < SPDK_JSONRPC_MAX_CONNS) { 388 pfd = &server->pollfds[0]; 389 if (pfd->revents) { 390 spdk_jsonrpc_server_accept(server); 391 } 392 pfd->revents = 0; 393 } 394 395 for (i = 0; i < server->num_conns; i++) { 396 pfd = &server->pollfds[i + 1]; 397 conn = &server->conns[i]; 398 399 if (pfd->revents & POLLOUT) { 400 rc = spdk_jsonrpc_server_conn_send(conn); 401 if (rc != 0) { 402 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to send failure\n"); 403 spdk_jsonrpc_server_conn_close(conn); 404 continue; 405 } 406 } 407 408 if (pfd->revents & POLLIN) { 409 rc = spdk_jsonrpc_server_conn_recv(conn); 410 if (rc != 0) { 411 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to recv failure\n"); 412 spdk_jsonrpc_server_conn_close(conn); 413 continue; 414 } 415 } 416 417 if (pfd->revents & (POLLERR | POLLNVAL)) { 418 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to poll() flag %d\n", 419 (int)pfd->revents); 420 spdk_jsonrpc_server_conn_close(conn); 421 continue; 422 } 423 424 pfd->revents = 0; 425 } 426 427 return 0; 428 } 429