xref: /spdk/lib/jsonrpc/jsonrpc_server_tcp.c (revision 0cb95227812ac0ccadad31d05cb0f8c7b7e86ab9)
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