[Libwebsockets] handling of recv returning 0

Andy Green andy at warmcat.com
Wed Mar 20 14:20:08 CET 2019



On 20/03/2019 20:20, vuko wrote:
> Hi,
> 
> I have found problem with non SSL connection on Unix platforms. If 
> network socket is closed on other end lws loop cpu usage changes to 
> 100%. Poll function does not block on closed socket - it immediately 
> returns. Solution is to check if value returned by recv is 0.

We've had a few of these in the past... it's complicated by the fact 
that different tls libraries and platforms return different stuff and 
errno set differently for the same situation.

I thought they had all been gone a while, but...

> This check is already implemented in lws_ssl_capable_read_no_ssl 
> function, but is only done on unix sockets:
> 
> if (!n && wsi->unix_skt)
>      return LWS_SSL_CAPABLE_ERROR;
> 
> changing it to:
> if (!n)
>      return LWS_SSL_CAPABLE_ERROR;
> solves the issue, but i am not sure how this should be handled on 
> non-unix platforms.
> 
> Way to reproduce:
> 1. run test server:
>     $ echo -e  "HTTP/1.0 200 OK\r\n\r\n" | nc -l -p 7681
> 
> 2. run minimal-http-client built with "i.ssl_connection = 
> LCCSCF_USE_SSL;" commented out:
>     $ minimal-http-client -d 1307 -l
> 
> 3. use Ctrl-C on terminal running nc to terminate server. Client should 
> go into infinite loop printing:
> [2019/03/20 13:09:54:9187] DEBUG: _lws_change_pollfd: wsi 
> 0x561e29f6b720: fd 6 events 0 -> 1
> [2019/03/20 13:09:54:9187] DEBUG: _lws_change_pollfd: wsi 
> 0x561e29f6b720: fd 6 events 1 -> 0

...this last bit is sounding a familiar... I saw something similar the 
other day on linux + OpenSSL 1.1.1b and fixed it... the fix got squashed 
as part of another patch but it was this stanza

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.

-Andy


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


More information about the Libwebsockets mailing list