diff options
-rw-r--r-- | include/socketengine.h | 5 | ||||
-rw-r--r-- | modules/extra/m_ssl.cpp | 27 | ||||
-rw-r--r-- | src/socket_transport.cpp | 9 | ||||
-rw-r--r-- | src/sockets.cpp | 38 |
4 files changed, 70 insertions, 9 deletions
diff --git a/include/socketengine.h b/include/socketengine.h index c1dd36536..8772b14a6 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -41,6 +41,11 @@ class CoreExport SocketEngine /** Read from sockets and do things */ static void Process(); + + static int GetLastError(); + static void SetLastError(int); + + static bool IgnoreErrno(); }; #endif // SOCKETENGINE_H diff --git a/modules/extra/m_ssl.cpp b/modules/extra/m_ssl.cpp index 85b99d119..44971908c 100644 --- a/modules/extra/m_ssl.cpp +++ b/modules/extra/m_ssl.cpp @@ -190,14 +190,37 @@ SSLSocketIO::SSLSocketIO() int SSLSocketIO::Recv(Socket *s, char *buf, size_t sz) { int i = SSL_read(this->sslsock, buf, sz); - TotalRead += i; + if (i > 0) + TotalRead += i; + else if (i < 0) + { + int err = SSL_get_error(this->sslsock, i); + switch (err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + SocketEngine::SetLastError(EAGAIN); + } + } + return i; } int SSLSocketIO::Send(Socket *s, const char *buf, size_t sz) { int i = SSL_write(this->sslsock, buf, sz); - TotalWritten += i; + if (i > 0) + TotalWritten += i; + else if (i < 0) + { + int err = SSL_get_error(this->sslsock, i); + switch (err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + SocketEngine::SetLastError(EAGAIN); + } + } return i; } diff --git a/src/socket_transport.cpp b/src/socket_transport.cpp index 72b712232..26653e55f 100644 --- a/src/socket_transport.cpp +++ b/src/socket_transport.cpp @@ -29,8 +29,10 @@ bool BufferedSocket::ProcessRead() this->recv_len = 0; int len = this->io->Recv(this, tbuffer, sizeof(tbuffer) - 1); - if (len <= 0) + if (len == 0) return false; + if (len < 0) + return SocketEngine::IgnoreErrno(); tbuffer[len] = 0; this->read_buffer.append(tbuffer); @@ -42,8 +44,11 @@ bool BufferedSocket::ProcessRead() bool BufferedSocket::ProcessWrite() { int count = this->io->Send(this, this->write_buffer); - if (count <= -1) + if (count == 0) return false; + if (count < 0) + return SocketEngine::IgnoreErrno(); + this->write_buffer = this->write_buffer.substr(count); if (this->write_buffer.empty()) SocketEngine::Change(this, false, SF_WRITABLE); diff --git a/src/sockets.cpp b/src/sockets.cpp index e71505d44..948f3e238 100644 --- a/src/sockets.cpp +++ b/src/sockets.cpp @@ -348,15 +348,17 @@ size_t cidr::hash::operator()(const cidr &s) const int SocketIO::Recv(Socket *s, char *buf, size_t sz) { - size_t i = recv(s->GetFD(), buf, sz, 0); - TotalRead += i; + int i = recv(s->GetFD(), buf, sz, 0); + if (i > 0) + TotalRead += i; return i; } int SocketIO::Send(Socket *s, const char *buf, size_t sz) { - size_t i = send(s->GetFD(), buf, sz, 0); - TotalWritten += i; + int i = send(s->GetFD(), buf, sz, 0); + if (i > 0) + TotalWritten += i; return i; } @@ -402,7 +404,7 @@ void SocketIO::Connect(ConnectionSocket *s, const Anope::string &target, int por int c = connect(s->GetFD(), &s->conaddr.sa, s->conaddr.size()); if (c == -1) { - if (Anope::LastErrorCode() != EINPROGRESS) + if (!SocketEngine::IgnoreErrno()) s->OnError(Anope::LastError()); else { @@ -542,3 +544,29 @@ bool ListenSocket::ProcessRead() return true; } +int SocketEngine::GetLastError() +{ +#ifndef _WIN32 + return errno; +#else + return WSAGetLastError(); +#endif +} + +void SocketEngine::SetLastError(int err) +{ +#ifndef _WIN32 + errno = err; +#else + WSASetLastError(err); +#endif +} + +bool SocketEngine::IgnoreErrno() +{ + return GetLastError() == EAGAIN + || GetLastError() == EWOULDBLOCK + || GetLastError() == EINTR + || GetLastError() == EINPROGRESS; +} + |