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

Andy Green andy at warmcat.com
Sat Nov 7 00:10:00 CET 2015



On 7 November 2015 01:13:33 GMT+08:00, Andrejs Hanins <andrejs.hanins at ubnt.com> wrote:
>Andy,
>
>On 11/03/2015 04:57 PM, Andy Green wrote:
>> 
>> 
>> On 3 November 2015 22:46:09 GMT+08:00, Andrejs Hanins
><andrejs.hanins at ubnt.com> wrote:
>>>
>>>
>>> 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*
>> 
>> From the user code perspective, it looks like that.
>> 
>> But in fact that api sets POLLOUT able to do something.  After
>POLLOUT comes, other code in the library on POLLOUT path can write
>things, but in this case not call the user code.
>
>Exactly here was the problem. Library didn't send close ack on POLLOUT
>path. I have debugged the problem and submitted a pull request. Please
>check.

Thanks a lot for figuring it out, the patch is pushed.

-Andy

>> 
>>> 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?
>> 
>> Not sure what your problem is now... originally it was extra
>writeable callback coming to user code, right?  But this patch does
>suppress it?  Or still two?
>> 
>> -Andy
>> 
>>>>
>>>> -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