From dbc6dc90283220c06b4f4946cf0a131d2f965884 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Tue, 16 Apr 2013 00:20:01 +0200 Subject: Do not enable SO_LINGER on our sockets Using this option allowed close() to block for up to a second Thanks to Shamsdeen and Rix for their assistance that made this fix possible Fixes issue #445 reported by @shaggie76 Fixes issue #494 reported by @Rixcho --- src/socketengine.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/socketengine.cpp') diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 27abd0ad6..6c99edc95 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -166,12 +166,7 @@ int SocketEngine::NonBlocking(int fd) void SocketEngine::SetReuse(int fd) { int on = 1; - struct linger linger = { 0, 0 }; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)); - /* This is BSD compatible, setting l_onoff to 0 is *NOT* http://web.irc.org/mla/ircd-dev/msg02259.html */ - linger.l_onoff = 1; - linger.l_linger = 1; - setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger)); } int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen) -- cgit v1.3.1-10-gc9f91 From 47332d6e9b990498dd35457090dd8983d8aae8d3 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 16 Apr 2013 03:34:58 -0500 Subject: Fix m_ssl_gnutls and perhaps some other things on Windows by recognizing WSAEWOULDBLOCK --- include/socketengine.h | 5 +++++ src/inspsocket.cpp | 6 +++--- src/modules/extra/m_ssl_gnutls.cpp | 12 ++++++++++++ src/socketengine.cpp | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) (limited to 'src/socketengine.cpp') diff --git a/include/socketengine.h b/include/socketengine.h index b790f6d77..293d27e43 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -489,6 +489,11 @@ public: /** Get data transfer statistics, kilobits per second in and out and total. */ void GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total); + + /** Should we ignore the error in errno? + * Checks EAGAIN and WSAEWOULDBLOCK + */ + static bool IgnoreError(); }; SocketEngine* CreateSocketEngine(); diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index 27c6f87ec..d78ace318 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -200,7 +200,7 @@ void StreamSocket::DoRead() error = "Connection closed"; ServerInstance->SE->ChangeEventMask(this, FD_WANT_NO_READ | FD_WANT_NO_WRITE); } - else if (errno == EAGAIN) + else if (SocketEngine::IgnoreError()) { ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_READ | FD_READ_WILL_BLOCK); } @@ -291,7 +291,7 @@ void StreamSocket::DoWrite() } else if (rv < 0) { - if (errno == EAGAIN || errno == EINTR) + if (errno == EINTR || SocketEngine::IgnoreError()) ServerInstance->SE->ChangeEventMask(this, FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK); else SetError(strerror(errno)); @@ -388,7 +388,7 @@ void StreamSocket::DoWrite() { error = "Connection closed"; } - else if (errno == EAGAIN) + else if (SocketEngine::IgnoreError()) { eventChange = FD_WANT_FAST_WRITE | FD_WRITE_WILL_BLOCK; } diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 38b3700b5..e329186a5 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -86,6 +86,12 @@ static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t user_wrap, void* buffe return -1; } int rv = ServerInstance->SE->Recv(user, reinterpret_cast(buffer), size, 0); + if (rv < 0) + { + /* On Windows we need to set errno for gnutls */ + if (SocketEngine::IgnoreError()) + errno = EAGAIN; + } if (rv < (int)size) ServerInstance->SE->ChangeEventMask(user, FD_READ_WILL_BLOCK); return rv; @@ -100,6 +106,12 @@ static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t user_wrap, const void* return -1; } int rv = ServerInstance->SE->Send(user, reinterpret_cast(buffer), size, 0); + if (rv < 0) + { + /* On Windows we need to set errno for gnutls */ + if (SocketEngine::IgnoreError()) + errno = EAGAIN; + } if (rv < (int)size) ServerInstance->SE->ChangeEventMask(user, FD_WRITE_WILL_BLOCK); return rv; diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 6c99edc95..cbdfb5651 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -255,3 +255,17 @@ void SocketEngine::GetStats(float &kbitpersec_in, float &kbitpersec_out, float & kbitpersec_in = in_kbit / 1024; kbitpersec_out = out_kbit / 1024; } + +bool SocketEngine::IgnoreError() +{ + if (errno == EAGAIN) + return true; + +#ifdef _WIN32 + if (WSAGetLastError() == WSAEWOULDBLOCK) + return true; +#endif + + return false; +} + -- cgit v1.3.1-10-gc9f91 From 2bb64c5dcfb66e9bf7f6114de6501fd5dcd97138 Mon Sep 17 00:00:00 2001 From: attilamolnar Date: Wed, 24 Apr 2013 19:54:58 +0200 Subject: Move SocketEngine::IgnoreError() code into socketengine.h and add test for EWOULDBLOCK --- include/socketengine.h | 13 +++++++++++++ src/socketengine.cpp | 14 -------------- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'src/socketengine.cpp') diff --git a/include/socketengine.h b/include/socketengine.h index 293d27e43..2fc3cdbfd 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -496,6 +496,19 @@ public: static bool IgnoreError(); }; +inline bool SocketEngine::IgnoreError() +{ + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) + return true; + +#ifdef _WIN32 + if (WSAGetLastError() == WSAEWOULDBLOCK) + return true; +#endif + + return false; +} + SocketEngine* CreateSocketEngine(); #endif diff --git a/src/socketengine.cpp b/src/socketengine.cpp index cbdfb5651..6c99edc95 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -255,17 +255,3 @@ void SocketEngine::GetStats(float &kbitpersec_in, float &kbitpersec_out, float & kbitpersec_in = in_kbit / 1024; kbitpersec_out = out_kbit / 1024; } - -bool SocketEngine::IgnoreError() -{ - if (errno == EAGAIN) - return true; - -#ifdef _WIN32 - if (WSAGetLastError() == WSAEWOULDBLOCK) - return true; -#endif - - return false; -} - -- cgit v1.3.1-10-gc9f91