[Libwebsockets] handling of recv returning 0

Andy Green andy at warmcat.com
Wed Mar 20 23:52:54 CET 2019



On 20/03/2019 21:45, vuko wrote:
> On 20.03.2019 14:20, Andy Green wrote:
>> diff --git a/lib/roles/http/client/client.c 
>> b/lib/roles/http/client/client.c
>> index 9a1aa00d4..b0574e630 100644
>> --- a/lib/roles/http/client/client.c
>> +++ b/lib/roles/http/client/client.c
>> @@ -637,14 +635,15 @@ lws_tls_server_accept(struct lws *wsi)
>>          if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL)
>>                  return LWS_SSL_CAPABLE_ERROR;
>>
>> -       if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) {
>> +       if (m == SSL_ERROR_WANT_READ ||
>> +           (m != SSL_ERROR_ZERO_RETURN && 
>> SSL_want_read(wsi->tls.ssl))) {
>>                  if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) {
>>                          lwsl_info("%s: WANT_READ change_pollfd 
>> failed\n",
>>                                    __func__);
>>                          return LWS_SSL_CAPABLE_ERROR;
>>                  }
>>
>> -               lwsl_info("SSL_ERROR_WANT_READ\n");
>> +               lwsl_info("SSL_ERROR_WANT_READ: m %d\n", m);
>>                  return LWS_SSL_CAPABLE_MORE_SERVICE_READ;
>>          }
>>          if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) {
>>
>> it's on current master. please see if it solves your situation on your 
>> platform + tls library as well.
> 
> This works only fo SSL connections. Non SSL conections use 
> lws_ssl_capable_read_no_ssl function that is missing zero return check.

Sorry, I didn't read your email properly.

> I have reproduced it both on current master and 3.1 version.

This is a different problem... POSIX itself is actually broken for 
returning 0 from recv.

RETURN VALUE

        These calls return the number of bytes received, or -1 if an error
        occurred.  In the event of an error, errno is set to indicate the
        error.

        When a stream socket peer has performed an orderly shutdown, the
        return value will be 0 (the traditional "end-of-file" return).

        Datagram sockets in various domains (e.g., the UNIX and Internet
        domains) permit zero-length datagrams.  When such a datagram is
        received, the return value is 0.

        The value 0 may also be returned if the requested number of bytes to
        receive from a stream socket was 0.

http://man7.org/linux/man-pages/man2/recv.2.html

errno is not set when it returns zero under your reproducer conditions. 
And it's not set by receiving a zero length packet either.  Both cases 
return 0 from the recv().

I also think this will differ per-platform, I guess that's why it's as 
it is atm.  But obviously the spinning is unreasonable.

I pushed something that does the same as your recommendation on master 
and v3.1-stable... if it breaks other platforms I'll adapt it to check 
the platform accordingly.

-Andy

> -vuko
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> https://libwebsockets.org/mailman/listinfo/libwebsockets


More information about the Libwebsockets mailing list