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

Andy Green andy at warmcat.com
Thu Nov 24 16:45:33 CET 2016



On November 23, 2016 11:19:50 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:53:57 PM GMT+08:00, Alan Conway
><aconway at redhat.com> wrote:
>>On Wed, 2016-11-23 at 09:46 -0500, Alan Conway 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
>>> ones?
>>> 
>>> > 
>>> > 
>>> > > 
>>> > > 
>>> > > 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
>>> later...
>>> 
>>> > 
>>> >  - 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.
>>> 
>>
>>What if I use a separate context per connection? I know you said I
>
>No, that is a very bad idea.
>
>>should have only one context but: a context per connection avoids all
>>thread-safety issues around concurrent use of a context, and gives me
>a
>>place to store the connection-lifetime info I need. Obviously there'll
>>be extra overhead but would it work?
>
>No.
>
>-Andy
>
>>Cheers,
>>Alan.




More information about the Libwebsockets mailing list