<br><br><div class="gmail_quote">On Tue, Nov 6, 2012 at 10:49 PM, Matt Freeman <span dir="ltr">&lt;<a href="mailto:matt@nonuby.com" target="_blank">matt@nonuby.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote">I asked this question on  Stackoverflow (even offered a bounty) and IRC:<br><br><a href="http://stackoverflow.com/questions/13117502/twisted-conch-flow-control" target="_blank">http://stackoverflow.com/questions/13117502/twisted-conch-flow-control</a><br>


--<br><div>
        <p>I have a Twisted Conch SSH server and the typical scenario is this:</p>

<p>git via OpenSSH client   &gt;&gt;--- WAN1 ---&gt;&gt; Twisted conch svr &gt;&gt;--- WAN2 --&gt;&gt; Git server</p>

<p>There will be occassions that the &#39;git push&#39; is sending data faster 
over WAN1 than I can proxy it over WAN2, so I need to tell the client to
 slow down (well before any TCP packet loss causes adjustments the TCP 
window size) to avoid buffering too much on the Twisted server. Reading 
the RFC for SSH this is accomplished with not acknowledging via adj 
window this will then cause the git push to block on syscall write to 
the pipe backed by openssh. </p>

<p>Looking at conch/ssh/connection.py:L216 in the method  def 
ssh_CHANNEL_DATA(self, packet):
I can accomplish this with setting localWindowSize to 0, and inflight 
data will still land as the predicate on 230 should still pass (give 
localWindowLeft). I am wondering if this is the correct approach or am I
 missing something blindly obvious with regards to flow control with 
Twisted SSH Conch? *</p>

<p>Note: I acknowledge there are methods placeholders for stopWriting 
and startWriting on (channel) that I can override so I have hooks to 
control the other side of the transmission &#39;git pull&#39;, but Im interested
 in first leg. Also IPush/IPull producer dont seem applicable at 
this level and I cant see how I can tie in these higher abstraction 
without butchering conch?<br></p></div></div></blockquote><div>The general non-SSH specific answer is to use the producer API. Something like:<br><br>    wan2transport.registerProducer(wan1transport, True)<br> <br>Assuming WAN2 is also over SSH (it wasn&#39;t quite clear), SSHChannel ideally should implement the producer and consumer APIs so you could do:<br>
<br>    wan2channel.registerProducer(wan1channel, True)<br><br>But, as you say, it doesn&#39;t implement those APIs. Thus it looks like you&#39;d want to subclass SSHChannel, and have wan2&#39;s SSHChannel.stop/startWriting call pause/resumeProducing on the WAN1 channel&#39;s *transport* (SSHConnection). Unless you have multiple channels in your incoming SSH connection that you want to pause/resume separately, and it doesn&#39;t sound like you do, this should work.<br>
<br>twisted.conch.scripts.conch.SSHSession has an example of this, more or less, except that it&#39;s pausing reading from stdin rather than another SSH connection.<br><br></div></div>-- <br>Itamar Turner-Trauring, Future Foundries LLC<br>
<a href="http://futurefoundries.com/" target="_blank">http://futurefoundries.com/</a> — Twisted consulting, training and support.<br><br>