package org.kne.cloud.network; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Map; public class SocketToSocketProxy extends Proxy { private SocketListener sl; private DatagramSocketListener dsl; private MultipurposeSocketAddress listen, cbind, defaultConnect; private Map detectedConnect; public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress connect) throws IOException { this(listen, new MultipurposeSocketAddress(new InetSocketAddress(0)), connect); } public SocketToSocketProxy(String l, String r) throws IOException { this(new MultipurposeSocketAddress(l), new MultipurposeSocketAddress(r)); } public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind, MultipurposeSocketAddress defaultConnect, Map detectedConnect) throws IOException { this.listen = listen; this.cbind = cbind; this.defaultConnect = defaultConnect; this.detectedConnect = detectedConnect; open(); } public SocketToSocketProxy(MultipurposeSocketAddress listen, MultipurposeSocketAddress cbind, MultipurposeSocketAddress defaultConnect) throws IOException { this(listen, cbind, defaultConnect,null); } private void open() throws IOException { if (listen.isStream()) { if (detectedConnect == null || detectedConnect.isEmpty()) { sl = new SocketListener(listen); } else { sl = new SocketListener(new ProtocolDetectorServerSocket(listen.listenServerSocket())); } sl.setCon((sox) -> { Socket sk = null; try { if (sox instanceof ProtocolDetectorSocket) { ProtocolStack ps = ((ProtocolDetectorSocket) sox).getProtocolStack(); if (!ps.isEmpty()) { MultipurposeSocketAddress pmsa = detectedConnect.get(ps.pop().getName()); if(pmsa!=null) { sk = pmsa.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort()); }else { sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort()); } } else { sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort()); } } else { sk = defaultConnect.connectSocket(InetAddress.getByName(cbind.getHost()), cbind.getPort()); } runBridge(sox,sk); } catch (IOException e) { e.printStackTrace(); } finally { if (sk != null) try { sk.close(); } catch (IOException e) { e.printStackTrace(); } try { sox.close(); } catch (IOException e) { e.printStackTrace(); } } }); } else { dsl = new DatagramSocketListener(listen); dsl.setCon((dox) -> { }); } } protected void runBridge(Socket sk, Socket sox) throws IOException { SocketBridge sb = new SocketBridge(sk, sox); sb.run(); } public MultipurposeSocketAddress getListen() { return listen; } public MultipurposeSocketAddress getCbind() { return cbind; } public MultipurposeSocketAddress getDefaultConnect() { return defaultConnect; } @Override public void close() throws IOException { if (dsl != null) dsl.close(); if (sl != null) sl.close(); } public InetAddress getListenAddress() { if (sl != null) { return sl.getServerSocket().getInetAddress(); } else { return dsl.getDatagramServerSocket().getLocalAddress(); } } public int getListenPort() { if (sl != null) { return sl.getServerSocket().getLocalPort(); } else { return dsl.getDatagramServerSocket().getLocalPort(); } } }