diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2018-01-09 05:48:32 +0100 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2018-01-09 05:48:36 +0100 |
commit | 674ffb2f6dfc750bb719e7e90d8f03ba8d23d7e4 (patch) | |
tree | bb78cc73196c7c5022e8b177f2332dfd1f27835e | |
parent | 6c30452b2849f57dbf621367e1fd5f92197965de (diff) | |
download | xK-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.c | 23 |
1 files changed, 14 insertions, 9 deletions
@@ -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), |