2 A server based on unix domain socket
4 Copyright (C) Amitay Isaacs 2016
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
28 #include "lib/async_req/async_sock.h"
29 #include "lib/util/debug.h"
30 #include "lib/util/blocking.h"
31 #include "lib/util/dlinklist.h"
32 #include "lib/util/tevent_unix.h"
33 #include "lib/util/become_daemon.h"
35 #include "common/logging.h"
36 #include "common/reqid.h"
37 #include "common/comm.h"
38 #include "common/pidfile.h"
39 #include "common/sock_daemon.h"
42 struct sock_socket *prev, *next;
45 struct sock_socket_funcs *funcs;
49 struct tevent_req *req;
53 struct sock_client *prev, *next;
55 struct tevent_req *req;
56 struct sock_client_context *client_ctx;
59 struct sock_client_context {
60 struct tevent_context *ev;
61 struct sock_socket *sock;
63 struct comm_context *comm;
65 struct sock_client *client;
68 struct sock_daemon_context {
69 struct sock_daemon_funcs *funcs;
72 struct pidfile_context *pid_ctx;
73 struct sock_socket *socket_list;
77 * Process a single client
80 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
82 static void sock_client_read_done(struct tevent_req *subreq);
83 static void sock_client_dead_handler(void *private_data);
84 static int sock_client_context_destructor(
85 struct sock_client_context *client_ctx);
87 static int sock_client_context_init(TALLOC_CTX *mem_ctx,
88 struct tevent_context *ev,
89 struct sock_socket *sock,
91 struct sock_client *client,
92 struct sock_client_context **result)
94 struct sock_client_context *client_ctx;
97 client_ctx = talloc_zero(mem_ctx, struct sock_client_context);
98 if (client_ctx == NULL) {
103 client_ctx->sock = sock;
104 client_ctx->fd = client_fd;
105 client_ctx->client = client;
107 ret = comm_setup(client_ctx, ev, client_fd,
108 sock_client_read_handler, client_ctx,
109 sock_client_dead_handler, client_ctx,
112 talloc_free(client_ctx);
116 if (sock->funcs->connect != NULL) {
119 status = sock->funcs->connect(client_ctx, sock->private_data);
121 talloc_free(client_ctx);
127 talloc_set_destructor(client_ctx, sock_client_context_destructor);
129 *result = client_ctx;
133 static void sock_client_read_handler(uint8_t *buf, size_t buflen,
136 struct sock_client_context *client_ctx = talloc_get_type_abort(
137 private_data, struct sock_client_context);
138 struct sock_socket *sock = client_ctx->sock;
139 struct tevent_req *subreq;
141 subreq = sock->funcs->read_send(client_ctx, client_ctx->ev,
142 client_ctx, buf, buflen,
144 if (subreq == NULL) {
145 talloc_free(client_ctx);
148 tevent_req_set_callback(subreq, sock_client_read_done, client_ctx);
151 static void sock_client_read_done(struct tevent_req *subreq)
153 struct sock_client_context *client_ctx = tevent_req_callback_data(
154 subreq, struct sock_client_context);
155 struct sock_socket *sock = client_ctx->sock;
159 status = sock->funcs->read_recv(subreq, &ret);
161 D_ERR("client read failed with ret=%d\n", ret);
162 talloc_free(client_ctx);
166 static void sock_client_dead_handler(void *private_data)
168 struct sock_client_context *client_ctx = talloc_get_type_abort(
169 private_data, struct sock_client_context);
170 struct sock_socket *sock = client_ctx->sock;
172 if (sock->funcs->disconnect != NULL) {
173 sock->funcs->disconnect(client_ctx, sock->private_data);
176 talloc_free(client_ctx);
179 static int sock_client_context_destructor(
180 struct sock_client_context *client_ctx)
182 TALLOC_FREE(client_ctx->client);
183 TALLOC_FREE(client_ctx->comm);
184 if (client_ctx->fd != -1) {
185 close(client_ctx->fd);
193 * Process a single listening socket
196 static int socket_setup(const char *sockpath, bool remove_before_use)
198 struct sockaddr_un addr;
202 memset(&addr, 0, sizeof(addr));
203 addr.sun_family = AF_UNIX;
205 len = strlcpy(addr.sun_path, sockpath, sizeof(addr.sun_path));
206 if (len >= sizeof(addr.sun_path)) {
207 D_ERR("socket path too long: %s\n", sockpath);
211 fd = socket(AF_UNIX, SOCK_STREAM, 0);
213 D_ERR("socket create failed - %s\n", sockpath);
217 ret = set_blocking(fd, false);
219 D_ERR("socket set nonblocking failed - %s\n", sockpath);
224 if (remove_before_use) {
228 ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
230 D_ERR("socket bind failed - %s\n", sockpath);
235 ret = listen(fd, 10);
237 D_ERR("socket listen failed - %s\n", sockpath);
242 D_NOTICE("listening on %s\n", sockpath);
247 static int sock_socket_destructor(struct sock_socket *sock);
249 static int sock_socket_init(TALLOC_CTX *mem_ctx, const char *sockpath,
250 struct sock_socket_funcs *funcs,
252 struct sock_socket **result)
254 struct sock_socket *sock;
259 if (funcs->read_send == NULL || funcs->read_recv == NULL) {
263 sock = talloc_zero(mem_ctx, struct sock_socket);
268 sock->sockpath = sockpath;
270 sock->private_data = private_data;
273 talloc_set_destructor(sock, sock_socket_destructor);
279 static int sock_socket_destructor(struct sock_socket *sock)
281 TALLOC_FREE(sock->req);
283 if (sock->fd != -1) {
288 unlink(sock->sockpath);
293 struct sock_socket_start_state {
294 struct tevent_context *ev;
295 struct sock_socket *sock;
297 struct sock_client *client_list;
300 static int sock_socket_start_state_destructor(
301 struct sock_socket_start_state *state);
302 static void sock_socket_start_new_client(struct tevent_req *subreq);
303 static int sock_socket_start_client_destructor(struct sock_client *client);
305 static struct tevent_req *sock_socket_start_send(TALLOC_CTX *mem_ctx,
306 struct tevent_context *ev,
307 struct sock_socket *sock,
308 bool remove_before_use)
310 struct tevent_req *req, *subreq;
311 struct sock_socket_start_state *state;
313 req = tevent_req_create(mem_ctx, &state,
314 struct sock_socket_start_state);
322 sock->fd = socket_setup(sock->sockpath, remove_before_use);
323 if (sock->fd == -1) {
324 tevent_req_error(req, EIO);
325 return tevent_req_post(req, ev);
328 talloc_set_destructor(state, sock_socket_start_state_destructor);
330 subreq = accept_send(state, ev, sock->fd);
331 if (tevent_req_nomem(subreq, req)) {
332 return tevent_req_post(req, ev);
334 tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
341 static int sock_socket_start_state_destructor(
342 struct sock_socket_start_state *state)
344 struct sock_client *client;
346 while ((client = state->client_list) != NULL) {
353 static void sock_socket_start_new_client(struct tevent_req *subreq)
355 struct tevent_req *req = tevent_req_callback_data(
356 subreq, struct tevent_req);
357 struct sock_socket_start_state *state = tevent_req_data(
358 req, struct sock_socket_start_state);
359 struct sock_client *client;
362 client_fd = accept_recv(subreq, NULL, NULL, &ret);
364 if (client_fd == -1) {
365 D_ERR("failed to accept new connection\n");
368 subreq = accept_send(state, state->ev, state->sock->fd);
369 if (tevent_req_nomem(subreq, req)) {
372 tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
374 if (client_fd == -1) {
378 client = talloc_zero(state, struct sock_client);
379 if (tevent_req_nomem(client, req)) {
386 ret = sock_client_context_init(client, state->ev, state->sock,
387 client_fd, client, &client->client_ctx);
393 talloc_set_destructor(client, sock_socket_start_client_destructor);
394 DLIST_ADD(state->client_list, client);
397 static int sock_socket_start_client_destructor(struct sock_client *client)
399 struct sock_socket_start_state *state = tevent_req_data(
400 client->req, struct sock_socket_start_state);
402 DLIST_REMOVE(state->client_list, client);
403 TALLOC_FREE(client->client_ctx);
408 static bool sock_socket_start_recv(struct tevent_req *req, int *perr)
410 struct sock_socket_start_state *state = tevent_req_data(
411 req, struct sock_socket_start_state);
414 state->sock->req = NULL;
416 if (tevent_req_is_unix_error(req, &ret)) {
427 * Send message to a client
430 struct tevent_req *sock_socket_write_send(TALLOC_CTX *mem_ctx,
431 struct tevent_context *ev,
432 struct sock_client_context *client_ctx,
433 uint8_t *buf, size_t buflen)
435 struct tevent_req *req;
437 req = comm_write_send(mem_ctx, ev, client_ctx->comm, buf, buflen);
442 bool sock_socket_write_recv(struct tevent_req *req, int *perr)
447 status = comm_write_recv(req, &ret);
461 int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name,
462 const char *logging, const char *debug_level,
463 struct sock_daemon_funcs *funcs,
465 struct sock_daemon_context **out)
467 struct sock_daemon_context *sockd;
470 sockd = talloc_zero(mem_ctx, struct sock_daemon_context);
475 sockd->funcs = funcs;
476 sockd->private_data = private_data;
478 ret = logging_init(sockd, logging, debug_level, daemon_name);
481 "Failed to initialize logging, logging=%s, debug=%s\n",
482 logging, debug_level);
490 int sock_daemon_add_unix(struct sock_daemon_context *sockd,
491 const char *sockpath,
492 struct sock_socket_funcs *funcs,
495 struct sock_socket *sock;
498 ret = sock_socket_init(sockd, sockpath, funcs, private_data, &sock);
504 DLIST_ADD(sockd->socket_list, sock);
512 struct sock_daemon_run_state {
513 struct tevent_context *ev;
514 struct sock_daemon_context *sockd;
520 static void sock_daemon_run_started(struct tevent_req *subreq);
521 static void sock_daemon_run_signal_handler(struct tevent_context *ev,
522 struct tevent_signal *se,
523 int signum, int count, void *siginfo,
525 static void sock_daemon_run_reconfigure(struct tevent_req *req);
526 static void sock_daemon_run_shutdown(struct tevent_req *req);
527 static void sock_daemon_run_socket_fail(struct tevent_req *subreq);
528 static void sock_daemon_run_watch_pid(struct tevent_req *subreq);
529 static void sock_daemon_run_wait_done(struct tevent_req *subreq);
531 struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
532 struct tevent_context *ev,
533 struct sock_daemon_context *sockd,
535 bool do_fork, bool create_session,
538 struct tevent_req *req, *subreq;
539 struct sock_daemon_run_state *state;
540 struct tevent_signal *se;
541 struct sock_socket *sock;
542 bool remove_before_use = false;
544 req = tevent_req_create(mem_ctx, &state,
545 struct sock_daemon_run_state);
550 become_daemon(do_fork, !create_session, false);
552 if (pidfile != NULL) {
553 int ret = pidfile_context_create(sockd, pidfile,
556 tevent_req_error(req, EEXIST);
557 return tevent_req_post(req, ev);
559 remove_before_use = true;
563 state->sockd = sockd;
564 state->pid_watch = pid_watch;
567 subreq = tevent_wakeup_send(state, ev,
568 tevent_timeval_current_ofs(0, 0));
569 if (tevent_req_nomem(subreq, req)) {
570 return tevent_req_post(req, ev);
572 tevent_req_set_callback(subreq, sock_daemon_run_started, req);
574 se = tevent_add_signal(ev, state, SIGHUP, 0,
575 sock_daemon_run_signal_handler, req);
576 if (tevent_req_nomem(se, req)) {
577 return tevent_req_post(req, ev);
580 se = tevent_add_signal(ev, state, SIGUSR1, 0,
581 sock_daemon_run_signal_handler, req);
582 if (tevent_req_nomem(se, req)) {
583 return tevent_req_post(req, ev);
586 se = tevent_add_signal(ev, state, SIGINT, 0,
587 sock_daemon_run_signal_handler, req);
588 if (tevent_req_nomem(se, req)) {
589 return tevent_req_post(req, ev);
592 se = tevent_add_signal(ev, state, SIGTERM, 0,
593 sock_daemon_run_signal_handler, req);
594 if (tevent_req_nomem(se, req)) {
595 return tevent_req_post(req, ev);
598 for (sock = sockd->socket_list; sock != NULL; sock = sock->next) {
599 subreq = sock_socket_start_send(state, ev, sock,
601 if (tevent_req_nomem(subreq, req)) {
602 return tevent_req_post(req, ev);
604 tevent_req_set_callback(subreq, sock_daemon_run_socket_fail,
609 subreq = tevent_wakeup_send(state, ev,
610 tevent_timeval_current_ofs(1,0));
611 if (tevent_req_nomem(subreq, req)) {
612 return tevent_req_post(req, ev);
614 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid,
618 if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL &&
619 sockd->funcs->wait_recv != NULL) {
620 subreq = sockd->funcs->wait_send(state, ev,
621 sockd->private_data);
622 if (tevent_req_nomem(subreq, req)) {
623 return tevent_req_post(req, ev);
625 tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
632 static void sock_daemon_run_started(struct tevent_req *subreq)
634 struct tevent_req *req = tevent_req_callback_data(
635 subreq, struct tevent_req);
636 struct sock_daemon_run_state *state = tevent_req_data(
637 req, struct sock_daemon_run_state);
638 struct sock_daemon_context *sockd = state->sockd;
641 status = tevent_wakeup_recv(subreq);
644 tevent_req_error(req, EIO);
648 D_NOTICE("daemon started, pid=%u\n", getpid());
650 if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
651 sockd->funcs->startup(sockd->private_data);
655 static void sock_daemon_run_signal_handler(struct tevent_context *ev,
656 struct tevent_signal *se,
657 int signum, int count, void *siginfo,
660 struct tevent_req *req = talloc_get_type_abort(
661 private_data, struct tevent_req);
663 D_NOTICE("Received signal %d\n", signum);
665 if (signum == SIGHUP || signum == SIGUSR1) {
666 sock_daemon_run_reconfigure(req);
670 if (signum == SIGINT || signum == SIGTERM) {
671 sock_daemon_run_shutdown(req);
672 tevent_req_error(req, EINTR);
676 static void sock_daemon_run_reconfigure(struct tevent_req *req)
678 struct sock_daemon_run_state *state = tevent_req_data(
679 req, struct sock_daemon_run_state);
680 struct sock_daemon_context *sockd = state->sockd;
682 if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
683 sockd->funcs->reconfigure(sockd->private_data);
687 static void sock_daemon_run_shutdown(struct tevent_req *req)
689 struct sock_daemon_run_state *state = tevent_req_data(
690 req, struct sock_daemon_run_state);
691 struct sock_daemon_context *sockd = state->sockd;
692 struct sock_socket *sock;
694 D_NOTICE("Shutting down\n");
696 while ((sock = sockd->socket_list) != NULL) {
697 DLIST_REMOVE(sockd->socket_list, sock);
701 if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) {
702 sockd->funcs->shutdown(sockd->private_data);
705 TALLOC_FREE(sockd->pid_ctx);
708 static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
710 struct tevent_req *req = tevent_req_callback_data(
711 subreq, struct tevent_req);
715 status = sock_socket_start_recv(subreq, &ret);
717 sock_daemon_run_shutdown(req);
719 tevent_req_error(req, ret);
721 tevent_req_done(req);
725 static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
727 struct tevent_req *req = tevent_req_callback_data(
728 subreq, struct tevent_req);
729 struct sock_daemon_run_state *state = tevent_req_data(
730 req, struct sock_daemon_run_state);
734 status = tevent_wakeup_recv(subreq);
737 tevent_req_error(req, EIO);
741 ret = kill(state->pid_watch, 0);
743 if (errno == ESRCH) {
744 D_ERR("PID %d gone away, exiting\n", state->pid_watch);
745 sock_daemon_run_shutdown(req);
746 tevent_req_error(req, ESRCH);
749 D_ERR("Failed to check PID status %d, ret=%d\n",
750 state->pid_watch, errno);
754 subreq = tevent_wakeup_send(state, state->ev,
755 tevent_timeval_current_ofs(5,0));
756 if (tevent_req_nomem(subreq, req)) {
759 tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
762 static void sock_daemon_run_wait_done(struct tevent_req *subreq)
764 struct tevent_req *req = tevent_req_callback_data(
765 subreq, struct tevent_req);
766 struct sock_daemon_run_state *state = tevent_req_data(
767 req, struct sock_daemon_run_state);
768 struct sock_daemon_context *sockd = state->sockd;
772 status = sockd->funcs->wait_recv(subreq, &ret);
774 sock_daemon_run_shutdown(req);
776 tevent_req_error(req, ret);
778 tevent_req_done(req);
782 bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
786 if (tevent_req_is_unix_error(req, &ret)) {
796 int sock_daemon_run(struct tevent_context *ev,
797 struct sock_daemon_context *sockd,
799 bool do_fork, bool create_session,
802 struct tevent_req *req;
806 req = sock_daemon_run_send(ev, ev, sockd,
807 pidfile, do_fork, create_session, pid_watch);
812 tevent_req_poll(req, ev);
814 status = sock_daemon_run_recv(req, &ret);