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(struct sockaddr *listen_addr, socklen_t addrlen, 38 spdk_jsonrpc_handle_request_fn handle_request) 39 { 40 struct spdk_jsonrpc_server *server; 41 int rc, val; 42 43 server = calloc(1, sizeof(struct spdk_jsonrpc_server)); 44 if (server == NULL) { 45 return NULL; 46 } 47 48 server->handle_request = handle_request; 49 50 server->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 51 if (server->sockfd < 0) { 52 SPDK_ERRLOG("socket() failed\n"); 53 free(server); 54 return NULL; 55 } 56 57 val = 1; 58 setsockopt(server->sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 59 setsockopt(server->sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); 60 61 val = 1; 62 rc = ioctl(server->sockfd, FIONBIO, &val); 63 if (rc != 0) { 64 SPDK_ERRLOG("ioctl(FIONBIO) failed\n"); 65 close(server->sockfd); 66 free(server); 67 return NULL; 68 } 69 70 rc = bind(server->sockfd, listen_addr, addrlen); 71 if (rc != 0) { 72 SPDK_ERRLOG("could not bind JSON-RPC server: %s\n", strerror(errno)); 73 close(server->sockfd); 74 free(server); 75 return NULL; 76 } 77 78 rc = listen(server->sockfd, 512); 79 if (rc != 0) { 80 SPDK_ERRLOG("listen() failed, errno = %d\n", errno); 81 close(server->sockfd); 82 free(server); 83 return NULL; 84 } 85 86 /* Put listen socket in pollfds[0] */ 87 server->pollfds[0].fd = server->sockfd; 88 server->pollfds[0].events = POLLIN; 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_remove(struct spdk_jsonrpc_server_conn *conn) 109 { 110 struct spdk_jsonrpc_server *server = conn->server; 111 int conn_idx = conn - server->conns; 112 113 close(conn->sockfd); 114 115 /* Swap conn with the last entry in conns */ 116 server->conns[conn_idx] = server->conns[server->num_conns - 1]; 117 server->num_conns--; 118 } 119 120 static int 121 spdk_jsonrpc_server_accept(struct spdk_jsonrpc_server *server) 122 { 123 struct spdk_jsonrpc_server_conn *conn; 124 struct pollfd *pfd; 125 int rc, conn_idx, nonblock; 126 127 rc = accept(server->sockfd, NULL, NULL); 128 if (rc >= 0) { 129 assert(server->num_conns < SPDK_JSONRPC_MAX_CONNS); 130 conn_idx = server->num_conns; 131 conn = &server->conns[conn_idx]; 132 conn->server = server; 133 conn->sockfd = rc; 134 conn->recv_len = 0; 135 conn->send_len = 0; 136 conn->json_writer = 0; 137 138 nonblock = 1; 139 rc = ioctl(conn->sockfd, FIONBIO, &nonblock); 140 if (rc != 0) { 141 SPDK_ERRLOG("ioctl(FIONBIO) failed\n"); 142 close(conn->sockfd); 143 return -1; 144 } 145 146 /* Add connection to pollfds */ 147 pfd = &server->pollfds[conn_idx + 1]; 148 pfd->fd = conn->sockfd; 149 pfd->events = POLLIN | POLLOUT; 150 151 server->num_conns++; 152 153 return 0; 154 } 155 156 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 157 return 0; 158 } 159 160 return -1; 161 } 162 163 int 164 spdk_jsonrpc_server_write_cb(void *cb_ctx, const void *data, size_t size) 165 { 166 struct spdk_jsonrpc_server_conn *conn = cb_ctx; 167 168 if (SPDK_JSONRPC_SEND_BUF_SIZE - conn->send_len < size) { 169 SPDK_ERRLOG("Not enough space in send buf\n"); 170 return -1; 171 } 172 173 memcpy(conn->send_buf + conn->send_len, data, size); 174 conn->send_len += size; 175 176 return 0; 177 } 178 179 void 180 spdk_jsonrpc_server_handle_request(struct spdk_jsonrpc_server_conn *conn, 181 const struct spdk_json_val *method, const struct spdk_json_val *params, 182 const struct spdk_json_val *id) 183 { 184 conn->server->handle_request(conn, method, params, id); 185 } 186 187 void 188 spdk_jsonrpc_server_handle_error(struct spdk_jsonrpc_server_conn *conn, int error, 189 const struct spdk_json_val *method, const struct spdk_json_val *params, 190 const struct spdk_json_val *id) 191 { 192 const char *msg; 193 194 switch (error) { 195 case SPDK_JSONRPC_ERROR_PARSE_ERROR: 196 msg = "Parse error"; 197 break; 198 199 case SPDK_JSONRPC_ERROR_INVALID_REQUEST: 200 msg = "Invalid request"; 201 break; 202 203 case SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND: 204 msg = "Method not found"; 205 break; 206 207 case SPDK_JSONRPC_ERROR_INVALID_PARAMS: 208 msg = "Invalid parameters"; 209 break; 210 211 case SPDK_JSONRPC_ERROR_INTERNAL_ERROR: 212 msg = "Internal error"; 213 break; 214 215 default: 216 msg = "Error"; 217 break; 218 } 219 220 spdk_jsonrpc_send_error_response(conn, id, error, msg); 221 } 222 223 static int 224 spdk_jsonrpc_server_conn_recv(struct spdk_jsonrpc_server_conn *conn) 225 { 226 ssize_t rc; 227 size_t recv_avail = SPDK_JSONRPC_RECV_BUF_SIZE - conn->recv_len; 228 229 rc = recv(conn->sockfd, conn->recv_buf + conn->recv_len, recv_avail, 0); 230 if (rc == -1) { 231 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 232 return 0; 233 } 234 235 SPDK_TRACELOG(SPDK_TRACE_RPC, "recv() failed: %s\n", strerror(errno)); 236 return -1; 237 } 238 239 if (rc == 0) { 240 SPDK_TRACELOG(SPDK_TRACE_RPC, "remote closed connection\n"); 241 return -1; 242 } 243 244 conn->recv_len += rc; 245 246 rc = spdk_jsonrpc_parse_request(conn, conn->recv_buf, conn->recv_len); 247 if (rc < 0) { 248 SPDK_ERRLOG("jsonrpc parse request failed\n"); 249 return -1; 250 } 251 252 if (rc > 0) { 253 /* 254 * Successfully parsed a request - move any data past the end of the 255 * parsed request down to the beginning. 256 */ 257 assert((size_t)rc <= conn->recv_len); 258 memmove(conn->recv_buf, conn->recv_buf + rc, conn->recv_len - rc); 259 conn->recv_len -= rc; 260 } 261 262 return 0; 263 } 264 265 static int 266 spdk_jsonrpc_server_conn_send(struct spdk_jsonrpc_server_conn *conn) 267 { 268 ssize_t rc; 269 270 rc = send(conn->sockfd, conn->send_buf, conn->send_len, 0); 271 if (rc < 0) { 272 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { 273 return 0; 274 } 275 276 SPDK_TRACELOG(SPDK_TRACE_RPC, "send() failed: %s\n", strerror(errno)); 277 return -1; 278 } 279 280 if (rc == 0) { 281 SPDK_TRACELOG(SPDK_TRACE_RPC, "remote closed connection\n"); 282 return -1; 283 } 284 285 conn->send_len -= rc; 286 287 return 0; 288 } 289 290 int 291 spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server *server) 292 { 293 int rc, i; 294 struct pollfd *pfd; 295 struct spdk_jsonrpc_server_conn *conn; 296 297 rc = poll(server->pollfds, server->num_conns + 1, 0); 298 299 if (rc < 0) { 300 if (errno == EINTR) { 301 return 0; 302 } 303 304 SPDK_ERRLOG("jsonrpc poll() failed\n"); 305 return -1; 306 } 307 308 if (rc == 0) { 309 /* No sockets are ready */ 310 return 0; 311 } 312 313 /* Check listen socket */ 314 if (server->num_conns < SPDK_JSONRPC_MAX_CONNS) { 315 pfd = &server->pollfds[0]; 316 if (pfd->revents) { 317 spdk_jsonrpc_server_accept(server); 318 } 319 pfd->revents = 0; 320 } 321 322 for (i = 0; i < server->num_conns; i++) { 323 pfd = &server->pollfds[i + 1]; 324 conn = &server->conns[i]; 325 if (conn->send_len) { 326 /* 327 * If there is any data to send, keep sending it until the send buffer 328 * is empty. Each response should be allowed the full send buffer, so 329 * don't accept any new requests until the previous response is sent out. 330 */ 331 if (pfd->revents & POLLOUT) { 332 rc = spdk_jsonrpc_server_conn_send(conn); 333 if (rc != 0) { 334 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to send failure\n"); 335 spdk_jsonrpc_server_conn_remove(conn); 336 } 337 } 338 } else { 339 /* 340 * No data to send - we can receive a new request. 341 */ 342 if (pfd->revents & POLLIN) { 343 rc = spdk_jsonrpc_server_conn_recv(conn); 344 if (rc != 0) { 345 SPDK_TRACELOG(SPDK_TRACE_RPC, "closing conn due to recv failure\n"); 346 spdk_jsonrpc_server_conn_remove(conn); 347 } 348 } 349 } 350 pfd->revents = 0; 351 } 352 353 return 0; 354 } 355