If a connected host disappears without our knowledge, as can happen over wireless or a hibernating machine, we continue to hold the port open waiting for messages. Because we never try to send anything down this now-broken pipe, the connection will sit idle taking up a slot in our allowed incoming connections list.
If enough of these happen, an unintended Denial of Service takes place, where all connection slots are filled with now-broken, never ending connections. Setting the TCP keepalive option at least allows these to time out after the default two hours, which is sufficient in the non-malicious case. Signed-off-by: Dan McGee <d...@archlinux.org> --- src/server_socket.c | 8 ++++++-- src/socket_util.c | 15 +++++++++++++++ src/socket_util.h | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/server_socket.c b/src/server_socket.c index 82ad81f..fc8dbd1 100644 --- a/src/server_socket.c +++ b/src/server_socket.c @@ -160,12 +160,16 @@ server_socket_in_event(G_GNUC_UNUSED GIOChannel *source, size_t address_length = sizeof(address); int fd = accept_cloexec_nonblock(s->fd, (struct sockaddr*)&address, &address_length); - if (fd >= 0) + if (fd >= 0) { + if (socket_keepalive(fd)) + g_warning("Could not set TCP keepalive option: %s", + g_strerror(errno)); s->parent->callback(fd, (const struct sockaddr*)&address, address_length, get_remote_uid(fd), s->parent->callback_ctx); - else + } else { g_warning("accept() failed: %s", g_strerror(errno)); + } return true; } diff --git a/src/socket_util.c b/src/socket_util.c index a89a67e..aa0a44e 100644 --- a/src/socket_util.c +++ b/src/socket_util.c @@ -148,3 +148,18 @@ socket_bind_listen(int domain, int type, int protocol, return fd; } + +int +socket_keepalive(int fd) +{ + const int reuse = 1; + +#ifdef WIN32 + const char *optval = (const char *)&reuse; +#else + const void *optval = &reuse; +#endif + + return setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, + optval, sizeof(reuse)); +} diff --git a/src/socket_util.h b/src/socket_util.h index 3ebf408..f27751a 100644 --- a/src/socket_util.h +++ b/src/socket_util.h @@ -63,4 +63,7 @@ socket_bind_listen(int domain, int type, int protocol, int backlog, GError **error); +int +socket_keepalive(int fd); + #endif -- 1.7.6.1 ------------------------------------------------------------------------------ BlackBerry® DevCon Americas, Oct. 18-20, San Francisco, CA Learn about the latest advances in developing for the BlackBerry® mobile platform with sessions, labs & more. See new tools and technologies. Register for BlackBerry® DevCon today! http://p.sf.net/sfu/rim-devcon-copy1 _______________________________________________ Musicpd-dev-team mailing list Musicpd-dev-team@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team