forked from KNEMC/KLALB
131 lines
3.7 KiB
Java
131 lines
3.7 KiB
Java
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<String, MultipurposeSocketAddress> 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<String, MultipurposeSocketAddress> 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();
|
|
}
|
|
}
|
|
}
|