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

Alan Conway aconway at redhat.com
Wed Nov 23 15:53:57 CET 2016


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
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?

Cheers,
Alan.



More information about the Libwebsockets mailing list