Hi,

It's me again. I am using a fantastic FTP server written in pure java that is fully configurable, and allows me to specify the data ports to use for passive file transfer (http://www.mycgiserver.com/~ranab/ftp). This way, I can forward the necessary ports in order to use standard FTP clients. However, when using Jsch, when I attempt to send a file (put), the FTP session hangs. This works fine using the native OpenSSH client. I was able to determine that the issue is when the FTP client closes the data port, the closure is not passed on to the SSH server, thus hanging the FTP session. I made a patch to ChannelDirectTCPIP.java to resolve the issue (please see Patch 1 below).

Then I noticed that when FTPing many small files at once, or tunneling HTTP when the pages contained many requests, the performance wasn't very good. The changes I made to address this are in Patch 2 below. Now the performance is great!

Finally, I noticed that remote forwarding had the same FTP hang issue that the local forwarding had, but this patch was much more involved. I modeled the changes to ChannelForwardedTCPIP.java to look like the existing code in ChannelDirectTCPIP.java (please see Patch 3 below). Basically, I added a disconnect() method, and called it in place of eof().

Now the FTP functionality works great, and the performance is significantly better. Please incorporate these changes into the next release, and let me know if there is a more appropriate way to implement patch 3.

Thanks. Jsch rocks!
==================================================================
Patch 1: Fix FTP hang sending a file over a locally forwarded port
File: ChannelDirectTCPIP.java
*** ChannelDirectTCPIP.java             Wed Aug  6 07:29:45 2003
--- ChannelDirectTCPIP.java.PATCH       Mon Sep 22 00:24:50 2003
***************
*** 102,108 ****
      Packet packet=new Packet(buf);
      int i=0;
      try{
!       while(thread!=null && io.in!=null){
          i=io.in.read(buf.buffer,
                     14,
                     buf.buffer.length-14
--- 102,108 ----
      Packet packet=new Packet(buf);
      int i=0;
      try{
!       while(thread!=null && io!=null && io.in!=null){
          i=io.in.read(buf.buffer,
                     14,
                     buf.buffer.length-14
***************
*** 122,128 ****
      }
      catch(Exception e){
      }
!     thread=null;
  //System.out.println("connect end");

  /*
--- 122,128 ----
      }
      catch(Exception e){
      }
!     disconnect();
  //System.out.println("connect end");

  /*

==================================================================
Patch 2: Speed up performance when connections are setup and destroyed rapidly (ie: FTP & HTTP)
File: ChannelDirectTCPIP.java
*** ChannelDirectTCPIP.java             Wed Aug  6 07:29:45 2003
--- ChannelDirectTCPIP.java.PATCH       Mon Sep 22 00:24:50 2003
***************
*** 83,89 ****
        session.write(packet);
        try{
          while(this.getRecipient()==-1){
!           Thread.sleep(500);
          }
        }
        catch(Exception ee){
--- 83,89 ----
        session.write(packet);
        try{
          while(this.getRecipient()==-1){
!           Thread.sleep(10);
          }
        }
        catch(Exception ee){

File: Channel.java
*** Channel.java        Mon Aug 25 19:27:55 2003
--- Channel.java.PATCH  Mon Sep 22 00:59:03 2003
***************
*** 133,143 ****
        buf.putInt(this.lmpsize);
        session.write(packet);

!       int retry=100;
        while(this.getRecipient()==-1 &&
            session.isConnected() &&
            retry>0){
!       try{Thread.sleep(500);}catch(Exception ee){}
        retry--;
        }
        if(!session.isConnected()){
--- 133,143 ----
        buf.putInt(this.lmpsize);
        session.write(packet);

!       int retry=1000;
        while(this.getRecipient()==-1 &&
            session.isConnected() &&
            retry>0){
!       try{Thread.sleep(50);}catch(Exception ee){}
        retry--;
        }
        if(!session.isConnected()){

==================================================================
Patch 3: Fix FTP hang sending a file over a remotely forwarded port
File: ChannelForwardedTCPIP.java
*** ChannelForwardedTCPIP.java  Tue Aug 26 10:50:44 2003
--- ChannelForwardedTCPIP.java.PATCH    Mon Sep 22 00:58:06 2003
***************
*** 69,75 ****
      Packet packet=new Packet(buf);
      int i=0;
      try{
!       while(thread!=null && io.in!=null){
          i=io.in.read(buf.buffer,
                     14,
                     buf.buffer.length-14
--- 69,75 ----
      Packet packet=new Packet(buf);
      int i=0;
      try{
!       while(thread!=null && io!=null && io.in!=null){
          i=io.in.read(buf.buffer,
                     14,
                     buf.buffer.length-14
***************
*** 88,99 ****
        }
      }
      catch(Exception e){
!       System.out.println(e);
      }
-     thread=null;

!     eof();
    }
    void getData(Buffer buf){
      setRecipient(buf.getInt());
      setRemoteWindowSize(buf.getInt());
--- 88,113 ----
        }
      }
      catch(Exception e){
! //      System.out.println(e);
!     }
!     disconnect();
!
! //    eof();
    }

!   public void disconnect(){
!     close();
!     thread=null;
!     try{
!       if(io!=null && io.in!=null)io.in.close();
      }
+     catch(Exception e){
+       e.printStackTrace();
+     }
+     io=null;
+     Channel.del(this);
+   }
+
    void getData(Buffer buf){
      setRecipient(buf.getInt());
      setRemoteWindowSize(buf.getInt());

==================================================================