aboutsummaryrefslogtreecommitdiff
path: root/ge.c
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2023-06-23 21:03:29 +0000
committerOmar Polo <op@omarpolo.com>2023-06-23 21:03:29 +0000
commit509d0509a50883a6f8407b63774f40dd1e41dadf (patch)
treeea2389673345057be53bccbcf653fb0435d77259 /ge.c
parent37df23d183de23b74f8a026977b8210dc22701a6 (diff)
implement `listen on'
Listening by default on all the addresses is so bad I don't know why I haven't changed this before. Anyway. Add a `listen on $hostname port $port' syntax to the config file and deprecate the old "port" and "ipv6" global setting. Still try to honour them when no "listen on" directive is used for backward compatibily, but this will go away in the next next version hopefully. At the moment the `listen on' in server context don't filter the host, i.e. one can still reach a host from a address not specified in the corresponding `liste on', this will be added later.
Diffstat (limited to 'ge.c')
-rw-r--r--ge.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/ge.c b/ge.c
index f45d9b2..4978c2c 100644
--- a/ge.c
+++ b/ge.c
@@ -159,9 +159,14 @@ static int
serve(struct conf *conf, const char *host, int port, const char *dir)
{
struct addrinfo hints, *res, *res0;
+ struct vhost *vh = TAILQ_FIRST(&conf->hosts);
+ struct address *addr, *acp;
int r, error, saved_errno, sock = -1;
const char *cause = NULL;
char service[32];
+ int any = 0;
+
+ event_init();
r = snprintf(service, sizeof(service), "%d", port);
if (r < 0 || (size_t)r >= sizeof(service))
@@ -193,24 +198,34 @@ serve(struct conf *conf, const char *host, int port, const char *dir)
if (listen(sock, 5) == -1)
fatal("listen");
- /*
- * for the time being, we're happy as soon as
- * something binds.
- */
- break;
+ any = 1;
+
+ addr = xcalloc(1, sizeof(*addr));
+ addr->ai_flags = res->ai_flags;
+ addr->ai_family = res->ai_family;
+ addr->ai_socktype = res->ai_socktype;
+ addr->ai_protocol = res->ai_protocol;
+ addr->slen = res->ai_addrlen;
+ memcpy(&addr->ss, res->ai_addr, res->ai_addrlen);
+
+ addr->conf = conf;
+ addr->sock = sock;
+ event_set(&addr->evsock, addr->sock, EV_READ|EV_PERSIST,
+ do_accept, addr);
+
+ TAILQ_INSERT_HEAD(&conf->addrs, addr, addrs);
+
+ acp = xcalloc(1, sizeof(*acp));
+ memcpy(acp, addr, sizeof(*acp));
+ acp->sock = -1;
+ memset(&acp->evsock, 0, sizeof(acp->evsock));
+ TAILQ_INSERT_HEAD(&vh->addrs, addr, addrs);
}
- if (sock == -1)
+ if (!any)
fatal("%s", cause);
freeaddrinfo(res0);
- event_init();
-
- /* cheating */
- conf->sock4 = sock;
- event_set(&conf->evsock4, conf->sock4, EV_READ|EV_PERSIST,
- do_accept, conf);
-
server_init(NULL, NULL, NULL);
if (server_configure_done(conf) == -1)
fatalx("server configuration failed");
@@ -239,7 +254,7 @@ main(int argc, char **argv)
struct location *loc;
const char *errstr, *certs_dir = NULL, *hostname = "localhost";
char path[PATH_MAX];
- int ch;
+ int ch, port = 1965;
setlocale(LC_CTYPE, "");
@@ -262,7 +277,7 @@ main(int argc, char **argv)
usage();
break;
case 'p':
- conf->port = strtonum(optarg, 0, UINT16_MAX, &errstr);
+ port = strtonum(optarg, 0, UINT16_MAX, &errstr);
if (errstr)
fatalx("port number is %s: %s", errstr,
optarg);
@@ -316,5 +331,5 @@ main(int argc, char **argv)
/* start the server */
signal(SIGPIPE, SIG_IGN);
setproctitle("%s", loc->dir);
- return serve(conf, hostname, conf->port, loc->dir);
+ return serve(conf, hostname, port, loc->dir);
}