[Libwebsockets] How to set the "user" callback parameter for adopted sockets?

Andy Green andy at warmcat.com
Thu Nov 24 16:44:32 CET 2016

On November 23, 2016 11:18:51 PM GMT+08:00, Andy Green <andy at warmcat.com> wrote:

Forwarding to the list, since rhat mangles the list address in replies.

>On November 23, 2016 10:46:51 PM GMT+08:00, Alan Conway
><aconway at redhat.com> wrote:
>>On Wed, 2016-11-23 at 08:50 +0800, Andy Green wrote:
>>> On Tue, 2016-11-22 at 19:02 -0500, Alan Conway wrote:
>>> > 
>>> > I'm making progress! I can crash my router from a web brower :)
>>> > 
>>> > I can't figure out how to set the "user" parameter for lws
>>> > callbacks
>>> > for a socket adopted with lws_adopt_socket(). I can access the
>>> That's not what *user_space is for.
>>> It's for protocol-specific local data, per-connection.  When the
>>> protocol changes, which it may often do with a http/1.1 keepalive
>>> connection visiting urls that map on to different plugins, the user
>>> data allocation is destroyed by lws and a new one sized
>>> for the new protocol allocated.
>>For me, the protocol starts as "http" and may change to "binary" or
>>"amqp" (which I treat as both "amqp"). Does that mean that if I store
>>context for the http protocol, it will be wiped out in the upgrade? Is
>>there any way to preserve some per-connection data between the two or
>>is each protocol session treated as entirely separate from previous
>Store your persistant data on your non-lws side connection structure. 
>The user_data pointer belongs to the lws side not the external
>application.  That's why you'd need another pointer.
>>> > 
>>> > allocated space *after* the adopt call with lws_wsi_user(), but
>>> > lws_adopt_socket() itself is firing my callbacks so that's too
>>> > late.
>>> > 
>>> > The docs mention setting up your session data on the
>>> > LWS_CALLBACK_ESTABLISHED event, but at that point I have nothing I
>>> > can
>>> > use to find data from my application.
>>> LWS doesn't have this concept of external shadowed data per-
>>> connection
>>> built-in.
>>> You have two ways to do it
>>>  - add a new opaque void * in struct lws and set it at adopt-time,
>>> provide an accessor to get it from the wsi.  This is a bit of a
>>> burden
>>> for everyone who doesn't care about this then.
>>For current purposes I need to use a released, packaged version of lws
>>so modifying it isn't an option - I do hope to make contributions
>Maybe released, packaged versions don't do what you want.
>There are a lot of ws libs but ones that allow this kind of retrofit /
>coexistance exactly how you want are rare, since it's fiddly, different
>in each case and people who want it often lack the time travel
>equipment to inform the library guys they want it to exist in their
>past already.
>>>  - Set the context user pointer at context creation time.  You can
>>> get
>>> this from a wsi in the callback.  You can then use this context-wide
>>> pointer to dereference the wsi pointer to your private connection
>>> pointer on your side, entirely outside of lws.
>>I could use either the fd or the wsi pointer to look up my application
>>data, but it's an expensive lookup that requires a map of all the
>>fds/wsi-pointers. I could use thread-local storage as a hack to get my
>>context into the initial "http" established callback, but that doesn't
>>help if it will get wiped out in the upgrade to "amqp"... Hmmm.
>You can use a hashed table for now, since you are restricting the
>solution to already exist in your OS, and replace it with an lws-side
>private pointer later.
>>> -Andy
>>> > 
>>> > Thanks,
>>> > Alan.
>>> > _______________________________________________
>>> > Libwebsockets mailing list
>>> > Libwebsockets at ml.libwebsockets.org
>>> > http://libwebsockets.org/mailman/listinfo/libwebsockets

More information about the Libwebsockets mailing list