[Libwebsockets] 'Close' frame with external message loop issue

Andrejs Hanins andrejs.hanins at ubnt.com
Tue Nov 3 15:46:09 CET 2015



On 11/02/2015 09:21 PM, Andy Green wrote:
> 
> 
> On 3 November 2015 02:49:15 GMT+08:00, Andrejs Hanins <andrejs.hanins at ubnt.com> wrote:
>>
>>
>> On 11/02/2015 08:25 PM, Andy Green wrote:
>>>
>>>
>>> On 2 November 2015 22:52:59 GMT+08:00, Andrejs Hanins
>> <andrejs.hanins at ubnt.com> wrote:
>>>> Hi,
>>>>
>>>> 	I'm using LWS in server mode with external message loop (i.e. I
>> call
>>>> libwebsocket_service_fd by myself based on poll events reported by
>>>> external mechanism). Everything works absolutely fine, except when
>> WS
>>>> client sends a 'Close' frame to the sever. The frame is successfully
>>>> received by server (server log has 'server sees client close
>> packet')
>>>> but the client doesn't receive a response to 'Close' frame. I see
>> that
>>>> server requests 'writable' state with the intention to respond back
>> to
>>>> the client (POLLOUT added to the events), 'writable' state is indeed
>>>> acquired as per message 'lws_calllback_as_writeable: 0xb39910
>>>> (user=0xb99a50)' followed only by a single user callback
>>>> LWS_CALLBACK_SERVER_WRITEABLE. The actual sending of 'Close'
>> response
>>>> doesn't happedn.
>>>>
>>>> 	I have a suspicion that this situation is not handled properly by
>> LWS
>>>> code. Instead of sending an internal frame ('Close' response), the
>>>> library just calls LWS_CALLBACK_SERVER_WRITEABLE *as if* user had
>>>> requested a write, but this is not the case. User code doesn't have
>>>> anything to write. As a result, system ends up in hanged state -
>> client
>>>> wait for 'Close' response, but server does nothing.
>>>
>>> Is your lws older than a couple of weeks?  This patch was aimed at
>> solving that:
>>>
>>>
>> http://git.libwebsockets.org/cgi-bin/cgit/libwebsockets/commit/?id=2488c46c9bbed0ff5f1438f8709421effe4b224b
>>
>> I'm using latest stable tag v1.5-chrome47-firefox41 which includes
>> mentioned fix. But yes, the
>> issue seems to be somewhat similar, because I also get unexpected
>> writable cb.
> 
> Might be worth dumping wsi->state at the place that's patched, in case it's a slightly different close-related state than is checked for atm.

Did that and got the following log:

written 66 bytes to client
spill on uh-ws-proto
server sees client close packet
libwebsocket_read: read_ok
lws_handle_POLLOUT_event 7 <--- 7 is WSI_STATE_RETURNED_CLOSE_ALREADY
lws_calllback_as_writeable: 0x9e9bf0 (user=0x9e9680)

There is nothing else follows in the log.

So, the state 7 is already handled by the patch, but the connection is still not closed and user writable callback is called.
Although, I'm struggling to understand how writable callback *is not* supposed to be called in state 7 if the last line of
lws_handle_POLLOUT_event() method is exactly lws_calllback_as_writeable().

Any other ideas to try?

> 
> -Andy
> 
>>>
>>> -Andy
>>>
>>>> 	I tried to call libwebsocket_service(ctx, 0) each time I receive
>>>> LWS_CALLBACK_SERVER_WRITEABLE, but it also doesn't help for some
>>>> reason. I just got additional callback to LWS_CALLBACK_GET_THREAD_ID
>>>> for which I always return 0.
>>>>
>>>> BR, Andrey
>>>> _______________________________________________
>>>> Libwebsockets mailing list
>>>> Libwebsockets at ml.libwebsockets.org
>>>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>>
> 



More information about the Libwebsockets mailing list