Suggested fix on Windows: handle also WSAETIMEDOUT after recv() returns failure
Simon Josefsson
simon at josefsson.org
Wed Jun 4 16:06:13 CEST 2008
"Tor Lillqvist" <tml at iki.fi> writes:
> I have been debugging an interesting problem in Evolution's use of
> GnuTLS on Windows. The root cause for the problem was elsewhere, see
> below if you are interested. From GnuTLS's point of view the
> interesting effect was that the recv() call in _gnutls_read() in
> gnutls_buffers.c returned -1, with WSAGetLastError() returning
> WSAETIMEDOUT. I think WSAETIMEDOUT should be handled like
> WSAEWOULDBLOCK here? At least in this case, doing that made the code
> work also without fixing the root cause.
According to MSDN, WSAETIMEDOUT means the connection has been "dropped":
http://msdn.microsoft.com/en-us/library/ms740121(VS.85).aspx
"The connection has been dropped because of a network failure or
because the peer system failed to respond."
Are you saying that calling recv again after a WSAETIMEDOUT actually
results in data sooner or later? If so, I suggest we install this:
diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 8d9be9c..f21c57a 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -318,6 +318,10 @@ _gnutls_read (gnutls_session_t session, void *iptr,
int tmperr = WSAGetLastError();
switch (tmperr)
{
+ case WSAETIMEDOUT:
+ gnutls_assert();
+ /* fall through */
+
case WSAEWOULDBLOCK:
session->internals.errnum = EAGAIN;
break;
This triggers a debug message when debugging is enabled, which may help
people notice that something may be fishy in the recv functions, and
possibly even trace it back to this e-mail.
> FYI: The root cause for the problem was that libsoup uses setsockopt's
> SO_RCVTIMEO and SO_SNDTIMEO options to set the socket's timeout,
> passing a pointer to a struct timeval, like on Unix. But... the
> Winsock designers, for some reason, decided to change the semantics of
> these options: In Winsock the option value is an int, the timeout in
> milliseconds. So when libsoup tried to set the timeout to 30 seconds,
> it actually set it to 30 milliseconds, eek.) What on Earth were they
> thinking when they changed the type of the option value for
> SO_RCVTIMEO and SO_SNDTIMEO like this? They should at least have used
> a different names for the options when they change the type of their
> values. The type unsafety of setsockopt() means the compiler can't
> warn either.
Sigh.
/Simon
More information about the Gnutls-devel
mailing list