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