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