kike: handle accept() errors better

Might prevent some denial of service attacks.
This commit is contained in:
Přemysl Eric Janouch 2018-01-09 05:48:32 +01:00
parent 6c30452b28
commit 674ffb2f6d
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 14 additions and 9 deletions

23
kike.c
View File

@ -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); int fd = accept (listen_fd, (struct sockaddr *) &peer, &peer_len);
if (fd == -1) if (fd == -1)
{ {
if (errno == EAGAIN) if (errno == EAGAIN || errno == EWOULDBLOCK)
return false; return false;
if (errno == EINTR if (errno == EINTR)
|| errno == ECONNABORTED)
return true; return true;
// TODO: handle resource exhaustion (EMFILE, ENFILE) specially if (errno == EBADF
// (stop accepting new connections and wait until we close some; || errno == EINVAL
// also set a timer in case of ENFILE). || errno == ENOTSOCK
print_fatal ("%s: %s", "accept", strerror (errno)); || errno == EOPNOTSUPP)
irc_initiate_quit (ctx); print_fatal ("%s: %s", "accept", strerror (errno));
return false;
// 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); set_blocking (fd, false);
// A little bit questionable once the traffic gets high enough (IMO), // A little bit questionable once the traffic gets high enough (IMO),