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

Andy Green andy at warmcat.com
Wed Nov 23 16:18:51 CET 2016

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 appropriately
>> 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 known
>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