blob: b86307023fb832b62a00e9c0932efade2c8f8642 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ptp.remotetools.internal.ssh;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.ptp.remotetools.exception.PortForwardingException;
import org.eclipse.ptp.remotetools.exception.RemoteConnectionException;
import com.jcraft.jsch.JSchException;
/**
* Keeps references to all active port forwardings of a connection. This
* forwardings are shared by all execution managers, since it is a ressource
* that applies only to the connection.
*
* @author dfferber
*
*/
public class RemotePortForwardingPool {
/**
* Remote port to local forwarding that are active on the Connection.
*/
private final HashMap<Integer, RemotePortForwarding> remotePortForwardings = new HashMap<Integer, RemotePortForwarding>();;
/**
* Connection
*/
private final Connection connection;
public RemotePortForwardingPool(Connection connection) {
assert connection != null;
this.connection = connection;
}
public RemotePortForwarding createRemotePortForwarding(ExecutionManager owner, int remotePort, String localAddress,
int localPort) throws RemoteConnectionException, PortForwardingException {
assert (remotePort > 0);
assert (localPort > 0);
assert (owner != null);
assert (connection.getSession() != null);
synchronized (remotePortForwardings) {
/*
* Test if the forwarding is not already active.
*/
Integer remotePortInteger = new Integer(remotePort);
RemotePortForwarding remotePortForwarding = remotePortForwardings.get(remotePortInteger);
if (remotePortForwarding != null) {
throw new PortForwardingException(PortForwardingException.REMOTE_PORT_ALREADY_FORWARDED);
}
/*
* Create a port forwarding in Jsch.
*/
try {
this.connection.getSession().setPortForwardingR(remotePort, localAddress, localPort);
} catch (JSchException e) {
throw new PortForwardingException(PortForwardingException.REMOTE_FORWARDING_FAILED, e);
}
/*
* Create new forwarding instance and add it to the table.
*/
remotePortForwarding = new RemotePortForwarding(owner, localPort, localAddress, remotePort);
remotePortForwardings.put(remotePortInteger, remotePortForwarding);
return remotePortForwarding;
}
}
public void releaseRemotePortForwarding(RemotePortForwarding remoteForwarding, ExecutionManager owner)
throws RemoteConnectionException, PortForwardingException {
assert remoteForwarding != null;
assert (connection.getSession() != null);
synchronized (remotePortForwardings) {
/*
* Assure the port forwarding that is still active.
*/
if (!remoteForwarding.isActive()) {
throw new PortForwardingException(PortForwardingException.REMOTE_FORWARDING_NOT_ATIVE);
}
/*
* If a execution manager is given as owner, then assure the port
* forwarding belongs to it.
*/
if (owner != null) {
if (remoteForwarding.owner != owner) {
throw new PortForwardingException(PortForwardingException.REMOTE_FORWARDING_NOT_ATIVE);
}
}
Integer remotePortInteger = new Integer(remoteForwarding.remotePort);
assert remotePortForwardings.containsKey(remotePortInteger);
turnOffRemotePortForwarding(remoteForwarding);
remotePortForwardings.remove(remotePortInteger);
}
}
public RemotePortForwarding getRemotePortForwarding(int remotePort) throws RemoteConnectionException, PortForwardingException {
assert remotePort > 0;
assert (connection.getSession() != null);
synchronized (remotePortForwardings) {
Integer remotePortInteger = new Integer(remotePort);
return remotePortForwardings.get(remotePortInteger);
}
}
public void disconnect() {
Iterator<RemotePortForwarding> iterator = remotePortForwardings.values().iterator();
while (iterator.hasNext()) {
RemotePortForwarding forwarding = iterator.next();
turnOffRemotePortForwarding(forwarding);
iterator.remove();
}
}
public void disconnect(ExecutionManager executionManager) {
Iterator<RemotePortForwarding> iterator = remotePortForwardings.values().iterator();
while (iterator.hasNext()) {
RemotePortForwarding forwarding = iterator.next();
if (forwarding.owner == executionManager) {
turnOffRemotePortForwarding(forwarding);
iterator.remove();
}
}
}
/**
* Auxiliary method used by other methods to turn off a port forwarding.
*
* @param forwarding
* The port remote forwarding to be turned off.
*/
private void turnOffRemotePortForwarding(RemotePortForwarding forwarding) {
forwarding.releaseOwner();
try {
connection.getSession().delPortForwardingR(forwarding.remotePort);
} catch (JSchException e) {
// No possible exceptions are known.
assert false;
}
}
}