summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2011-05-14 19:52:42 -0700
committerRuss Allbery <rra@stanford.edu>2011-05-14 19:52:42 -0700
commit69226cc3e1e3503bf7ebb291a3b14d2709a4fa91 (patch)
tree838ddca76f0e4cb761c5e9cdb4c216e1536afe4e /server
parent38fc6a48db3e05cc7f81412c7e6ebde9cd9b47de (diff)
Bind to both IPv4 and IPv6 addresses when run as a standalone server
When run as a standalone daemon, remctld now binds to both IPv4 and IPv6 addresses rather than only IPv4. Add binding to specified addresses to TODO.
Diffstat (limited to 'server')
-rw-r--r--server/remctld.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/server/remctld.c b/server/remctld.c
index b44e532..4228bb5 100644
--- a/server/remctld.c
+++ b/server/remctld.c
@@ -7,8 +7,8 @@
*
* Written by Anton Ushakov
* Extensive modifications by Russ Allbery <rra@stanford.edu>
- * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
- * Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
@@ -243,8 +243,11 @@ static void
server_daemon(struct options *options, struct config *config,
gss_cred_id_t creds)
{
- int s, stmp, status;
+ int s, status, fd, maxfd;
+ unsigned int nfds, i;
+ int *fds;
pid_t child;
+ fd_set readfds, tmpfds;
struct sigaction sa, oldsa;
struct sockaddr_storage ss;
socklen_t sslen;
@@ -275,11 +278,19 @@ server_daemon(struct options *options, struct config *config,
notice("starting");
/* Bind to the network socket. */
- stmp = network_bind_ipv4("any", options->port);
- if (stmp < 0)
- sysdie("cannot create socket");
- if (listen(stmp, 5) < 0)
- sysdie("error listening on socket");
+ nfds = 0;
+ network_bind_all(options->port, &fds, &nfds);
+ if (nfds == 0)
+ sysdie("cannot bind any sockets");
+ FD_ZERO(&readfds);
+ maxfd = -1;
+ for (i = 0; i < nfds; i++) {
+ if (listen(fds[i], 5) < 0)
+ sysdie("error listening on socket (fd %d)", fds[i]);
+ FD_SET(fds[i], &readfds);
+ if (fds[i] > maxfd)
+ maxfd = fds[i];
+ }
/*
* The main processing loop. Each time through the loop, check to see if
@@ -313,8 +324,23 @@ server_daemon(struct options *options, struct config *config,
unlink(options->pid_path);
exit(0);
}
+ tmpfds = readfds;
+ status = select(maxfd + 1, &tmpfds, NULL, NULL, NULL);
+ if (status < 0) {
+ if (errno != EINTR)
+ sysdie("error waiting for incoming connection");
+ continue;
+ }
+ fd = -1;
+ for (i = 0; i < nfds; i++)
+ if (FD_ISSET(fds[i], &tmpfds)) {
+ fd = fds[i];
+ break;
+ }
+ if (fd == -1)
+ continue;
sslen = sizeof(ss);
- s = accept(stmp, (struct sockaddr *) &ss, &sslen);
+ s = accept(fd, (struct sockaddr *) &ss, &sslen);
if (s < 0) {
if (errno != EINTR)
syswarn("error accepting connection");
@@ -327,7 +353,7 @@ server_daemon(struct options *options, struct config *config,
warn("sleeping ten seconds in the hope we recover...");
sleep(10);
} else if (child == 0) {
- close(stmp);
+ close(fd);
if (sigaction(SIGCHLD, &oldsa, NULL) < 0)
syswarn("cannot reset SIGCHLD handler");
server_handle_connection(s, config, creds);