2008-12-20 15:25:02 +00:00
|
|
|
|
|
|
|
#include <lighttpd/base.h>
|
|
|
|
#include <lighttpd/angel.h>
|
2009-06-17 08:59:34 +00:00
|
|
|
#include <lighttpd/ip_parsers.h>
|
2008-12-20 15:25:02 +00:00
|
|
|
|
2010-09-25 12:08:56 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
2008-12-20 15:25:02 +00:00
|
|
|
/* listen to a socket */
|
2009-10-09 13:38:12 +00:00
|
|
|
int li_angel_fake_listen(liServer *srv, GString *str) {
|
2014-04-15 11:05:52 +00:00
|
|
|
liSocketAddress addr = li_sockaddr_from_string(str, 80);
|
|
|
|
liSockAddr *saddr = addr.addr;
|
|
|
|
GString *tmpstr;
|
|
|
|
int s, v;
|
2008-12-20 15:25:02 +00:00
|
|
|
|
2014-04-15 11:05:52 +00:00
|
|
|
if (NULL == saddr) {
|
|
|
|
ERROR(srv, "Invalid socket address: '%s'", str->str);
|
|
|
|
return -1;
|
|
|
|
}
|
2010-09-21 13:00:06 +00:00
|
|
|
|
2014-04-15 11:05:52 +00:00
|
|
|
tmpstr = li_sockaddr_to_string(addr, NULL, TRUE);
|
2010-09-21 13:00:06 +00:00
|
|
|
|
2014-04-15 11:05:52 +00:00
|
|
|
switch (saddr->plain.sa_family) {
|
|
|
|
#ifdef HAVE_SYS_UN_H
|
|
|
|
case AF_UNIX:
|
|
|
|
if (-1 == unlink(saddr->un.sun_path)) {
|
2010-09-21 13:17:30 +00:00
|
|
|
switch (errno) {
|
|
|
|
case ENOENT:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ERROR(srv, "removing old socket '%s' failed: %s\n", str->str, g_strerror(errno));
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2010-09-21 13:17:30 +00:00
|
|
|
}
|
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
if (-1 == (s = socket(saddr->plain.sa_family, SOCK_STREAM, 0))) {
|
2010-09-21 13:00:06 +00:00
|
|
|
ERROR(srv, "Couldn't open socket: %s", g_strerror(errno));
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2010-09-21 13:00:06 +00:00
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
if (-1 == bind(s, &saddr->plain, addr.len)) {
|
|
|
|
ERROR(srv, "Couldn't bind socket to '%s': %s", tmpstr->str, g_strerror(errno));
|
2010-09-21 13:00:06 +00:00
|
|
|
close(s);
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2010-09-21 13:00:06 +00:00
|
|
|
}
|
|
|
|
if (-1 == listen(s, 1000)) {
|
2014-04-15 11:05:52 +00:00
|
|
|
ERROR(srv, "Couldn't listen on '%s': %s", tmpstr->str, g_strerror(errno));
|
2010-09-21 13:00:06 +00:00
|
|
|
close(s);
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2010-09-21 13:00:06 +00:00
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
DEBUG(srv, "listen to unix socket: '%s'", tmpstr->str);
|
|
|
|
break;
|
2010-09-21 13:00:06 +00:00
|
|
|
#endif
|
2014-04-15 11:05:52 +00:00
|
|
|
case AF_INET:
|
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
case AF_INET6:
|
|
|
|
#endif
|
|
|
|
if (-1 == (s = socket(saddr->plain.sa_family, SOCK_STREAM, 0))) {
|
2008-12-20 15:25:02 +00:00
|
|
|
ERROR(srv, "Couldn't open socket: %s", g_strerror(errno));
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2008-12-20 15:25:02 +00:00
|
|
|
}
|
|
|
|
v = 1;
|
|
|
|
if (-1 == setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v))) {
|
2008-12-22 22:06:23 +00:00
|
|
|
ERROR(srv, "Couldn't setsockopt(SO_REUSEADDR): %s", g_strerror(errno));
|
2008-12-20 15:25:02 +00:00
|
|
|
close(s);
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2008-12-20 15:25:02 +00:00
|
|
|
}
|
|
|
|
#ifdef HAVE_IPV6
|
2014-04-15 11:05:52 +00:00
|
|
|
if (AF_INET6 == saddr->plain.sa_family && -1 == setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &v, sizeof(v))) {
|
2008-12-22 22:06:23 +00:00
|
|
|
ERROR(srv, "Couldn't setsockopt(IPV6_V6ONLY): %s", g_strerror(errno));
|
2014-04-15 11:05:52 +00:00
|
|
|
close(s);
|
|
|
|
goto error;
|
2008-12-22 21:48:47 +00:00
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
#endif
|
|
|
|
if (-1 == bind(s, &saddr->plain, addr.len)) {
|
|
|
|
ERROR(srv, "Couldn't bind socket to '%s': %s", tmpstr->str, g_strerror(errno));
|
2008-12-22 21:48:47 +00:00
|
|
|
close(s);
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2008-12-22 21:48:47 +00:00
|
|
|
}
|
2013-05-25 14:15:14 +00:00
|
|
|
#ifdef TCP_FASTOPEN
|
|
|
|
v = 1000;
|
|
|
|
setsockopt(s, SOL_TCP, TCP_FASTOPEN, &v, sizeof(v));
|
|
|
|
#endif
|
2008-12-22 21:48:47 +00:00
|
|
|
if (-1 == listen(s, 1000)) {
|
2014-04-15 11:05:52 +00:00
|
|
|
ERROR(srv, "Couldn't listen on '%s': %s", tmpstr->str, g_strerror(errno));
|
2008-12-22 21:48:47 +00:00
|
|
|
close(s);
|
2014-04-15 11:05:52 +00:00
|
|
|
goto error;
|
2008-12-22 21:48:47 +00:00
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
#ifdef HAVE_IPV6
|
|
|
|
if (AF_INET6 == saddr->plain.sa_family) {
|
|
|
|
DEBUG(srv, "listen to ipv6: '%s'", tmpstr->str);
|
|
|
|
} else
|
2008-12-20 15:25:02 +00:00
|
|
|
#endif
|
2014-04-15 11:05:52 +00:00
|
|
|
{
|
|
|
|
DEBUG(srv, "listen to ipv4: '%s'", tmpstr->str);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ERROR(srv, "Unknown address family for '%s'", tmpstr->str);
|
|
|
|
goto error;
|
2008-12-20 15:25:02 +00:00
|
|
|
}
|
2014-04-15 11:05:52 +00:00
|
|
|
|
|
|
|
g_string_free(tmpstr, TRUE);
|
|
|
|
li_sockaddr_clear(&addr);
|
|
|
|
return s;
|
|
|
|
|
|
|
|
error:
|
|
|
|
g_string_free(tmpstr, TRUE);
|
|
|
|
li_sockaddr_clear(&addr);
|
|
|
|
return -1;
|
2008-12-20 15:25:02 +00:00
|
|
|
}
|
|
|
|
|
2008-12-22 16:03:43 +00:00
|
|
|
/* print log messages during startup to stderr */
|
2009-10-09 13:38:12 +00:00
|
|
|
gboolean li_angel_fake_log(liServer *srv, GString *str) {
|
2008-12-20 15:25:02 +00:00
|
|
|
const char *buf;
|
|
|
|
guint len;
|
|
|
|
ssize_t written;
|
|
|
|
UNUSED(srv);
|
|
|
|
|
2008-12-22 21:48:47 +00:00
|
|
|
/* g_string_prepend(str, "fake: "); */
|
2008-12-20 15:25:02 +00:00
|
|
|
buf = str->str;
|
|
|
|
len = str->len;
|
|
|
|
|
|
|
|
while (len > 0) {
|
|
|
|
written = write(2, buf, len);
|
|
|
|
if (written < 0) {
|
2008-12-22 16:03:43 +00:00
|
|
|
switch (errno) {
|
|
|
|
case EAGAIN:
|
|
|
|
case EINTR:
|
|
|
|
continue;
|
|
|
|
}
|
2008-12-20 15:25:02 +00:00
|
|
|
g_string_free(str, TRUE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
len -= written;
|
|
|
|
buf += written;
|
|
|
|
}
|
|
|
|
g_string_free(str, TRUE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2010-09-25 12:08:56 +00:00
|
|
|
|
|
|
|
int li_angel_fake_log_open_file(liServer *srv, GString *filename) {
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = open(filename->str, O_RDWR | O_CREAT | O_APPEND, 0660);
|
|
|
|
if (-1 == fd) {
|
|
|
|
ERROR(srv, "failed to open log file '%s': %s", filename->str, g_strerror(errno));
|
|
|
|
}
|
|
|
|
|
|
|
|
return fd;
|
|
|
|
}
|