All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.mycontainer.util.tunnel.Tunnel Maven / Gradle / Ivy

The newest version!
package com.googlecode.mycontainer.util.tunnel;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;

import com.googlecode.mycontainer.util.Util;
import com.googlecode.mycontainer.util.log.Log;

public class Tunnel implements Closeable {

	private static Log LOG = Log.get(Tunnel.class);

	private String localHost;
	private int localPort;
	private String remoteHost;
	private int remotePort;
	private ServerSocket serverSocket;
	private final List connections = new ArrayList();

	public Tunnel() {

	}

	public Tunnel(String localHost, int localPort, String remoteHost, int remotePort) {
		this.localHost = localHost;
		this.localPort = localPort;
		this.remoteHost = remoteHost;
		this.remotePort = remotePort;
	}

	public String getLocalHost() {
		return localHost;
	}

	public Tunnel setLocalHost(String localHost) {
		this.localHost = localHost;
		return this;
	}

	public int getLocalPort() {
		return localPort;
	}

	public Tunnel setLocalPort(int localPort) {
		this.localPort = localPort;
		return this;
	}

	public String getRemoteHost() {
		return remoteHost;
	}

	public Tunnel setRemoteHost(String remoteHost) {
		this.remoteHost = remoteHost;
		return this;
	}

	public int getRemotePort() {
		return remotePort;
	}

	public Tunnel setRemotePort(int remotePort) {
		this.remotePort = remotePort;
		return this;
	}

	public void bind() {
		try {
			InetAddress address = InetAddress.getByName(localHost);
			this.serverSocket = ServerSocketFactory.getDefault().createServerSocket(localPort, 50, address);
			this.localPort = serverSocket.getLocalPort();
			this.serverSocket.setSoTimeout(1);
			LOG.info("Bound " + this);
		} catch (UnknownHostException e) {
			throw new RuntimeException(e);
		} catch (SocketException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public String toString() {
		return "[Tunnel " + localHost + ":" + localPort + " " + remoteHost + ":" + remotePort + "]";
	}

	public void close() {
		LOG.info("Closing " + this);
		Util.close(serverSocket);
		for (TunnelConnection conn : connections) {
			Util.close(conn);
		}
	}

	public boolean isClosed() {
		return false;
	}

	public void accepts(TunnelHandler handler) {
		boolean error = true;
		Socket local = null;
		Socket remote = null;
		try {
			local = serverAccept();
			if (local == null) {
				return;
			}
			TunnelConnection socketTunnel = new TunnelConnection();
			socketTunnel.setLocal(local);
			local.setSoTimeout(1);
			remote = SocketFactory.getDefault().createSocket();
			remote.connect(new InetSocketAddress(remoteHost, remotePort), 30000);
			remote.setSoTimeout(1);
			socketTunnel.setRemote(remote);
			this.connections.add(socketTunnel);
			handler.connected(socketTunnel);
			error = false;
		} catch (UnknownHostException e) {
			LOG.error("error connecting", e);
		} catch (IOException e) {
			LOG.error("error connecting", e);
		} finally {
			if (error) {
				Util.close(local);
				Util.close(remote);
			}
		}
	}

	private Socket serverAccept() {
		try {
			return serverSocket.accept();
		} catch (SocketTimeoutException e) {
			return null;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public void read(TunnelHandler handler) {
		Iterator it = connections.iterator();
		while (it.hasNext()) {
			TunnelConnection conn = it.next();
			if (conn.isStopped()) {
				it.remove();
				Util.close(conn);
				handler.disconnected(conn);
				continue;
			}
			conn.readData();
			if (conn.hasBuffer()) {
				handler.data(conn);
			}
		}
	}

	public List getConnections() {
		return Collections.unmodifiableList(connections);
	}

	public void closeFinisheds() {
		Iterator it = connections.iterator();
		while (it.hasNext()) {
			TunnelConnection conn = it.next();
			TunnelData localData = conn.getLocalData();
			TunnelData remoteData = conn.getRemoteData();
			if (localData.isStopped() || remoteData.isStopped()) {
				if (!localData.hasBuffer() && !remoteData.hasBuffer()) {
					Util.close(conn);
				}
			}
		}
	}

	public static Tunnel parse(String str) {
		String[] array = str.split(":");
		String localhost = "127.0.0.1";
		int j = 0;
		if (array.length >= 4) {
			localhost = array[j++];
		}
		int localport = Integer.parseInt(array[j++]);
		String remotehost = array[j++];
		int remoteport = Integer.parseInt(array[j++]);
		Tunnel tunnel = new Tunnel(localhost, localport, remotehost, remoteport);
		return tunnel;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy