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