mirror of https://github.com/omar-polo/gmid.git
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.
This commit is contained in:
parent
37df23d183
commit
509d0509a5
168
config.c
168
config.c
|
@ -37,9 +37,8 @@ config_new(void)
|
|||
TAILQ_INIT(&conf->fcgi);
|
||||
TAILQ_INIT(&conf->hosts);
|
||||
TAILQ_INIT(&conf->pkis);
|
||||
TAILQ_INIT(&conf->addrs);
|
||||
|
||||
conf->port = 1965;
|
||||
conf->ipv6 = 0;
|
||||
conf->protos = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3;
|
||||
|
||||
init_mime(&conf->mime);
|
||||
|
@ -50,9 +49,6 @@ config_new(void)
|
|||
conf->use_privsep_crypto = 1;
|
||||
#endif
|
||||
|
||||
conf->sock4 = -1;
|
||||
conf->sock6 = -1;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
@ -67,21 +63,12 @@ config_purge(struct conf *conf)
|
|||
struct envlist *e, *te;
|
||||
struct alist *a, *ta;
|
||||
struct pki *pki, *tpki;
|
||||
struct address *addr, *taddr;
|
||||
int use_privsep_crypto;
|
||||
|
||||
ps = conf->ps;
|
||||
use_privsep_crypto = conf->use_privsep_crypto;
|
||||
|
||||
if (conf->sock4 != -1) {
|
||||
event_del(&conf->evsock4);
|
||||
close(conf->sock4);
|
||||
}
|
||||
|
||||
if (conf->sock6 != -1) {
|
||||
event_del(&conf->evsock6);
|
||||
close(conf->sock6);
|
||||
}
|
||||
|
||||
free_mime(&conf->mime);
|
||||
TAILQ_FOREACH_SAFE(f, &conf->fcgi, fcgi, tf) {
|
||||
TAILQ_REMOVE(&conf->fcgi, f, fcgi);
|
||||
|
@ -96,6 +83,11 @@ config_purge(struct conf *conf)
|
|||
free(h->key);
|
||||
free(h->ocsp);
|
||||
|
||||
TAILQ_FOREACH_SAFE(addr, &h->addrs, addrs, taddr) {
|
||||
TAILQ_REMOVE(&h->addrs, addr, addrs);
|
||||
free(addr);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(l, &h->locations, locations, tl) {
|
||||
TAILQ_REMOVE(&h->locations, l, locations);
|
||||
|
||||
|
@ -139,11 +131,19 @@ config_purge(struct conf *conf)
|
|||
free(pki);
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(addr, &conf->addrs, addrs, taddr) {
|
||||
TAILQ_REMOVE(&conf->addrs, addr, addrs);
|
||||
if (addr->sock != -1) {
|
||||
close(addr->sock);
|
||||
event_del(&addr->evsock);
|
||||
}
|
||||
free(addr);
|
||||
}
|
||||
|
||||
memset(conf, 0, sizeof(*conf));
|
||||
|
||||
conf->ps = ps;
|
||||
conf->use_privsep_crypto = use_privsep_crypto;
|
||||
conf->sock4 = conf->sock6 = -1;
|
||||
conf->protos = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3;
|
||||
init_mime(&conf->mime);
|
||||
TAILQ_INIT(&conf->fcgi);
|
||||
|
@ -222,83 +222,48 @@ config_send_kp(struct privsep *ps, int cert_type, int key_type,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
make_socket(int port, int family)
|
||||
{
|
||||
int sock, v;
|
||||
struct sockaddr_in addr4;
|
||||
struct sockaddr_in6 addr6;
|
||||
struct sockaddr *addr;
|
||||
socklen_t len;
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
memset(&addr4, 0, sizeof(addr4));
|
||||
addr4.sin_family = family;
|
||||
addr4.sin_port = htons(port);
|
||||
addr4.sin_addr.s_addr = INADDR_ANY;
|
||||
addr = (struct sockaddr*)&addr4;
|
||||
len = sizeof(addr4);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
memset(&addr6, 0, sizeof(addr6));
|
||||
addr6.sin6_family = AF_INET6;
|
||||
addr6.sin6_port = htons(port);
|
||||
addr6.sin6_addr = in6addr_any;
|
||||
addr = (struct sockaddr*)&addr6;
|
||||
len = sizeof(addr6);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unreachable */
|
||||
abort();
|
||||
}
|
||||
|
||||
if ((sock = socket(family, SOCK_STREAM, 0)) == -1)
|
||||
fatal("socket");
|
||||
|
||||
v = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) == -1)
|
||||
fatal("setsockopt(SO_REUSEADDR)");
|
||||
|
||||
v = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &v, sizeof(v)) == -1)
|
||||
fatal("setsockopt(SO_REUSEPORT)");
|
||||
|
||||
mark_nonblock(sock);
|
||||
|
||||
if (bind(sock, addr, len) == -1)
|
||||
fatal("bind");
|
||||
|
||||
if (listen(sock, 16) == -1)
|
||||
fatal("listen");
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int
|
||||
config_send_socks(struct conf *conf)
|
||||
{
|
||||
struct privsep *ps = conf->ps;
|
||||
int sock;
|
||||
struct address *addr, a;
|
||||
int sock, v;
|
||||
|
||||
if ((sock = make_socket(conf->port, AF_INET)) == -1)
|
||||
return -1;
|
||||
TAILQ_FOREACH(addr, &conf->addrs, addrs) {
|
||||
sock = socket(addr->ai_family, addr->ai_socktype,
|
||||
addr->ai_protocol);
|
||||
if (sock == -1)
|
||||
fatal("socket");
|
||||
|
||||
if (config_send_file(ps, PROC_SERVER, IMSG_RECONF_SOCK4, sock,
|
||||
NULL, 0) == -1)
|
||||
return -1;
|
||||
v = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v))
|
||||
== -1)
|
||||
fatal("setsockopt(SO_REUSEADDR)");
|
||||
|
||||
if (!conf->ipv6)
|
||||
return 0;
|
||||
v = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &v, sizeof(v))
|
||||
== -1)
|
||||
fatal("setsockopt(SO_REUSEPORT)");
|
||||
|
||||
if ((sock = make_socket(conf->port, AF_INET6)) == -1)
|
||||
return -1;
|
||||
mark_nonblock(sock);
|
||||
|
||||
if (config_send_file(ps, PROC_SERVER, IMSG_RECONF_SOCK6, sock,
|
||||
NULL, 0) == -1)
|
||||
return -1;
|
||||
if (bind(sock, (struct sockaddr *)&addr->ss, addr->slen)
|
||||
== -1)
|
||||
fatal("bind");
|
||||
|
||||
if (listen(sock, 16) == -1)
|
||||
fatal("listen");
|
||||
|
||||
memcpy(&a, addr, sizeof(a));
|
||||
a.conf = NULL;
|
||||
a.sock = -1;
|
||||
memset(&a.evsock, 0, sizeof(a.evsock));
|
||||
memset(&a.addrs, 0, sizeof(a.addrs));
|
||||
|
||||
if (config_send_file(ps, PROC_SERVER, IMSG_RECONF_SOCK, sock,
|
||||
&a, sizeof(a)) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -327,10 +292,6 @@ config_send(struct conf *conf)
|
|||
&conf->protos, sizeof(conf->protos)) == -1)
|
||||
return -1;
|
||||
|
||||
if (proc_compose(ps, PROC_SERVER, IMSG_RECONF_PORT,
|
||||
&conf->port, sizeof(conf->port)) == -1)
|
||||
return -1;
|
||||
|
||||
if (proc_flush_imsg(ps, PROC_SERVER, -1) == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -549,6 +510,7 @@ config_recv(struct conf *conf, struct imsg *imsg)
|
|||
struct envlist *env;
|
||||
struct alist *alias;
|
||||
struct proxy *proxy;
|
||||
struct address *addr;
|
||||
uint8_t *d;
|
||||
size_t len, datalen;
|
||||
|
||||
|
@ -577,29 +539,17 @@ config_recv(struct conf *conf, struct imsg *imsg)
|
|||
memcpy(&conf->protos, imsg->data, datalen);
|
||||
break;
|
||||
|
||||
case IMSG_RECONF_PORT:
|
||||
IMSG_SIZE_CHECK(imsg, &conf->port);
|
||||
memcpy(&conf->port, imsg->data, datalen);
|
||||
break;
|
||||
|
||||
case IMSG_RECONF_SOCK4:
|
||||
if (conf->sock4 != -1)
|
||||
fatalx("socket ipv4 already recv'd");
|
||||
case IMSG_RECONF_SOCK:
|
||||
addr = xcalloc(1, sizeof(*addr));
|
||||
IMSG_SIZE_CHECK(imsg, addr);
|
||||
memcpy(addr, imsg->data, sizeof(*addr));
|
||||
if (imsg->fd == -1)
|
||||
fatalx("missing socket for IMSG_RECONF_SOCK4");
|
||||
conf->sock4 = imsg->fd;
|
||||
event_set(&conf->evsock4, conf->sock4, EV_READ|EV_PERSIST,
|
||||
do_accept, conf);
|
||||
break;
|
||||
|
||||
case IMSG_RECONF_SOCK6:
|
||||
if (conf->sock6 != -1)
|
||||
fatalx("socket ipv6 already recv'd");
|
||||
if (imsg->fd == -1)
|
||||
fatalx("missing socket for IMSG_RECONF_SOCK6");
|
||||
conf->sock6 = imsg->fd;
|
||||
event_set(&conf->evsock6, conf->sock6, EV_READ|EV_PERSIST,
|
||||
do_accept, conf);
|
||||
addr->conf = conf;
|
||||
addr->sock = imsg->fd;
|
||||
event_set(&addr->evsock, addr->sock, EV_READ|EV_PERSIST,
|
||||
do_accept, addr);
|
||||
TAILQ_INSERT_HEAD(&conf->addrs, addr, addrs);
|
||||
break;
|
||||
|
||||
case IMSG_RECONF_FCGI:
|
||||
|
|
2
fcgi.c
2
fcgi.c
|
@ -350,7 +350,7 @@ fcgi_req(struct client *c)
|
|||
struct tm tminfo;
|
||||
struct envlist *p;
|
||||
|
||||
e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr),
|
||||
e = getnameinfo((struct sockaddr*)&c->raddr, c->raddrlen,
|
||||
addr, sizeof(addr),
|
||||
NULL, 0,
|
||||
NI_NUMERICHOST);
|
||||
|
|
47
ge.c
47
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);
|
||||
}
|
||||
|
|
2
gmid.c
2
gmid.c
|
@ -484,9 +484,7 @@ main_print_conf(struct conf *conf)
|
|||
|
||||
if (*conf->chroot != '\0')
|
||||
printf("chroot \"%s\"\n", conf->chroot);
|
||||
printf("ipv6 %s\n", conf->ipv6 ? "on" : "off");
|
||||
/* XXX: defined mimes? */
|
||||
printf("port %d\n", conf->port);
|
||||
printf("prefork %d\n", conf->prefork);
|
||||
/* XXX: protocols? */
|
||||
if (*conf->user != '\0')
|
||||
|
|
34
gmid.h
34
gmid.h
|
@ -104,6 +104,25 @@ struct parser {
|
|||
const char *err;
|
||||
};
|
||||
|
||||
struct conf;
|
||||
TAILQ_HEAD(addrhead, address);
|
||||
struct address {
|
||||
int ai_flags;
|
||||
int ai_family;
|
||||
int ai_socktype;
|
||||
int ai_protocol;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
int16_t port;
|
||||
|
||||
/* used in the server */
|
||||
struct conf *conf;
|
||||
int sock;
|
||||
struct event evsock; /* set if sock != -1 */
|
||||
|
||||
TAILQ_ENTRY(address) addrs;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(fcgihead, fcgi);
|
||||
struct fcgi {
|
||||
int id;
|
||||
|
@ -188,6 +207,8 @@ struct vhost {
|
|||
|
||||
TAILQ_ENTRY(vhost) vhosts;
|
||||
|
||||
struct addrhead addrs;
|
||||
|
||||
/*
|
||||
* the first location rule is always '*' and holds the default
|
||||
* settings for the vhost, then follows the "real" location
|
||||
|
@ -220,8 +241,6 @@ struct pki {
|
|||
|
||||
struct conf {
|
||||
struct privsep *ps;
|
||||
int port;
|
||||
int ipv6;
|
||||
uint32_t protos;
|
||||
struct mime mime;
|
||||
char chroot[PATH_MAX];
|
||||
|
@ -230,14 +249,10 @@ struct conf {
|
|||
int reload;
|
||||
int use_privsep_crypto;
|
||||
|
||||
int sock4;
|
||||
struct event evsock4;
|
||||
int sock6;
|
||||
struct event evsock6;
|
||||
|
||||
struct fcgihead fcgi;
|
||||
struct vhosthead hosts;
|
||||
struct pkihead pkis;
|
||||
struct addrhead addrs;
|
||||
};
|
||||
|
||||
extern const char *config_path;
|
||||
|
@ -258,6 +273,7 @@ enum {
|
|||
|
||||
struct client {
|
||||
struct conf *conf;
|
||||
struct address *addr;
|
||||
uint32_t id;
|
||||
struct tls *ctx;
|
||||
char *req;
|
||||
|
@ -324,9 +340,7 @@ enum imsg_type {
|
|||
IMSG_RECONF_START, /* 7 */
|
||||
IMSG_RECONF_MIME,
|
||||
IMSG_RECONF_PROTOS,
|
||||
IMSG_RECONF_PORT,
|
||||
IMSG_RECONF_SOCK4,
|
||||
IMSG_RECONF_SOCK6,
|
||||
IMSG_RECONF_SOCK,
|
||||
IMSG_RECONF_FCGI,
|
||||
IMSG_RECONF_HOST,
|
||||
IMSG_RECONF_CERT,
|
||||
|
|
130
parse.y
130
parse.y
|
@ -37,6 +37,9 @@
|
|||
|
||||
struct conf *conf;
|
||||
|
||||
static const char *default_host = "*";
|
||||
static uint16_t default_port = 1965;
|
||||
|
||||
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
|
||||
static struct file {
|
||||
TAILQ_ENTRY(file) entry;
|
||||
|
@ -96,6 +99,7 @@ void parsehp(char *, char **, const char **, const char *);
|
|||
int fastcgi_conf(const char *, const char *);
|
||||
void add_param(char *, char *);
|
||||
int getservice(const char *);
|
||||
void listen_on(const char *, const char *);
|
||||
|
||||
static struct vhost *host;
|
||||
static struct location *loc;
|
||||
|
@ -125,7 +129,7 @@ typedef struct {
|
|||
%token FASTCGI FOR_HOST
|
||||
%token INCLUDE INDEX IPV6
|
||||
%token KEY
|
||||
%token LANG LOCATION LOG
|
||||
%token LANG LISTEN LOCATION LOG
|
||||
%token OCSP OFF ON
|
||||
%token PARAM PORT PREFORK PROTO PROTOCOLS PROXY
|
||||
%token RELAY_TO REQUIRE RETURN ROOT
|
||||
|
@ -220,8 +224,19 @@ option : CHROOT string {
|
|||
yyerror("chroot path too long");
|
||||
free($2);
|
||||
}
|
||||
| IPV6 bool { conf->ipv6 = $2; }
|
||||
| PORT NUM { conf->port = check_port_num($2); }
|
||||
| IPV6 bool {
|
||||
yywarn("option `ipv6' is deprecated,"
|
||||
" please use `listen on'");
|
||||
if ($2)
|
||||
default_host = "*";
|
||||
else
|
||||
default_host = "0.0.0.0";
|
||||
}
|
||||
| PORT NUM {
|
||||
yywarn("option `port' is deprecated,"
|
||||
" please use `listen on'");
|
||||
default_port = $2;
|
||||
}
|
||||
| PREFORK NUM { conf->prefork = check_prefork_num($2); }
|
||||
| PROTOCOLS string {
|
||||
if (tls_config_parse_protocols(&conf->protos, $2) == -1)
|
||||
|
@ -259,6 +274,20 @@ vhost : SERVER string {
|
|||
host->key_path == NULL)
|
||||
yyerror("invalid vhost definition: %s",
|
||||
host->domain);
|
||||
if (TAILQ_EMPTY(&host->addrs)) {
|
||||
char portno[32];
|
||||
int r;
|
||||
|
||||
r = snprintf(portno, sizeof(portno), "%d",
|
||||
default_port);
|
||||
if (r < 0 || (size_t)r >= sizeof(portno))
|
||||
fatal("snprintf");
|
||||
|
||||
yywarn("missing `listen on' in server %s,"
|
||||
" assuming %s port %d", $2, default_host,
|
||||
default_port);
|
||||
listen_on(default_host, portno);
|
||||
}
|
||||
}
|
||||
| error '}' { yyerror("bad server directive"); }
|
||||
;
|
||||
|
@ -295,6 +324,22 @@ servopt : ALIAS string {
|
|||
| PARAM string '=' string {
|
||||
add_param($2, $4);
|
||||
}
|
||||
| LISTEN ON STRING PORT STRING {
|
||||
listen_on($3, $5);
|
||||
free($3);
|
||||
free($5);
|
||||
}
|
||||
| LISTEN ON STRING PORT NUM {
|
||||
char portno[32];
|
||||
int r;
|
||||
|
||||
r = snprintf(portno, sizeof(portno), "%d", $5);
|
||||
if (r < 0 || (size_t)r >= sizeof(portno))
|
||||
fatal("snprintf");
|
||||
|
||||
listen_on($3, portno);
|
||||
free($3);
|
||||
}
|
||||
| locopt
|
||||
;
|
||||
|
||||
|
@ -515,6 +560,7 @@ static const struct keyword {
|
|||
{"ipv6", IPV6},
|
||||
{"key", KEY},
|
||||
{"lang", LANG},
|
||||
{"listen", LISTEN},
|
||||
{"location", LOCATION},
|
||||
{"log", LOG},
|
||||
{"ocsp", OCSP},
|
||||
|
@ -913,6 +959,9 @@ parse_conf(struct conf *c, const char *filename)
|
|||
{
|
||||
struct sym *sym, *next;
|
||||
|
||||
default_host = "*";
|
||||
default_port = 1965;
|
||||
|
||||
conf = c;
|
||||
|
||||
file = pushfile(filename, 0);
|
||||
|
@ -1153,3 +1202,78 @@ getservice(const char *n)
|
|||
|
||||
return ((unsigned short)llval);
|
||||
}
|
||||
|
||||
static void
|
||||
add_to_addr_queue(struct addrhead *a, struct addrinfo *ai)
|
||||
{
|
||||
struct address *addr;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
if (ai->ai_addrlen > sizeof(addr->ss))
|
||||
fatalx("ai_addrlen larger than a sockaddr_storage");
|
||||
|
||||
TAILQ_FOREACH(addr, a, addrs) {
|
||||
if (addr->ai_flags == ai->ai_flags &&
|
||||
addr->ai_family == ai->ai_family &&
|
||||
addr->ai_socktype == ai->ai_socktype &&
|
||||
addr->ai_protocol == ai->ai_protocol &&
|
||||
addr->slen == ai->ai_addrlen &&
|
||||
!memcmp(&addr->ss, ai->ai_addr, addr->slen))
|
||||
return;
|
||||
}
|
||||
|
||||
addr = xcalloc(1, sizeof(*addr));
|
||||
addr->ai_flags = ai->ai_flags;
|
||||
addr->ai_family = ai->ai_family;
|
||||
addr->ai_socktype = ai->ai_socktype;
|
||||
addr->ai_protocol = ai->ai_protocol;
|
||||
addr->slen = ai->ai_addrlen;
|
||||
memcpy(&addr->ss, ai->ai_addr, ai->ai_addrlen);
|
||||
|
||||
/* for commodity */
|
||||
switch (addr->ai_family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)&addr->ss;
|
||||
addr->port = ntohs(sin->sin_port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)&addr->ss;
|
||||
addr->port = ntohs(sin6->sin6_port);
|
||||
break;
|
||||
default:
|
||||
fatalx("unknown socket family %d", addr->ai_family);
|
||||
}
|
||||
|
||||
addr->sock = -1;
|
||||
|
||||
TAILQ_INSERT_HEAD(a, addr, addrs);
|
||||
}
|
||||
|
||||
void
|
||||
listen_on(const char *hostname, const char *servname)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
int error;
|
||||
|
||||
if (!strcmp(hostname, "*"))
|
||||
hostname = NULL;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
error = getaddrinfo(hostname, servname, &hints, &res0);
|
||||
if (error) {
|
||||
yyerror("listen on \"%s\" port %s: %s", hostname, servname,
|
||||
gai_strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
add_to_addr_queue(&host->addrs, res);
|
||||
add_to_addr_queue(&conf->addrs, res);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,7 @@ current_test=
|
|||
run_test() {
|
||||
ggflags=
|
||||
port=10965
|
||||
config_common="ipv6 off
|
||||
port $port
|
||||
"
|
||||
config_common=""
|
||||
hdr=
|
||||
body=
|
||||
dont_check_server_alive=no
|
||||
|
@ -64,6 +62,7 @@ server "localhost" {
|
|||
cert "$PWD/cert.pem"
|
||||
key "$PWD/key.pem"
|
||||
root "$PWD/testdata"
|
||||
listen on localhost port $port
|
||||
$2
|
||||
}
|
||||
EOF
|
||||
|
@ -78,6 +77,7 @@ set_proxy() {
|
|||
server "localhost.local" {
|
||||
cert "$PWD/cert.pem"
|
||||
key "$PWD/key.pem"
|
||||
listen on localhost port $port
|
||||
proxy {
|
||||
relay-to localhost port $port
|
||||
$1
|
||||
|
|
|
@ -239,13 +239,13 @@ test_fastcgi() {
|
|||
test_macro_expansion() {
|
||||
cat <<EOF > reg.conf
|
||||
pwd = "$PWD"
|
||||
$config_common
|
||||
|
||||
server "localhost" {
|
||||
# the quoting of \$ is for sh
|
||||
cert \$pwd "/cert.pem"
|
||||
key \$pwd "/key.pem"
|
||||
root \$pwd "/testdata"
|
||||
listen on localhost port $port
|
||||
}
|
||||
EOF
|
||||
|
||||
|
|
23
server.c
23
server.c
|
@ -489,7 +489,6 @@ strip_path(const char *path, int strip)
|
|||
static void
|
||||
fmt_sbuf(const char *fmt, struct client *c, const char *path)
|
||||
{
|
||||
struct conf *conf = c->conf;
|
||||
size_t i;
|
||||
char buf[32];
|
||||
|
||||
|
@ -519,7 +518,7 @@ fmt_sbuf(const char *fmt, struct client *c, const char *path)
|
|||
strlcat(c->sbuf, c->iri.query, sizeof(c->sbuf));
|
||||
break;
|
||||
case 'P':
|
||||
snprintf(buf, sizeof(buf), "%d", conf->port);
|
||||
snprintf(buf, sizeof(buf), "%d", c->addr->port);
|
||||
strlcat(c->sbuf, buf, sizeof(c->sbuf));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
break;
|
||||
|
@ -1313,7 +1312,7 @@ client_close(struct client *c)
|
|||
void
|
||||
do_accept(int sock, short et, void *d)
|
||||
{
|
||||
struct conf *conf = d;
|
||||
struct address *addr = d;
|
||||
struct client *c;
|
||||
struct sockaddr_storage raddr;
|
||||
struct sockaddr *sraddr;
|
||||
|
@ -1332,7 +1331,8 @@ do_accept(int sock, short et, void *d)
|
|||
mark_nonblock(fd);
|
||||
|
||||
c = xcalloc(1, sizeof(*c));
|
||||
c->conf = conf;
|
||||
c->conf = addr->conf;
|
||||
c->addr = addr;
|
||||
c->id = ++server_client_id;
|
||||
c->fd = fd;
|
||||
c->pfd = -1;
|
||||
|
@ -1486,15 +1486,18 @@ server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
|
|||
int
|
||||
server_configure_done(struct conf *conf)
|
||||
{
|
||||
struct address *addr;
|
||||
|
||||
if (load_default_mime(&conf->mime) == -1)
|
||||
fatal("can't load default mime");
|
||||
sort_mime(&conf->mime);
|
||||
setup_tls(conf);
|
||||
load_vhosts(conf);
|
||||
if (conf->sock4 != -1)
|
||||
event_add(&conf->evsock4, NULL);
|
||||
if (conf->sock6 != -1)
|
||||
event_add(&conf->evsock6, NULL);
|
||||
|
||||
TAILQ_FOREACH(addr, &conf->addrs, addrs) {
|
||||
if (addr->sock != -1)
|
||||
event_add(&addr->evsock, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1509,9 +1512,7 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
|
|||
case IMSG_RECONF_START:
|
||||
case IMSG_RECONF_MIME:
|
||||
case IMSG_RECONF_PROTOS:
|
||||
case IMSG_RECONF_PORT:
|
||||
case IMSG_RECONF_SOCK4:
|
||||
case IMSG_RECONF_SOCK6:
|
||||
case IMSG_RECONF_SOCK:
|
||||
case IMSG_RECONF_FCGI:
|
||||
case IMSG_RECONF_HOST:
|
||||
case IMSG_RECONF_CERT:
|
||||
|
|
Loading…
Reference in New Issue