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