Hi ymnk,

I have found a timing issue with reverse port forwarding 
(session.setPortForwardingR). This is affecting my application when it 
is running on the same physical box as the SSH server. My application 
sets up a series of remote forwards, and I noticed that calls to 
session.setPortForwardingR() take a very long time (exactly 10 seconds 
to be precise). This is because the reply from the SSH server is being 
received before the sending thread is ready (sleeping). So, the thread 
interrupt never occurs, and the sending thread sleeps for the full 10 
seconds.

I have resolved the issue by replacing the sleep/interrupt logic with a 
simple synchronized reply lock. I have attached the patch diffs to 
0.1.43 below.

Thanks.
  - Scott

P.S: Please also notice that I will throw the error Exception with 
(reply!=1) as opposed to (reply==0) because reply is seeded to -1, and 
if the reply is not received within the full 10 seconds window, I think 
we still want to throw the error.

==== Begin Patch ====

*** Session.java        version 0.1.43
--- Session.java        patched
***************
*** 1503,1512 ****
           break;
         case SSH_MSG_REQUEST_FAILURE:
         case SSH_MSG_REQUEST_SUCCESS:
             Thread t=grr.getThread();
             if(t!=null){
               grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0);
!             t.interrupt();
             }
           break;
         default:
--- 1503,1514 ----
           break;
         case SSH_MSG_REQUEST_FAILURE:
         case SSH_MSG_REQUEST_SUCCESS:
+           synchronized(grr.replyLock){
             Thread t=grr.getThread();
             if(t!=null){
               grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0);
!             grr.replyLock.notifyAll();
!           }
             }
           break;
         default:
***************
*** 1657,1662 ****
--- 1659,1665 ----
     private class GlobalRequestReply{
       private Thread thread=null;
       private int reply=-1;
+     public Object replyLock = new Object();
       void setThread(Thread thread){
         this.thread=thread;
         this.reply=-1;
***************
*** 1673,1678 ****
--- 1676,1682 ----

       String address_to_bind=ChannelForwardedTCPIP.normalize(bind_address);

+     synchronized(grr.replyLock){
       try{
         // byte SSH_MSG_GLOBAL_REQUEST 80
         // string "tcpip-forward"
***************
*** 1695,1709 ****
       }

       grr.setThread(Thread.currentThread());
!     try{ Thread.sleep(10000);}
!     catch(Exception e){
       }
       int reply=grr.getReply();
       grr.setThread(null);
!     if(reply==0){
         throw new JSchException("remote port forwarding failed for 
listen port "+rport);
       }
       }
     }
     public void delPortForwardingR(int rport) throws JSchException{
       ChannelForwardedTCPIP.delPort(this, rport);
--- 1699,1714 ----
       }

       grr.setThread(Thread.currentThread());
!     try{ grr.replyLock.wait(10000); }
!     catch(InterruptedException e){
       }
       int reply=grr.getReply();
       grr.setThread(null);
!     if(reply!=1){
         throw new JSchException("remote port forwarding failed for 
listen port "+rport);
       }
       }
+     }
     }
     public void delPortForwardingR(int rport) throws JSchException{
       ChannelForwardedTCPIP.delPort(this, rport);

==== End Patch ====

------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
_______________________________________________
JSch-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jsch-users

Reply via email to