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_remove(struct spdk_jsonrpc_server_conn *conn) 112 { 113 struct spdk_jsonrpc_server *server = conn->server; 114 int conn_idx = conn - server->conns; 115 116 close(conn->sockfd); 117 118 spdk_ring_free(conn->send_queue); 119 120 /* Swap conn with the last entry in conns */ 121 server->conns[conn_idx] = server->conns[server->num_conns - 1]; 122 server->num_conns--; 123 } 124 125 static int 126 spdk_jsonrpc_server_accept(struct spdk_jsonrpc_server *server) 127 { 128 struct spdk_jsonrpc_server_conn *conn; 129 struct pollfd *pfd; 130 int rc, conn_idx, nonblock; 131 132 rc = accept(server->sockfd, NULL, NULL); 133 if (rc >= 0) { 134 assert(server->num_conns < SPDK_JSONRPC_MAX_CONNS); 135 conn_idx = server->num_conns; 136 conn = &server->conns[conn_idx]; 137 conn->server = server; 138 conn->sockfd = rc; 139 conn->closed = false; 140 conn->recv_len = 0; 141 conn->outstanding_requests = 0; 142 conn->send_request = NULL; 143 conn->send_queue = spdk_ring_create(SPDK_RING_TYPE_SP_SC, 128, SPDK_ENV_SOCKET_ID_ANY); 144 if (conn->send_queue == NULL) { 145 SPDK_ERRLOG("send_queue allocation failed\n"); 146 close(conn->sockfd); 147 return -1; 148 } 149 150 nonblock = 1; 151 rc = ioctl(conn->sockfd, FIONBIO, &nonblock); 152 if (rc != 0) { 153 SPDK_ERRLOG("ioctl(FIONBIO) failed\n"); 154 close(conn->sockfd); 155 return -1; 156 } 157 158 /* Add connection to pollfds */ 159 pfd = &server->pollfds[conn_idx + 1]; 160 pfd->fd = conn->sockfd; 161 pfd->events = POLLIN | POLLOUT; 162 163 server->num_conns++; 164 165 return 0; 166 } 167 168 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 169 return 0; 170 } 171 172 return -1; 173 } 174 175 void 176 spdk_jsonrpc_server_handle_request(struct spdk_jsonrpc_request *request, 177 const struct spdk_json_val *method, const struct spdk_json_val *params) 178 { 179 request->conn->server->handle_request(request, method, params); 180 } 181 182 void 183 spdk_jsonrpc_server_handle_error(struct spdk_jsonrpc_request *request, int error) 184 { 185 const char *msg; 186 187 switch (error) { 188 case SPDK_JSONRPC_ERROR_PARSE_ERROR: 189 msg = "Parse error"; 190 break; 191 192 case SPDK_JSONRPC_ERROR_INVALID_REQUEST: 193 msg = "Invalid request"; 194 break; 195 196 case SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND: 197 msg = "Method not found"; 198 break; 199 200 case SPDK_JSONRPC_ERROR_INVALID_PARAMS: 201 msg = "Invalid parameters"; 202 break; 203 204 case SPDK_JSONRPC_ERROR_INTERNAL_ERROR: 205 msg = "Internal error"; 206 break; 207 208 default: 209 msg = "Error"; 210 break; 211 } 212 213 spdk_jsonrpc_send_error_response(request, error, msg); 214 } 215 216 static int 217 spdk_jsonrpc_server_conn_recv(struct spdk_jsonrpc_server_conn *conn) 218 { 219 ssize_t rc; 220 size_t recv_avail = SPDK_JSONRPC_RECV_BUF_SIZE - conn->recv_len; 221 222 rc = recv(conn->sockfd, conn->recv_buf + conn->recv_len, recv_avail, 0); 223 if (rc == -1) { 224 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 225 return 0; 226 } 227 228 SPDK_TRACELOG(SPDK_TRACE_RPC, "recv() failed: %s\n", strerror(errno)); 229 return -1; 230 } 231 232 if (rc == 0) { 233 SPDK_TRACELOG(SPDK_TRACE_RPC, "remote closed connection\n"); 234 return -1; 235 } 236 237 conn->recv_len += rc; 238 239 rc = spdk_jsonrpc_parse_request(conn, conn->recv_buf, conn->recv_len); 240 if (rc < 0) { 241 SPDK_ERRLOG("jsonrpc parse request failed\n"); 242 return -1; 243 } 244 245 if (rc > 0) { 246 /* 247 * Successfully parsed a request - move any data past the end of the 248 * parsed request down to the beginning. 249 */ 250 assert((size_t)rc <= conn->recv_len); 251 memmove(conn->recv_buf, conn->recv_buf + rc, conn->recv_len - rc); 252 conn->recv_len -= rc; 253 } 254 255 return 0; 256 } 257 258 void 259 spdk_jsonrpc_server_send_response(struct spdk_jsonrpc_server_conn *conn, 260 struct spdk_jsonrpc_request *request) 261 { 262 /* Queue the response to be sent */ 263 spdk_ring_enqueue(conn->send_queue, (void **)&request, 1); 264 } 265 266 static int 267 spdk_jsonrpc_server_conn_send(struct spdk_jsonrpc_server_conn *conn) 268 { 269 struct spdk_jsonrpc_request *request; 270 ssize_t rc; 271 272 more: 273 if (conn->outstanding_requests == 0) { 274 return 0; 275 } 276 277 if (conn->send_request == NULL) { 278 if (spdk_ring_dequeue(conn->send_queue, (void **)&conn->send_request, 1) != 1) { 279 return 0; 280 } 281 } 282 283 request = conn->send_request; 284 if (request == NULL) { 285 /* Nothing to send right now */ 286 return 0; 287 } 288 289 rc = send(conn->sockfd, request->send_buf + request->send_offset, 290 request->send_len, 0); 291 if (rc < 0) { 292 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 293 return 0; 294 } 295 296 SPDK_TRACELOG(SPDK_TRACE_RPC, "send() failed: %s\n", strerror(errno)); 297 return -1; 298 } 299 300 if (rc == 0) { 301 SPDK_TRACELOG(SPDK_TRACE_RPC, "remote closed connection\n"); 302 return -1; 303 } 304 305 request->send_offset += rc; 306 request->send_len -= rc; 307 308 if (request->send_len == 0) { 309 /* 310 * Full response has been sent. 311 * Free it and set send_request to NULL to move on to the next queued response. 312 */ 313 conn->send_request = NULL; 314 spdk_jsonrpc_free_request(request); 315 goto more; 316 } 317 318 return 0; 319 } 320 321 int 322 spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) 323 { 324 int rc, i; 325 struct pollfd *pfd; 326 struct spdk_jsonrpc_server_conn *conn; 327 328 rc = poll(server->pollfds, server->num_conns + 1, 0); 329 330 if (rc < 0) { 331 if (errno == EINTR) { 332 return 0; 333 } 334 335 SPDK_ERRLOG("jsonrpc poll() failed\n"); 336 return -1; 337 } 338 339 if (rc == 0) { 340 /* No sockets are ready */ 341 return 0; 342 } 343 344 /* Check listen socket */ 345 if (server->num_conns < SPDK_JSONRPC_MAX_CONNS) { 346 pfd = &server->pollfds[0]; 347 if (pfd->revents) { 348 spdk_jsonrpc_server_accept(server); 349 } 350 pfd->revents = 0; 351 } 352 353 for (i = 0; i < server->num_conns; i++) { 354 pfd = &server->pollfds[i + 1]; 355 conn = &server->conns[i]; 356 357 if (conn->closed) { 358 struct spdk_jsonrpc_request *request; 359 360 /* 361 * The client closed the connection, but there may still be requests 362 * outstanding; we have no way to cancel outstanding requests, so wait until 363 * each outstanding request sends a response (which will be discarded, since 364 * the connection is closed). 365 */ 366 367 if (conn->send_request) { 368 spdk_jsonrpc_free_request(conn->send_request); 369 conn->send_request = NULL; 370 } 371 372 while (spdk_ring_dequeue(conn->send_queue, (void **)&request, 1) == 1) { 373 spdk_jsonrpc_free_request(request); 374 } 375 376 if (conn->outstanding_requests == 0) { 377 SPDK_TRACELOG(SPDK_TRACE_RPC, "all outstanding requests completed\n"); 378 spdk_jsonrpc_server_conn_remove(conn); 379 } 380 381 continue; 382 } 383 384 if (pfd->revents & POLLOUT) { 385 rc = spdk_jsonrpc_server_conn_send(conn); 386 if (rc != 0) { 387 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to send failure\n"); 388 conn->closed = true; 389 continue; 390 } 391 } 392 393 if (pfd->revents & POLLIN) { 394 rc = spdk_jsonrpc_server_conn_recv(conn); 395 if (rc != 0) { 396 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to recv failure\n"); 397 conn->closed = true; 398 continue; 399 } 400 } 401 402 pfd->revents = 0; 403 } 404 405 return 0; 406 } 407