2 * Copyright (c) 2020-2021 Tracey Emery <tracey@traceyemery.net>
3 * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include "got_compat.h"
20 #include <sys/types.h>
21 #include <sys/queue.h>
24 #include <sys/socket.h>
27 #include <netinet/in.h>
39 #include "got_opentemp.h"
40 #include "got_reference.h"
45 config_init(struct gotwebd
*env
)
47 strlcpy(env
->httpd_chroot
, D_HTTPD_CHROOT
, sizeof(env
->httpd_chroot
));
49 env
->prefork_gotwebd
= GOTWEBD_NUMPROC
;
51 TAILQ_INIT(&env
->servers
);
52 TAILQ_INIT(&env
->sockets
);
58 config_getcfg(struct gotwebd
*env
, struct imsg
*imsg
)
60 /* nothing to do but tell gotwebd configuration is done */
61 if (sockets_compose_main(env
, IMSG_CFG_DONE
, NULL
, 0) == -1)
62 fatal("sockets_compose_main IMSG_CFG_DONE");
67 config_setserver(struct gotwebd
*env
, struct server
*srv
)
69 if (main_compose_sockets(env
, IMSG_CFG_SRV
, -1, srv
, sizeof(*srv
))
71 fatal("main_compose_sockets IMSG_CFG_SRV");
76 config_getserver(struct gotwebd
*env
, struct imsg
*imsg
)
79 uint8_t *p
= imsg
->data
;
81 srv
= calloc(1, sizeof(*srv
));
83 fatalx("%s: calloc", __func__
);
85 if (IMSG_DATA_SIZE(imsg
) != sizeof(*srv
))
86 fatalx("%s: wrong size", __func__
);
88 memcpy(srv
, p
, sizeof(*srv
));
91 log_debug("%s: server=%s fcgi_socket=%s unix_socket=%s", __func__
,
92 srv
->name
, srv
->fcgi_socket
? "yes" : "no", srv
->unix_socket
?
95 TAILQ_INSERT_TAIL(&env
->servers
, srv
, entry
);
101 config_setsock(struct gotwebd
*env
, struct socket
*sock
)
103 /* open listening sockets */
104 if (sockets_privinit(env
, sock
) == -1)
107 if (main_compose_sockets(env
, IMSG_CFG_SOCK
, sock
->fd
,
108 &sock
->conf
, sizeof(sock
->conf
)) == -1)
109 fatal("main_compose_sockets IMSG_CFG_SOCK");
116 config_getsock(struct gotwebd
*env
, struct imsg
*imsg
)
118 struct socket
*sock
= NULL
;
119 struct socket_conf sock_conf
;
120 uint8_t *p
= imsg
->data
;
123 if (IMSG_DATA_SIZE(imsg
) != sizeof(sock_conf
))
124 fatalx("%s: wrong size", __func__
);
126 memcpy(&sock_conf
, p
, sizeof(sock_conf
));
128 if (IMSG_DATA_SIZE(imsg
) != sizeof(sock_conf
)) {
129 log_debug("%s: imsg size error", __func__
);
133 /* create a new socket */
134 if ((sock
= calloc(1, sizeof(*sock
))) == NULL
) {
138 memcpy(&sock
->conf
, &sock_conf
, sizeof(sock
->conf
));
139 sock
->fd
= imsg_get_fd(imsg
);
141 TAILQ_INSERT_TAIL(&env
->sockets
, sock
, entry
);
143 for (i
= 0; i
< PRIV_FDS__MAX
; i
++)
144 sock
->priv_fd
[i
] = -1;
146 for (i
= 0; i
< GOTWEB_PACK_NUM_TEMPFILES
; i
++)
147 sock
->pack_fds
[i
] = -1;
149 /* log new socket info */
150 log_debug("%s: name=%s id=%d server=%s af_type=%s socket_path=%s",
151 __func__
, sock
->conf
.name
, sock
->conf
.id
, sock
->conf
.srv_name
,
152 sock
->conf
.af_type
== AF_UNIX
? "unix" :
153 (sock
->conf
.af_type
== AF_INET
? "inet" :
154 (sock
->conf
.af_type
== AF_INET6
? "inet6" : "unknown")),
155 *sock
->conf
.unix_socket_name
!= '\0' ?
156 sock
->conf
.unix_socket_name
: "none");
162 config_setfd(struct gotwebd
*env
, struct socket
*sock
)
166 log_debug("%s: Allocating %d file descriptors",
167 __func__
, PRIV_FDS__MAX
+ GOTWEB_PACK_NUM_TEMPFILES
);
169 for (i
= 0; i
< PRIV_FDS__MAX
+ GOTWEB_PACK_NUM_TEMPFILES
; i
++) {
170 for (j
= 0; j
< env
->nserver
; ++j
) {
171 fd
= got_opentempfd();
173 fatal("got_opentemp");
174 if (imsg_compose_event(&env
->iev_server
[j
],
175 IMSG_CFG_FD
, 0, -1, fd
, &sock
->conf
.id
,
176 sizeof(sock
->conf
.id
)) == -1)
177 fatal("imsg_compose_event IMSG_CFG_FD");
180 ret
= imsg_flush(&env
->iev_server
[j
].ibuf
);
181 } while (ret
== -1 && errno
== EAGAIN
);
184 imsg_event_add(&env
->iev_server
[j
]);
192 config_getfd(struct gotwebd
*env
, struct imsg
*imsg
)
195 uint8_t *p
= imsg
->data
;
196 int sock_id
, match
= 0, i
, j
;
198 if (IMSG_DATA_SIZE(imsg
) != sizeof(sock_id
))
199 fatalx("%s: wrong size", __func__
);
201 memcpy(&sock_id
, p
, sizeof(sock_id
));
203 TAILQ_FOREACH(sock
, &env
->sockets
, entry
) {
204 const int nfds
= (GOTWEB_PACK_NUM_TEMPFILES
+ PRIV_FDS__MAX
);
205 for (i
= 0; i
< nfds
; i
++) {
206 if (i
< PRIV_FDS__MAX
&& sock
->priv_fd
[i
] == -1) {
207 sock
->priv_fd
[i
] = imsg_get_fd(imsg
);
208 log_debug("%s: assigning socket %d priv_fd %d",
209 __func__
, sock_id
, sock
->priv_fd
[i
]);
214 j
= i
- PRIV_FDS__MAX
;
215 if (sock
->pack_fds
[j
] == -1) {
216 sock
->pack_fds
[j
] = imsg_get_fd(imsg
);
217 log_debug("%s: assigning socket %d pack_fd %d",
218 __func__
, sock_id
, sock
->pack_fds
[j
]);