Files
KLALB/src/org/kne/cloud/network/SocketToSocketProxy.java
T
2024-01-30 16:54:09 +08:00

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();
}
}
}