aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2018-01-09 05:48:32 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2018-01-09 05:48:36 +0100
commit674ffb2f6dfc750bb719e7e90d8f03ba8d23d7e4 (patch)
treebb78cc73196c7c5022e8b177f2332dfd1f27835e
parent6c30452b2849f57dbf621367e1fd5f92197965de (diff)
downloadxK-674ffb2f6dfc750bb719e7e90d8f03ba8d23d7e4.tar.gz
xK-674ffb2f6dfc750bb719e7e90d8f03ba8d23d7e4.tar.xz
xK-674ffb2f6dfc750bb719e7e90d8f03ba8d23d7e4.zip
kike: handle accept() errors better
Might prevent some denial of service attacks.
-rw-r--r--kike.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/kike.c b/kike.c
index 92fd482..dfd896f 100644
--- a/kike.c
+++ b/kike.c
@@ -3379,20 +3379,25 @@ irc_try_fetch_client (struct server_context *ctx, int listen_fd)
int fd = accept (listen_fd, (struct sockaddr *) &peer, &peer_len);
if (fd == -1)
{
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
return false;
- if (errno == EINTR
- || errno == ECONNABORTED)
+ if (errno == EINTR)
return true;
- // TODO: handle resource exhaustion (EMFILE, ENFILE) specially
- // (stop accepting new connections and wait until we close some;
- // also set a timer in case of ENFILE).
- print_fatal ("%s: %s", "accept", strerror (errno));
- irc_initiate_quit (ctx);
- return false;
+ if (errno == EBADF
+ || errno == EINVAL
+ || errno == ENOTSOCK
+ || errno == EOPNOTSUPP)
+ print_fatal ("%s: %s", "accept", strerror (errno));
+
+ // OS kernels may return a wide range of unforeseeable errors.
+ // Assuming that they're either transient or caused by
+ // a connection that we've just extracted from the queue.
+ print_warning ("%s: %s", "accept", strerror (errno));
+ return true;
}
+ hard_assert (peer_len <= sizeof peer);
set_blocking (fd, false);
// A little bit questionable once the traffic gets high enough (IMO),