- Started with Web Protocol

This commit is contained in:
2025-09-25 23:40:24 +02:00
parent f30a2a1046
commit 1dbfad7947
30 changed files with 1389 additions and 141 deletions

View File

@@ -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);

View File

@@ -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;
}
}
}