4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #include "jsonrpc_internal.h"
35 #include "spdk/string.h"
36 #include "spdk/util.h"
38 struct spdk_jsonrpc_server
*
39 spdk_jsonrpc_server_listen(int domain
, int protocol
,
40 struct sockaddr
*listen_addr
, socklen_t addrlen
,
41 spdk_jsonrpc_handle_request_fn handle_request
)
43 struct spdk_jsonrpc_server
*server
;
46 server
= calloc(1, sizeof(struct spdk_jsonrpc_server
));
51 TAILQ_INIT(&server
->free_conns
);
52 TAILQ_INIT(&server
->conns
);
54 for (i
= 0; i
< SPDK_JSONRPC_MAX_CONNS
; i
++) {
55 TAILQ_INSERT_TAIL(&server
->free_conns
, &server
->conns_array
[i
], link
);
58 server
->handle_request
= handle_request
;
60 server
->sockfd
= socket(domain
, SOCK_STREAM
, protocol
);
61 if (server
->sockfd
< 0) {
62 SPDK_ERRLOG("socket() failed\n");
68 setsockopt(server
->sockfd
, SOL_SOCKET
, SO_REUSEADDR
, &val
, sizeof(val
));
70 flag
= fcntl(server
->sockfd
, F_GETFL
);
71 if (fcntl(server
->sockfd
, F_SETFL
, flag
| O_NONBLOCK
) < 0) {
72 SPDK_ERRLOG("fcntl can't set nonblocking mode for socket, fd: %d (%s)\n",
73 server
->sockfd
, spdk_strerror(errno
));
74 close(server
->sockfd
);
79 rc
= bind(server
->sockfd
, listen_addr
, addrlen
);
81 SPDK_ERRLOG("could not bind JSON-RPC server: %s\n", spdk_strerror(errno
));
82 close(server
->sockfd
);
87 rc
= listen(server
->sockfd
, 512);
89 SPDK_ERRLOG("listen() failed, errno = %d\n", errno
);
90 close(server
->sockfd
);
98 static struct spdk_jsonrpc_request
*
99 jsonrpc_server_dequeue_request(struct spdk_jsonrpc_server_conn
*conn
)
101 struct spdk_jsonrpc_request
*request
= NULL
;
103 pthread_spin_lock(&conn
->queue_lock
);
104 request
= STAILQ_FIRST(&conn
->send_queue
);
106 STAILQ_REMOVE_HEAD(&conn
->send_queue
, link
);
108 pthread_spin_unlock(&conn
->queue_lock
);
113 jsonrpc_server_free_conn_request(struct spdk_jsonrpc_server_conn
*conn
)
115 struct spdk_jsonrpc_request
*request
;
117 jsonrpc_free_request(conn
->send_request
);
118 conn
->send_request
= NULL
;
119 while ((request
= jsonrpc_server_dequeue_request(conn
)) != NULL
) {
120 jsonrpc_free_request(request
);
125 jsonrpc_server_conn_close(struct spdk_jsonrpc_server_conn
*conn
)
129 if (conn
->sockfd
>= 0) {
130 jsonrpc_server_free_conn_request(conn
);
134 if (conn
->close_cb
) {
135 conn
->close_cb(conn
, conn
->close_cb_ctx
);
141 spdk_jsonrpc_server_shutdown(struct spdk_jsonrpc_server
*server
)
143 struct spdk_jsonrpc_server_conn
*conn
;
145 close(server
->sockfd
);
147 TAILQ_FOREACH(conn
, &server
->conns
, link
) {
148 jsonrpc_server_conn_close(conn
);
155 jsonrpc_server_conn_remove(struct spdk_jsonrpc_server_conn
*conn
)
157 struct spdk_jsonrpc_server
*server
= conn
->server
;
159 jsonrpc_server_conn_close(conn
);
161 pthread_spin_destroy(&conn
->queue_lock
);
162 assert(STAILQ_EMPTY(&conn
->send_queue
));
164 TAILQ_REMOVE(&server
->conns
, conn
, link
);
165 TAILQ_INSERT_HEAD(&server
->free_conns
, conn
, link
);
169 spdk_jsonrpc_conn_add_close_cb(struct spdk_jsonrpc_server_conn
*conn
,
170 spdk_jsonrpc_conn_closed_fn cb
, void *ctx
)
174 pthread_spin_lock(&conn
->queue_lock
);
175 if (conn
->close_cb
== NULL
) {
177 conn
->close_cb_ctx
= ctx
;
179 rc
= conn
->close_cb
== cb
&& conn
->close_cb_ctx
== ctx
? -EEXIST
: -ENOSPC
;
181 pthread_spin_unlock(&conn
->queue_lock
);
187 spdk_jsonrpc_conn_del_close_cb(struct spdk_jsonrpc_server_conn
*conn
,
188 spdk_jsonrpc_conn_closed_fn cb
, void *ctx
)
192 pthread_spin_lock(&conn
->queue_lock
);
193 if (conn
->close_cb
== NULL
|| conn
->close_cb
!= cb
|| conn
->close_cb_ctx
!= ctx
) {
196 conn
->close_cb
= NULL
;
198 pthread_spin_unlock(&conn
->queue_lock
);
204 jsonrpc_server_accept(struct spdk_jsonrpc_server
*server
)
206 struct spdk_jsonrpc_server_conn
*conn
;
209 rc
= accept(server
->sockfd
, NULL
, NULL
);
211 conn
= TAILQ_FIRST(&server
->free_conns
);
212 assert(conn
!= NULL
);
214 conn
->server
= server
;
216 conn
->closed
= false;
218 conn
->outstanding_requests
= 0;
219 STAILQ_INIT(&conn
->send_queue
);
220 conn
->send_request
= NULL
;
222 if (pthread_spin_init(&conn
->queue_lock
, PTHREAD_PROCESS_PRIVATE
)) {
223 SPDK_ERRLOG("Unable to create queue lock for socket: %d", conn
->sockfd
);
228 flag
= fcntl(conn
->sockfd
, F_GETFL
);
229 if (fcntl(conn
->sockfd
, F_SETFL
, flag
| O_NONBLOCK
) < 0) {
230 SPDK_ERRLOG("fcntl can't set nonblocking mode for socket, fd: %d (%s)\n",
231 conn
->sockfd
, spdk_strerror(errno
));
233 pthread_spin_destroy(&conn
->queue_lock
);
237 TAILQ_REMOVE(&server
->free_conns
, conn
, link
);
238 TAILQ_INSERT_TAIL(&server
->conns
, conn
, link
);
242 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EINTR
) {
250 jsonrpc_server_handle_request(struct spdk_jsonrpc_request
*request
,
251 const struct spdk_json_val
*method
, const struct spdk_json_val
*params
)
253 request
->conn
->server
->handle_request(request
, method
, params
);
257 jsonrpc_server_handle_error(struct spdk_jsonrpc_request
*request
, int error
)
262 case SPDK_JSONRPC_ERROR_PARSE_ERROR
:
266 case SPDK_JSONRPC_ERROR_INVALID_REQUEST
:
267 msg
= "Invalid request";
270 case SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND
:
271 msg
= "Method not found";
274 case SPDK_JSONRPC_ERROR_INVALID_PARAMS
:
275 msg
= "Invalid parameters";
278 case SPDK_JSONRPC_ERROR_INTERNAL_ERROR
:
279 msg
= "Internal error";
287 spdk_jsonrpc_send_error_response(request
, error
, msg
);
291 jsonrpc_server_conn_recv(struct spdk_jsonrpc_server_conn
*conn
)
294 size_t recv_avail
= SPDK_JSONRPC_RECV_BUF_SIZE
- conn
->recv_len
;
296 rc
= recv(conn
->sockfd
, conn
->recv_buf
+ conn
->recv_len
, recv_avail
, 0);
298 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EINTR
) {
301 SPDK_DEBUGLOG(SPDK_LOG_RPC
, "recv() failed: %s\n", spdk_strerror(errno
));
306 SPDK_DEBUGLOG(SPDK_LOG_RPC
, "remote closed connection\n");
311 conn
->recv_len
+= rc
;
315 rc
= jsonrpc_parse_request(conn
, conn
->recv_buf
+ offset
, conn
->recv_len
- offset
);
317 SPDK_ERRLOG("jsonrpc parse request failed\n");
326 * Successfully parsed a requests - move any data past the end of the
327 * parsed requests down to the beginning.
329 assert((size_t)offset
<= conn
->recv_len
);
330 memmove(conn
->recv_buf
, conn
->recv_buf
+ offset
, conn
->recv_len
- offset
);
331 conn
->recv_len
-= offset
;
338 jsonrpc_server_send_response(struct spdk_jsonrpc_request
*request
)
340 struct spdk_jsonrpc_server_conn
*conn
= request
->conn
;
342 /* Queue the response to be sent */
343 pthread_spin_lock(&conn
->queue_lock
);
344 STAILQ_INSERT_TAIL(&conn
->send_queue
, request
, link
);
345 pthread_spin_unlock(&conn
->queue_lock
);
350 jsonrpc_server_conn_send(struct spdk_jsonrpc_server_conn
*conn
)
352 struct spdk_jsonrpc_request
*request
;
356 if (conn
->outstanding_requests
== 0) {
360 if (conn
->send_request
== NULL
) {
361 conn
->send_request
= jsonrpc_server_dequeue_request(conn
);
364 request
= conn
->send_request
;
365 if (request
== NULL
) {
366 /* Nothing to send right now */
370 if (request
->send_len
> 0) {
371 rc
= send(conn
->sockfd
, request
->send_buf
+ request
->send_offset
,
372 request
->send_len
, 0);
374 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
|| errno
== EINTR
) {
378 SPDK_DEBUGLOG(SPDK_LOG_RPC
, "send() failed: %s\n", spdk_strerror(errno
));
382 request
->send_offset
+= rc
;
383 request
->send_len
-= rc
;
386 if (request
->send_len
== 0) {
388 * Full response has been sent.
389 * Free it and set send_request to NULL to move on to the next queued response.
391 conn
->send_request
= NULL
;
392 jsonrpc_free_request(request
);
400 spdk_jsonrpc_server_poll(struct spdk_jsonrpc_server
*server
)
403 struct spdk_jsonrpc_server_conn
*conn
, *conn_tmp
;
405 TAILQ_FOREACH_SAFE(conn
, &server
->conns
, link
, conn_tmp
) {
406 /* If we can't receive and there are no outstanding requests close the connection. */
407 if (conn
->closed
== true && conn
->outstanding_requests
== 0) {
408 jsonrpc_server_conn_close(conn
);
411 if (conn
->sockfd
== -1 && conn
->outstanding_requests
== 0) {
412 jsonrpc_server_conn_remove(conn
);
416 /* Check listen socket */
417 if (!TAILQ_EMPTY(&server
->free_conns
)) {
418 jsonrpc_server_accept(server
);
421 TAILQ_FOREACH(conn
, &server
->conns
, link
) {
422 if (conn
->sockfd
== -1) {
426 rc
= jsonrpc_server_conn_send(conn
);
428 jsonrpc_server_conn_close(conn
);
433 rc
= jsonrpc_server_conn_recv(conn
);
435 jsonrpc_server_conn_close(conn
);