Hi Nick,
I have a question for you. It's not high priority, so feel free to postpone your answer till after the workshop is over.
Are you aware of pyptlib? It is a small Python library that does the managed proxy environment-variable/stdout configuration dance, so that people who write pluggable transports don't have to care how the pluggable transport protocol actually works.
Another thing I would like transport authors to never learn about is the Extended ORPort. It would be truly great if pyptlib could do the Extended ORPort dance (authentication, send client's IP address, etc.), and after it's completed, let the transport send whatever ORPort data it wants.
Unfortunately, I don't know how to do such a thing without influencing a certain networking programming style to the transport author. For example, if I coded the Extended ORPort client in Twisted, the transport author would probably have to use Twisted for the rest of her communication with the Extended ORPort. Similarly, if I coded the Extended ORPort client using the low-level 'socket' module, a transport author who wanted to use Twisted would be in trouble.
As a matter of fact, I'm not sure how to do this task without coding separate different Extended ORPort clients for each networking library (one for Twisted, one for 'socket', etc.). But this sounds like too much work.
Do you think there is a way to do what I want, or is it a lost cause? #7903 is the relevant ticket.
Thanks!
On Wed, Jan 23, 2013 at 7:02 PM, George Kadianakis desnacked@riseup.net wrote:
Hi Nick,
Hi, George!
[...]
Unfortunately, I don't know how to do such a thing without influencing a certain networking programming style to the transport author. For example, if I coded the Extended ORPort client in Twisted, the transport author would probably have to use Twisted for the rest of her communication with the Extended ORPort. Similarly, if I coded the Extended ORPort client using the low-level 'socket' module, a transport author who wanted to use Twisted would be in trouble.
As a matter of fact, I'm not sure how to do this task without coding separate different Extended ORPort clients for each networking library (one for Twisted, one for 'socket', etc.). But this sounds like too much work.
So generally speaking, if you want to implement a protocol in a transport-neutral way, you're into architecturally tricky territory. One option is to have a transport abstraction that different transports can implement -- but in practice at most one library's set of transports will start out implementing your transport abstraction, so you're not in luck there. Another option is to make a protocol-handling object that receives bytes and tells you when you can write bytes, and then write code to plug it onto different kinds of transport -- but neither is quite so clean and simple as writing the protocol with exactly one transport in mind.
In practice, I think that you don't need to worry about an arbitrary number of transports -- in general, asynchonous ones tend to converge to interfaces like twisted or libevent, and synchonous ones tend to look like socket. For flexibility here, you might want to carefully restrict which methods of the underlying transport you call--possibly via a tidy little wrapper -- so that it's easy to tell what methods you're really relying on.
(Of course, none of these are necessarily going to be great ideas in practice; if they don't work, I'd suggest something else.)
yrs,