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