2 ashd - A Sane HTTP Daemon
3 Copyright (C) 2008 Fredrik Tolf <fredrik@dolda2000.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/select.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
39 struct blocker *n, *p;
45 static struct blocker *blockers;
47 static int block(int fd, int ev)
70 static int listensock4(int port)
72 struct sockaddr_in name;
76 memset(&name, 0, sizeof(name));
77 name.sin_family = AF_INET;
78 name.sin_port = htons(port);
79 if((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
82 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &valbuf, sizeof(valbuf));
83 if(bind(fd, (struct sockaddr *)&name, sizeof(name))) {
87 if(listen(fd, 16) < 0) {
94 static int listensock6(int port)
96 struct sockaddr_in6 name;
100 memset(&name, 0, sizeof(name));
101 name.sin6_family = AF_INET6;
102 name.sin6_port = htons(port);
103 if((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
106 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &valbuf, sizeof(valbuf));
107 if(bind(fd, (struct sockaddr *)&name, sizeof(name))) {
111 if(listen(fd, 16) < 0) {
118 static void listenloop(struct muth *muth, va_list args)
122 struct sockaddr_storage name;
126 namelen = sizeof(name);
128 ns = accept(ss, (struct sockaddr *)&name, &namelen);
130 write(ns, "test\n", 5);
135 static void ioloop(void)
138 fd_set rfds, wfds, efds;
139 struct blocker *bl, *nbl;
148 for(bl = blockers; bl; bl = bl->n) {
150 FD_SET(bl->fd, &rfds);
151 if(bl->ev & EV_WRITE)
152 FD_SET(bl->fd, &wfds);
153 FD_SET(bl->fd, &efds);
157 ret = select(maxfd + 1, &rfds, &wfds, &efds, NULL);
160 flog(LOG_CRIT, "ioloop: select errored out: %s", strerror(errno));
161 /* To avoid CPU hogging in case it's bad, which it
166 for(bl = blockers; bl; bl = nbl) {
169 if(FD_ISSET(bl->fd, &rfds))
171 if(FD_ISSET(bl->fd, &wfds))
173 if(FD_ISSET(bl->fd, &efds))
180 int main(int argc, char **argv)
184 if((fd = listensock6(8080)) < 0) {
185 flog(LOG_ERR, "could not listen on IPv6: %s", strerror(errno));
188 mustart(listenloop, fd);
189 if((fd = listensock4(8080)) < 0) {
190 if(errno != EADDRINUSE) {
191 flog(LOG_ERR, "could not listen on IPv4: %s", strerror(errno));
195 mustart(listenloop, fd);