- Started with Web Protocol
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
package org.openautonomousconnection.protocol.side.client;
|
||||
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.exceptions.UnsupportedProtocolException;
|
||||
import org.openautonomousconnection.protocol.packets.OACPacket;
|
||||
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.GetDestinationPacket;
|
||||
import org.openautonomousconnection.protocol.packets.v1_0_0.beta.ValidateDomainPacket;
|
||||
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_DomainPacket;
|
||||
import org.openautonomousconnection.protocol.packets.v1_0_0.classic.Classic_PingPacket;
|
||||
import org.openautonomousconnection.protocol.versions.ProtocolVersion;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.DNSResponseCode;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.Domain;
|
||||
@@ -11,10 +15,14 @@ import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
|
||||
import dev.unlegitdqrk.unlegitlibrary.network.system.client.events.ClientDisconnectedEvent;
|
||||
import dev.unlegitdqrk.unlegitlibrary.network.utils.NetworkUtils;
|
||||
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.ClassicConverter;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.Classic_Domain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.Classic_RequestDomain;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
@@ -55,22 +63,41 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final NetworkClient networkClient;
|
||||
private final NetworkClient clientToDNS; // Handles everything with DNS-Connection
|
||||
private WebClient webClient;
|
||||
|
||||
private ProtocolVersion serverVersion = null;
|
||||
@Getter
|
||||
private final ClientCertificateFolderStructure folderStructure;
|
||||
|
||||
public final NetworkClient getClientDNSConnection() {
|
||||
return clientToDNS;
|
||||
}
|
||||
|
||||
public ProtocolClient() throws CertificateException, IOException {
|
||||
folderStructure = new ClientCertificateFolderStructure();
|
||||
|
||||
networkClient = new NetworkClient.ClientBuilder().setLogger(ProtocolBridge.getInstance().getLogger()).
|
||||
clientToDNS = new NetworkClient.ClientBuilder().setLogger(ProtocolBridge.getInstance().getLogger()).
|
||||
setHost(ProtocolBridge.getInstance().getProtocolSettings().host).setPort(ProtocolBridge.getInstance().getProtocolSettings().port).
|
||||
setPacketHandler(ProtocolBridge.getInstance().getProtocolSettings().packetHandler).setEventManager(ProtocolBridge.getInstance().getProtocolSettings().eventManager).
|
||||
setRootCAFolder(folderStructure.publicCAFolder).setClientCertificatesFolder(folderStructure.publicClientFolder, folderStructure.privateClientFolder).
|
||||
build();
|
||||
}
|
||||
|
||||
public final void createWebConnection(Domain domain, int pipelinePort, int webPort) throws Exception {
|
||||
if (!ProtocolBridge.getInstance().isProtocolSupported(ProtocolVersion.Protocol.OAC)) throw new UnsupportedProtocolException();
|
||||
|
||||
if (webClient != null) {
|
||||
try {
|
||||
webClient.closeConnection();
|
||||
} catch (IOException e) {
|
||||
ProtocolBridge.getInstance().getLogger().exception("Failed to close connection to web server", e);
|
||||
}
|
||||
}
|
||||
|
||||
webClient = new WebClient(domain, pipelinePort, webPort);
|
||||
}
|
||||
|
||||
private final void checkFileExists(File folder, String prefix, String extension) throws CertificateException, IOException {
|
||||
boolean found = false;
|
||||
if (folder == null) throw new FileNotFoundException("Folder does not exist");
|
||||
@@ -94,15 +121,22 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
if (serverVersion == null) this.serverVersion = serverVersion;
|
||||
}
|
||||
|
||||
public final void onDisconnect(ClientDisconnectedEvent event) {
|
||||
public final void onDNSDisconnect(ClientDisconnectedEvent event) {
|
||||
serverVersion = null;
|
||||
if (webClient != null) {
|
||||
try {
|
||||
webClient.closeConnection();
|
||||
} catch (IOException e) {
|
||||
ProtocolBridge.getInstance().getLogger().exception("Failed to close connection to web server", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isStableServer() {
|
||||
return !isBetaServer() && !isClassicServer();
|
||||
}
|
||||
|
||||
public final boolean serverSupportStable() {
|
||||
public final boolean supportServerStable() {
|
||||
boolean yes = false;
|
||||
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
|
||||
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.STABLE;
|
||||
@@ -116,7 +150,7 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.BETA;
|
||||
}
|
||||
|
||||
public final boolean serverSupportBeta() {
|
||||
public final boolean supportServerBeta() {
|
||||
boolean yes = false;
|
||||
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
|
||||
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.BETA;
|
||||
@@ -130,7 +164,7 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
return getServerVersion().getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
|
||||
}
|
||||
|
||||
public final boolean serverSupportClassic() {
|
||||
public final boolean supportServerClassic() {
|
||||
boolean yes = false;
|
||||
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
|
||||
yes = compatibleVersion.getProtocolType() == ProtocolVersion.ProtocolType.CLASSIC;
|
||||
@@ -140,16 +174,34 @@ public abstract class ProtocolClient extends DefaultMethodsOverrider {
|
||||
return isClassicServer() || yes;
|
||||
}
|
||||
|
||||
public final boolean isPacketSupported(OACPacket packet) {
|
||||
return isVersionSupported(packet.getProtocolVersion());
|
||||
public final boolean supportServerPacket(OACPacket packet) {
|
||||
return supportServerVersion(packet.getProtocolVersion());
|
||||
}
|
||||
|
||||
public final boolean isVersionSupported(ProtocolVersion targetVersion) {
|
||||
public final boolean supportServerVersion(ProtocolVersion targetVersion) {
|
||||
return getServerVersion() == targetVersion || getServerVersion().getCompatibleVersions().contains(targetVersion);
|
||||
}
|
||||
|
||||
public final boolean supportServerProtocol(ProtocolVersion.Protocol protocol) {
|
||||
boolean yes = false;
|
||||
for (ProtocolVersion compatibleVersion : getServerVersion().getCompatibleVersions()) {
|
||||
yes = compatibleVersion.getSupportedProtocols().contains(protocol);
|
||||
if (yes) break;
|
||||
}
|
||||
|
||||
return getServerVersion().getSupportedProtocols().contains(protocol) || yes;
|
||||
}
|
||||
|
||||
public final void validateDomain(Domain domain) throws IOException, ClassNotFoundException {
|
||||
networkClient.sendPacket(new ValidateDomainPacket(domain));
|
||||
Classic_PingPacket cPingPacket = new Classic_PingPacket(new Classic_RequestDomain(domain.getName(), domain.getTopLevelName(), domain.getPath()), null, false);
|
||||
if (ProtocolBridge.getInstance().isPacketSupported(cPingPacket)) clientToDNS.sendPacket(cPingPacket);
|
||||
clientToDNS.sendPacket(new ValidateDomainPacket(domain));
|
||||
}
|
||||
|
||||
public final void requestDestination(Domain domain, DNSResponseCode responseCode) throws IOException, ClassNotFoundException {
|
||||
Classic_DomainPacket cDomainPacket = new Classic_DomainPacket(0, new Classic_RequestDomain(domain.getName(), domain.getTopLevelName(), domain.getPath()), null);
|
||||
if (ProtocolBridge.getInstance().isPacketSupported(cDomainPacket)) clientToDNS.sendPacket(cDomainPacket);
|
||||
clientToDNS.sendPacket(new GetDestinationPacket(domain, responseCode));
|
||||
}
|
||||
|
||||
public abstract void validationCompleted(Domain domain, DNSResponseCode responseCode);
|
||||
|
@@ -0,0 +1,136 @@
|
||||
package org.openautonomousconnection.protocol.side.client;
|
||||
|
||||
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
|
||||
import dev.unlegitdqrk.unlegitlibrary.network.system.client.events.*;
|
||||
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
|
||||
import lombok.Getter;
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.Domain;
|
||||
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
|
||||
public final class WebClient {
|
||||
private final NetworkClient clientToWebPipeline; // Handles everything with Pipeline-Connection
|
||||
private SSLSocket clientToWebServer; // Handles everything with Web-Connection
|
||||
|
||||
private final Thread receiveThread = new Thread(this::receive);
|
||||
private ObjectOutputStream outputStream;
|
||||
private ObjectInputStream inputStream;
|
||||
|
||||
public final NetworkClient getClientPipelineConnection() {
|
||||
return clientToWebPipeline;
|
||||
}
|
||||
|
||||
public final SSLSocket getClientWebConnection() {
|
||||
return clientToWebServer;
|
||||
}
|
||||
|
||||
public WebClient(Domain domain, int pipelinePort, int webPort) throws Exception {
|
||||
clientToWebPipeline = new NetworkClient.ClientBuilder().setLogger(ProtocolBridge.getInstance().getLogger()).
|
||||
setHost(domain.getDestination()).setPort(pipelinePort).
|
||||
setPacketHandler(ProtocolBridge.getInstance().getProtocolSettings().packetHandler).setEventManager(ProtocolBridge.getInstance().getProtocolSettings().eventManager).
|
||||
setRootCAFolder(ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().publicCAFolder).setClientCertificatesFolder(ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().publicClientFolder, ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().privateClientFolder).
|
||||
build();
|
||||
|
||||
clientToWebPipeline.connect();
|
||||
|
||||
while (!clientToWebPipeline.isConnected()) if (clientToWebPipeline.isConnected()) break;
|
||||
|
||||
SSLSocketFactory sslSocketFactory = NetworkClient.ClientBuilder.createSSLSocketFactory(ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().publicCAFolder, ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().publicClientFolder, ProtocolBridge.getInstance().getProtocolClient().getFolderStructure().privateClientFolder);
|
||||
Proxy proxy = clientToWebPipeline.getProxy();
|
||||
SSLSocket tempSocket;
|
||||
if (sslSocketFactory == null) {
|
||||
throw new ConnectException("SSL socket factory not set. Client certificate required!");
|
||||
} else {
|
||||
if (proxy != null) {
|
||||
Socket rawSocket = new Socket(proxy);
|
||||
rawSocket.connect(new InetSocketAddress(domain.getDestination(), webPort), 0);
|
||||
tempSocket = (SSLSocket)sslSocketFactory.createSocket(rawSocket, domain.getDestination(), webPort, true);
|
||||
} else {
|
||||
tempSocket = (SSLSocket)sslSocketFactory.createSocket(domain.getDestination(), webPort);
|
||||
}
|
||||
|
||||
clientToWebServer = tempSocket;
|
||||
SSLParameters sslParameters = clientToWebPipeline.getSocket().getSSLParameters();
|
||||
|
||||
if (sslParameters != null) {
|
||||
clientToWebServer.setSSLParameters(sslParameters);
|
||||
} else {
|
||||
SSLParameters defaultParams = clientToWebServer.getSSLParameters();
|
||||
defaultParams.setProtocols(new String[]{"TLSv1.3"});
|
||||
clientToWebServer.setSSLParameters(defaultParams);
|
||||
}
|
||||
|
||||
clientToWebServer.setTcpNoDelay(true);
|
||||
clientToWebServer.setSoTimeout(0);
|
||||
|
||||
try {
|
||||
this.clientToWebServer.startHandshake();
|
||||
} catch (Exception handshakeEx) {
|
||||
throw new ConnectException("Handshake failed: " + handshakeEx.getMessage());
|
||||
}
|
||||
|
||||
this.outputStream = new ObjectOutputStream(clientToWebServer.getOutputStream());
|
||||
this.inputStream = new ObjectInputStream(clientToWebServer.getInputStream());
|
||||
this.receiveThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
public final boolean isConnected() {
|
||||
return this.clientToWebServer != null && this.clientToWebServer.isConnected() && !this.clientToWebServer.isClosed()
|
||||
&& this.receiveThread.isAlive() && !this.receiveThread.isInterrupted() &&
|
||||
ProtocolBridge.getInstance().getProtocolClient().getClientDNSConnection().isConnected() && clientToWebPipeline.isConnected();
|
||||
}
|
||||
|
||||
private void receive() {
|
||||
try {
|
||||
while(this.isConnected()) {
|
||||
Object received = this.inputStream.readObject();
|
||||
}
|
||||
} catch (Exception var2) {
|
||||
try {
|
||||
this.closeConnection();
|
||||
} catch (IOException exception) {
|
||||
ProtocolBridge.getInstance().getLogger().exception("Failed to close connection to web server", var2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized final boolean closeConnection() throws IOException {
|
||||
if (!this.isConnected()) {
|
||||
return false;
|
||||
} else {
|
||||
clientToWebPipeline.disconnect();
|
||||
|
||||
try {
|
||||
this.receiveThread.interrupt();
|
||||
if (this.outputStream != null) {
|
||||
this.outputStream.close();
|
||||
}
|
||||
|
||||
if (this.inputStream != null) {
|
||||
this.inputStream.close();
|
||||
}
|
||||
|
||||
if (this.clientToWebServer != null) {
|
||||
this.clientToWebServer.close();
|
||||
}
|
||||
} finally {
|
||||
this.clientToWebServer = null;
|
||||
this.outputStream = null;
|
||||
this.inputStream = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user