[Twisted-Python] Effects of calling transport.writeSomeData() ?
Mark Montague
mark at catseye.org
Tue Jun 24 11:01:43 MDT 2014
On 2014-06-21, 10:24, exarkun at twistedmatrix.com wrote:
> > If bypassing the reactor this way is bad, how bad is it and what are
> the consequences or effects?
>
> This use is untested. There's no reason to expect it will continue to
> work with future Twisted releases (or, really, that it fully works
> now; since `writeSomeData` bypasses the transport's buffering layer,
> it seems like you're risking an out-of-order or partial send; probably
> these will only arise under load so you may not have observed them in
> your testing).
Thanks for the very helpful reply! This is exactly the sort of thing I
was hoping to find out.
>> Is there a better way to get a working solution?
>
> The proper way to do this would be for OpenSSH to acknowledge the
> operation. At this point you would know it's safe to proceed to the
> next operation. Since you didn't mention anything about
> acknowledgements, I'm guessing there are none.
Correct, the order of events is:
0. client opens OpenSSH socket, sends hello, receives reply
1. user calls the protocol function to create a new OpenSSH session over
the existing socket
2. client sends MUX_C_ALIVE_CHECK to OpenSSH
3. OpenSSH replies with MUX_S_ALIVE
4. client sends MUX_C_NEW_SESSION to OpenSSH, then immediately forwards
the file descriptors
5. OpenSSH replies with either MUX_S_SESSION_OPENED,
MUX_S_PERMISSION_DENIED, or MUX_S_FAILURE.
6. ...session is now created...
7. OpenSSH sends MUX_S_EXIT_MESSAGE when the session has finished
8. client can now close the OpenSSH socket
It would make sense for OpenSSH to acknowledge the MUX_C_NEW_SESSION in
step 4 before the file descriptors get sent, but I've read the source
code and OpenSSH does not do this -- it expects the file descriptors to
be sent as soon as the new session message is sent.
> Since you're already relying on `self.transport.socket.fileno()` and
> `send1msg` (basically, bypassing the transport abstraction and just
> doing socket operations yourself) one improvement you could make would
> be just to rely on that for the whole thing. Don't use
> `writeSomeData`. Use `socket.send(command)`. At least this way you're
> only relying on being able to treat a transport like a UNIX socket -
> not on the particulars of the transport's buffering implementation.
>
> A different approach you could take would be to implement this
> connection sharing feature for Conch. I can pretty much guarantee
> it's possible to implement since an older version of Conch actually
> did implement it. :) The implementation was removed because it was
> fragile, complicated, and poorly tested. It would be great to
> re-introduce the functionality with a higher quality implementation.
I'll look into what it might take to implement this in a robust way with
tests for Conch. I think that's definitely a preferred solution, since
it sounds like such a feature might be accepted (I wasn't considering
this initially since Conch is a generic SSH transport, and piggybacking
on top of an existing OpenSSH socket is a highly-specific thing.) If I
can come up with a good way to do this, I'll submit a patch, otherwise
I'll keep the functionality as it is now, in a standalone class that
doesn't use Conch at all.
--
Mark Montague
mark at catseye.org
More information about the Twisted-Python
mailing list