org/objectweb/proactive/core/ssh/SshTunnel.java

00001 /* 
00002  * ################################################################
00003  * 
00004  * ProActive: The Java(TM) library for Parallel, Distributed, 
00005  *            Concurrent computing with Security and Mobility
00006  * 
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  * 
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *  
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  * 
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *  
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s): 
00028  * 
00029  * ################################################################
00030  */ 
00031 package org.objectweb.proactive.core.ssh;
00032 
00033 import java.io.IOException;
00034 import java.net.InetAddress;
00035 import java.util.Random;
00036 
00037 import org.apache.log4j.Logger;
00038 import org.objectweb.proactive.core.ssh.SshParameters;
00039 import org.objectweb.proactive.core.util.log.Loggers;
00040 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00041 
00042 import com.jcraft.jsch.*;
00043 
00044 
00057 public class SshTunnel {
00058     static Logger logger = ProActiveLogger.getLogger(Loggers.SSH);
00059     private static Random _random = new Random();
00060     static private int lastTriedPort = _random.nextInt(65536-1024)+1024;
00061     private int _localPort;
00062     private Session _session;
00063     private String _username;
00064     private String _distantHost;
00065     private String _sshPort;
00066     private int _distantPort;
00067 
00093     public SshTunnel(String distantHost, int distantPort)
00094         throws IOException {
00095         JSchSingleton.acquireLock();
00096         try {
00097             String username = SshParameters.getSshUsername(distantHost);
00098             String sshPort = SshParameters.getSshPort();
00099             Session session;
00100             try {
00101                 session = JSchSingleton.getSession(username, distantHost,
00102                         sshPort);
00103             } catch (IOException e) {
00104                 throw new IOException("SSH tunnel failed: 127.0.0.1 -->" +
00105                     distantHost + ":" + distantPort + "for " + username);
00106             }
00107             
00108             /*
00109              * We are under JSchSingle lock. lastTriedPort will not change until we release it.
00110              *
00111              * Try to find a free port by looping until we find a free port.
00112              */ 
00113             int lport;
00114             for (
00115                         // Start search at the last allocated port
00116                         lport = lastTriedPort==65535 ? 1024 : lastTriedPort+1;
00117                         // No free port found
00118                         lport != lastTriedPort;
00119                         lport = lport==65535 ? 1024 : lport+1) {
00120                                         
00121                 try {
00122                     session.setPortForwardingL("127.0.0.1", lport, distantHost,
00123                         distantPort);
00124                     _session = session;
00125                     _localPort = lport;
00126                     _username = username;
00127                     _distantHost = distantHost;
00128                     _distantPort = distantPort;
00129                     _sshPort = sshPort;
00130                     break;
00131                 } catch (JSchException e) {
00132                     // Port probably in use...
00133                         logger.info("Please ignore the previous line. Everithing is ok; JSch is just a bit too verbose");
00134                 }
00135                 
00136                 
00137             }
00138             
00139             if (lport == lastTriedPort) {
00140                 throw new IOException(
00141                     "SSH tunnel failed (could not allocate port number): 127.0.0.1 -->" +
00142                     distantHost + ":" + distantPort);
00143             }
00144             
00145             lastTriedPort = lport;
00146         } catch (IOException e) {
00147                 throw e;
00148         } finally {
00149             JSchSingleton.releaseLock();
00150         }
00151     }
00152 
00153     public void realClose() throws Exception {
00154         JSchSingleton.acquireLock();
00155         try {
00156             logger.debug("close Tunnel for port " + _localPort);
00157             JSchSingleton.flushMaybe(_username, _distantHost, _sshPort,
00158                 _localPort);
00159             _username = null;
00160             _distantHost = null;
00161             _distantPort = 0;
00162             _sshPort = null;
00163             _session = null;
00164             _localPort = 0;
00165         } catch (Exception e) {
00166             throw e;
00167         } finally {
00168             JSchSingleton.releaseLock();
00169         }
00170     }
00171 
00177     public int getPort() {
00178         return _localPort;
00179     }
00180 
00181     public InetAddress getInetAddress() throws java.net.UnknownHostException {
00182         return InetAddress.getByName(_distantHost);
00183     }
00184 
00185     public String getDistantHost() {
00186         return _distantHost;
00187     }
00188 
00189     public int getDistantPort() {
00190         return _distantPort;
00191     }
00192 }

Generated on Mon Jan 22 15:16:09 2007 for ProActive by  doxygen 1.5.1