From 9c88395e7dc789034081665587fadbdc9de9aede Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Fri, 13 Dec 2024 20:05:11 +0100 Subject: [PATCH] Server --- .forgejo/workflows/build.yml | 24 ++++++ pom.xml | 46 ++++++++--- .../java/eu/m724/autopeerer/client/Main.java | 15 +++- .../autopeerer/client/MyWebsocketClient.java | 16 ---- .../m724/autopeerer/client/PacketHandler.java | 15 ++-- .../m724/autopeerer/common/packet/Packet.java | 17 +++++ .../{ => common}/packet/Packets.java | 16 ++-- .../packet/client/PingRequestPacket.java | 4 +- .../packet/client/SessionRequestPacket.java | 4 +- .../packet/server/PingResponsePacket.java | 6 +- .../packet/server/SessionResponsePacket.java | 6 +- .../eu/m724/autopeerer/packet/Packet.java | 10 --- .../m724/autopeerer/server/ClientState.java | 25 ++++++ .../java/eu/m724/autopeerer/server/Main.java | 13 ++++ .../autopeerer/server/MyWebsocketServer.java | 76 +++++++++++++++++++ .../m724/autopeerer/server/PacketHandler.java | 46 +++++++++++ 16 files changed, 278 insertions(+), 61 deletions(-) create mode 100644 .forgejo/workflows/build.yml create mode 100644 src/main/java/eu/m724/autopeerer/common/packet/Packet.java rename src/main/java/eu/m724/autopeerer/{ => common}/packet/Packets.java (69%) rename src/main/java/eu/m724/autopeerer/{ => common}/packet/client/PingRequestPacket.java (92%) rename src/main/java/eu/m724/autopeerer/{ => common}/packet/client/SessionRequestPacket.java (96%) rename src/main/java/eu/m724/autopeerer/{ => common}/packet/server/PingResponsePacket.java (92%) rename src/main/java/eu/m724/autopeerer/{ => common}/packet/server/SessionResponsePacket.java (92%) delete mode 100644 src/main/java/eu/m724/autopeerer/packet/Packet.java create mode 100644 src/main/java/eu/m724/autopeerer/server/ClientState.java create mode 100644 src/main/java/eu/m724/autopeerer/server/Main.java create mode 100644 src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java create mode 100644 src/main/java/eu/m724/autopeerer/server/PacketHandler.java diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..17793d8 --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,24 @@ +on: [push] +jobs: + deploy: + runs-on: docker + container: debian:sid + steps: + - name: Prepare for installation + run: apt update + + - name: Install JDK and other deps + run: apt install --no-install-recommends -y openjdk-21-jdk-headless git nodejs + + - name: Clone repository + run: git clone https://git.m724.eu/Minecon724/projetc3.git . + + - name: Build + run: mvn clean package + + - name: Upload artifacts + uses: https://github.com/actions/upload-artifact@v3 + with: + path: | + target/*-client.jar + target/*-server.jar \ No newline at end of file diff --git a/pom.xml b/pom.xml index ed4b8d4..e25da8f 100644 --- a/pom.xml +++ b/pom.xml @@ -33,24 +33,48 @@ org.apache.maven.plugins maven-shade-plugin 3.6.0 + + false + true + + + ** + + module-info.class + META-INF/ + + + + + shade-server package shade - false - true - - - ** - - module-info.class - META-INF/ - - - + ${project.artifactId}-${project.version}-server + + + eu.m724.autopeerer.server.Main + + + + + + shade-client + package + + shade + + + ${project.artifactId}-${project.version}-client + + + eu.m724.autopeerer.client.Main + + diff --git a/src/main/java/eu/m724/autopeerer/client/Main.java b/src/main/java/eu/m724/autopeerer/client/Main.java index 5faa6f0..28017c8 100644 --- a/src/main/java/eu/m724/autopeerer/client/Main.java +++ b/src/main/java/eu/m724/autopeerer/client/Main.java @@ -6,11 +6,22 @@ public class Main { public static void main(String[] args) throws InterruptedException { System.out.println("Hello world!"); - URI serverUri = URI.create("wss://echo.websocket.org/"); + URI serverUri = URI.create("ws://127.0.0.1:8002"); var packetHandler = new PacketHandler(); var client = new MyWebsocketClient(serverUri, packetHandler); - client.connectBlocking(); + var delay = 1000; + + while (true) { + var success = client.connectBlocking(); + System.out.println("Reconnecting"); + if (success) { + delay = 1000; + } else { + delay *= 2; + Thread.sleep(delay); + } + } } } \ No newline at end of file diff --git a/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java b/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java index a917f6e..f39061e 100644 --- a/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java +++ b/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java @@ -1,16 +1,9 @@ package eu.m724.autopeerer.client; -import eu.m724.autopeerer.packet.Packets; -import eu.m724.autopeerer.packet.client.PingRequestPacket; -import eu.m724.autopeerer.packet.client.SessionRequestPacket; -import inet.ipaddr.IPAddressString; -import inet.ipaddr.ipv6.IPv6Address; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; -import java.net.InetAddress; import java.net.URI; -import java.net.UnknownHostException; import java.nio.ByteBuffer; public class MyWebsocketClient extends WebSocketClient { @@ -33,15 +26,6 @@ public class MyWebsocketClient extends WebSocketClient { public void onOpen(ServerHandshake serverHandshake) { double connectTime = (System.nanoTime() - connectStart) / 1000000.0; System.out.printf("Connected in %.3f ms\n", connectTime); - - try { - send(Packets.compose(new PingRequestPacket((short)1, InetAddress.getByName("1.1.1.3")))); - send(Packets.compose(new PingRequestPacket((short)2, InetAddress.getByName("1.1.1.1")))); - - send(Packets.compose(new SessionRequestPacket((short)1, (IPv6Address) new IPAddressString("fefe::fefe").getAddress(), "sAt8JSXW4leihcAAdsghsfgFWkO5stBZJm87PGLZFXY=", "example.com", 6823))); - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } } @Override diff --git a/src/main/java/eu/m724/autopeerer/client/PacketHandler.java b/src/main/java/eu/m724/autopeerer/client/PacketHandler.java index c8ea039..06d5726 100644 --- a/src/main/java/eu/m724/autopeerer/client/PacketHandler.java +++ b/src/main/java/eu/m724/autopeerer/client/PacketHandler.java @@ -2,11 +2,12 @@ package eu.m724.autopeerer.client; import eu.m724.autopeerer.client.wireguard.WireGuardLive; import eu.m724.autopeerer.client.wireguard.WireGuardSession; -import eu.m724.autopeerer.packet.*; -import eu.m724.autopeerer.packet.client.PingRequestPacket; -import eu.m724.autopeerer.packet.client.SessionRequestPacket; -import eu.m724.autopeerer.packet.server.PingResponsePacket; -import eu.m724.autopeerer.packet.server.SessionResponsePacket; +import eu.m724.autopeerer.common.packet.Packet; +import eu.m724.autopeerer.common.packet.Packets; +import eu.m724.autopeerer.common.packet.client.PingRequestPacket; +import eu.m724.autopeerer.common.packet.client.SessionRequestPacket; +import eu.m724.autopeerer.common.packet.server.PingResponsePacket; +import eu.m724.autopeerer.common.packet.server.SessionResponsePacket; import java.io.BufferedReader; import java.io.File; @@ -80,7 +81,7 @@ public class PacketHandler { } System.out.printf("Ping request #%d to %s - %s avg %.3f / mdev %.3f ms\n", packet.requestId, packet.target.getHostAddress(), status, average, meanDeviation); - sender.accept(new PingResponsePacket(packet.requestId, status, average, meanDeviation).serialize()); + Packets.send(new PingResponsePacket(packet.requestId, status, average, meanDeviation), sender); }); } @@ -89,7 +90,7 @@ public class PacketHandler { try { wireGuardLive.saveSession(packet.sessionId, session); } catch (IOException e) { - // sender.accept(new SessionResponsePacket(packet.sessionId, )); + Packets.send(new SessionResponsePacket(packet.sessionId, SessionResponsePacket.SessionResult.ERROR, -1, null), sender); throw new RuntimeException(e); } } diff --git a/src/main/java/eu/m724/autopeerer/common/packet/Packet.java b/src/main/java/eu/m724/autopeerer/common/packet/Packet.java new file mode 100644 index 0000000..f61b3aa --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/common/packet/Packet.java @@ -0,0 +1,17 @@ +package eu.m724.autopeerer.common.packet; + +import java.nio.ByteBuffer; +import java.util.function.Consumer; + +public interface Packet> { + byte getId(); + + //T deserialize(ByteArrayInputStream inputStream) throws IOException; + + /** + * Serialize the packet's DATA into a ByteBuffer
+ * DON'T USE THIS TO SEND, USE {@link Packets#send(Packet, Consumer)} INSTEAD + * @return the DATA in a ByteBuffer + */ + ByteBuffer serialize(); +} diff --git a/src/main/java/eu/m724/autopeerer/packet/Packets.java b/src/main/java/eu/m724/autopeerer/common/packet/Packets.java similarity index 69% rename from src/main/java/eu/m724/autopeerer/packet/Packets.java rename to src/main/java/eu/m724/autopeerer/common/packet/Packets.java index c5ce3fc..ab757d1 100644 --- a/src/main/java/eu/m724/autopeerer/packet/Packets.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/Packets.java @@ -1,11 +1,12 @@ -package eu.m724.autopeerer.packet; +package eu.m724.autopeerer.common.packet; -import eu.m724.autopeerer.packet.client.PingRequestPacket; -import eu.m724.autopeerer.packet.client.SessionRequestPacket; -import eu.m724.autopeerer.packet.server.PingResponsePacket; -import eu.m724.autopeerer.packet.server.SessionResponsePacket; +import eu.m724.autopeerer.common.packet.client.PingRequestPacket; +import eu.m724.autopeerer.common.packet.client.SessionRequestPacket; +import eu.m724.autopeerer.common.packet.server.PingResponsePacket; +import eu.m724.autopeerer.common.packet.server.SessionResponsePacket; import java.nio.ByteBuffer; +import java.util.function.Consumer; public class Packets { public static Packet parseClient(ByteBuffer buffer) throws Exception { @@ -47,4 +48,9 @@ public class Packets { return bb; } + + public static void send(Packet packet, Consumer sender) { + sender.accept(compose(packet)); + } + } diff --git a/src/main/java/eu/m724/autopeerer/packet/client/PingRequestPacket.java b/src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java similarity index 92% rename from src/main/java/eu/m724/autopeerer/packet/client/PingRequestPacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java index c4c337f..88ece40 100644 --- a/src/main/java/eu/m724/autopeerer/packet/client/PingRequestPacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java @@ -1,6 +1,6 @@ -package eu.m724.autopeerer.packet.client; +package eu.m724.autopeerer.common.packet.client; -import eu.m724.autopeerer.packet.Packet; +import eu.m724.autopeerer.common.packet.Packet; import java.net.Inet6Address; import java.net.InetAddress; diff --git a/src/main/java/eu/m724/autopeerer/packet/client/SessionRequestPacket.java b/src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java similarity index 96% rename from src/main/java/eu/m724/autopeerer/packet/client/SessionRequestPacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java index 1739cc0..cf3288c 100644 --- a/src/main/java/eu/m724/autopeerer/packet/client/SessionRequestPacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java @@ -1,6 +1,6 @@ -package eu.m724.autopeerer.packet.client; +package eu.m724.autopeerer.common.packet.client; -import eu.m724.autopeerer.packet.Packet; +import eu.m724.autopeerer.common.packet.Packet; import inet.ipaddr.HostName; import inet.ipaddr.HostNameException; import inet.ipaddr.IPAddressString; diff --git a/src/main/java/eu/m724/autopeerer/packet/server/PingResponsePacket.java b/src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java similarity index 92% rename from src/main/java/eu/m724/autopeerer/packet/server/PingResponsePacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java index 478f311..87be440 100644 --- a/src/main/java/eu/m724/autopeerer/packet/server/PingResponsePacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java @@ -1,6 +1,6 @@ -package eu.m724.autopeerer.packet.server; +package eu.m724.autopeerer.common.packet.server; -import eu.m724.autopeerer.packet.Packet; +import eu.m724.autopeerer.common.packet.Packet; import java.nio.ByteBuffer; @@ -38,7 +38,7 @@ public class PingResponsePacket implements Packet { @Override public ByteBuffer serialize() { - var bb = ByteBuffer.allocate(9); + var bb = ByteBuffer.allocate(10); bb.putShort(requestId); switch (status) { case OK -> { diff --git a/src/main/java/eu/m724/autopeerer/packet/server/SessionResponsePacket.java b/src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java similarity index 92% rename from src/main/java/eu/m724/autopeerer/packet/server/SessionResponsePacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java index 345e25e..a33737a 100644 --- a/src/main/java/eu/m724/autopeerer/packet/server/SessionResponsePacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java @@ -1,6 +1,6 @@ -package eu.m724.autopeerer.packet.server; +package eu.m724.autopeerer.common.packet.server; -import eu.m724.autopeerer.packet.Packet; +import eu.m724.autopeerer.common.packet.Packet; import java.nio.ByteBuffer; import java.util.Base64; @@ -58,7 +58,7 @@ public class SessionResponsePacket implements Packet { return buffer; } - enum SessionResult { + public enum SessionResult { OK, ERROR } } diff --git a/src/main/java/eu/m724/autopeerer/packet/Packet.java b/src/main/java/eu/m724/autopeerer/packet/Packet.java deleted file mode 100644 index 2ba1ebe..0000000 --- a/src/main/java/eu/m724/autopeerer/packet/Packet.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.m724.autopeerer.packet; - -import java.nio.ByteBuffer; - -public interface Packet> { - byte getId(); - - //T deserialize(ByteArrayInputStream inputStream) throws IOException; - ByteBuffer serialize(); -} diff --git a/src/main/java/eu/m724/autopeerer/server/ClientState.java b/src/main/java/eu/m724/autopeerer/server/ClientState.java new file mode 100644 index 0000000..fbf6025 --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/server/ClientState.java @@ -0,0 +1,25 @@ +package eu.m724.autopeerer.server; + +import eu.m724.autopeerer.common.packet.Packet; +import eu.m724.autopeerer.common.packet.Packets; +import org.java_websocket.WebSocket; + +import java.nio.ByteBuffer; +import java.util.function.Consumer; + +public class ClientState { + public final int clientId; + public final WebSocket socket; + + private final Consumer sender; + + public ClientState(int clientId, WebSocket socket) { + this.clientId = clientId; + this.socket = socket; + this.sender = socket::send; + } + + void send(Packet packet) { + Packets.send(packet, sender); + } +} diff --git a/src/main/java/eu/m724/autopeerer/server/Main.java b/src/main/java/eu/m724/autopeerer/server/Main.java new file mode 100644 index 0000000..5bb008f --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/server/Main.java @@ -0,0 +1,13 @@ +package eu.m724.autopeerer.server; + +public class Main { + public static void main(String[] args) { + System.out.println("Hello world!"); + + var packetHandler = new PacketHandler(); + var client = new MyWebsocketServer(packetHandler); + + client.setDaemon(false); + client.start(); + } +} diff --git a/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java b/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java new file mode 100644 index 0000000..7b2b2ec --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java @@ -0,0 +1,76 @@ +package eu.m724.autopeerer.server; + +import eu.m724.autopeerer.common.packet.client.PingRequestPacket; +import eu.m724.autopeerer.common.packet.client.SessionRequestPacket; +import inet.ipaddr.IPAddressString; +import org.java_websocket.WebSocket; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.server.WebSocketServer; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +public class MyWebsocketServer extends WebSocketServer { + private final PacketHandler packetHandler; + private final Map states = new HashMap<>(); + + private int id = 0; + + public MyWebsocketServer(PacketHandler packetHandler) { + super(new InetSocketAddress("127.0.0.1", 8002)); + this.setReuseAddr(true); + this.packetHandler = packetHandler; + } + + @Override + public void onOpen(WebSocket conn, ClientHandshake handshake) { + var state = new ClientState(++id, conn); + states.put(conn, state); + System.out.printf("[%d] Connected: %s\n", id, conn.getRemoteSocketAddress().getHostString()); + + // TODO testing + try { + state.send(new PingRequestPacket((short) 1, InetAddress.getByName("1.1.1.1"))); + state.send(new PingRequestPacket((short) 2, InetAddress.getByName("1.1.1.2"))); + + state.send(new SessionRequestPacket( + (short) 1, + new IPAddressString("fe80::dead:fed").getAddress().toIPv6(), + "somepk", + "end.point", + 51820 + )); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } + } + + @Override + public void onClose(WebSocket conn, int code, String reason, boolean remote) { + var state = states.remove(conn); + System.out.printf("[%d] Disconnected: %s\n", state.clientId, conn.getRemoteSocketAddress().getHostString()); + } + + @Override + public void onMessage(WebSocket conn, ByteBuffer message) { + packetHandler.handle(states.get(conn), message); + } + + @Override + public void onError(WebSocket conn, Exception ex) { + ex.printStackTrace(); + } + + @Override + public void onStart() { + System.out.printf("Websocket server started on %s:%d\n", getAddress().getHostString(), getPort()); + } + + @Override + public void onMessage(WebSocket conn, String message) { + } +} diff --git a/src/main/java/eu/m724/autopeerer/server/PacketHandler.java b/src/main/java/eu/m724/autopeerer/server/PacketHandler.java new file mode 100644 index 0000000..f348d14 --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/server/PacketHandler.java @@ -0,0 +1,46 @@ +package eu.m724.autopeerer.server; + +import eu.m724.autopeerer.common.packet.Packet; +import eu.m724.autopeerer.common.packet.Packets; +import eu.m724.autopeerer.common.packet.server.PingResponsePacket; +import eu.m724.autopeerer.common.packet.server.SessionResponsePacket; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.util.Base64; + +public class PacketHandler { + void handle(ClientState state, ByteBuffer bytes) { + // TODO this is not safe but enough for now + Packet p; + try { + p = Packets.parseServer(bytes); + } catch (BufferUnderflowException e) { + bytes.rewind(); + byte[] bytez = new byte[bytes.remaining()]; + bytes.get(bytez); + + System.err.println("Received too short packet"); + System.err.println("> Length: " + bytez.length); + System.err.println("> Packet: " + Base64.getEncoder().encodeToString(bytez)); + + return; + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (p instanceof PingResponsePacket packet) { + handlePingResponse(state, packet); + } else if (p instanceof SessionResponsePacket packet) { + handleSessionResponse(state, packet); + } + } + + private void handlePingResponse(ClientState state, PingResponsePacket packet) { + System.out.printf("[%d] Ping response #%d: %s avg %.3f / mdev %.3f ms\n", state.clientId, packet.requestId, packet.status, packet.average, packet.meanDeviation); + } + + private void handleSessionResponse(ClientState state, SessionResponsePacket packet) { + System.out.printf("[%d] Session response #%d: %s\n", state.clientId, packet.sessionId, packet.result); + } +}