00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00110
00111
00112
00113 int lport;
00114 for (
00115
00116 lport = lastTriedPort==65535 ? 1024 : lastTriedPort+1;
00117
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
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 }