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