diff --git a/src/main/java/eu/m724/autopeerer/client/ClientConfiguration.java b/src/main/java/eu/m724/autopeerer/client/ClientConfiguration.java new file mode 100644 index 0000000..eb18a1f --- /dev/null +++ b/src/main/java/eu/m724/autopeerer/client/ClientConfiguration.java @@ -0,0 +1,9 @@ +package eu.m724.autopeerer.client; + +import eu.m724.autopeerer.common.Configuration; + +public class ClientConfiguration extends Configuration { + public ClientConfiguration() { + super("client"); + } +} diff --git a/src/main/java/eu/m724/autopeerer/client/Main.java b/src/main/java/eu/m724/autopeerer/client/Main.java index 28017c8..1a4c2f6 100644 --- a/src/main/java/eu/m724/autopeerer/client/Main.java +++ b/src/main/java/eu/m724/autopeerer/client/Main.java @@ -1,27 +1,28 @@ package eu.m724.autopeerer.client; +import eu.m724.autopeerer.client.wireguard.WireGuardLive; + +import java.io.File; +import java.io.IOException; import java.net.URI; public class Main { public static void main(String[] args) throws InterruptedException { System.out.println("Hello world!"); - URI serverUri = URI.create("ws://127.0.0.1:8002"); + var config = new ClientConfiguration(); + try { + config.load(); + } catch (IOException e) { + throw new RuntimeException("Failed to load configuration", e); + } - var packetHandler = new PacketHandler(); + URI serverUri = URI.create(config.getString("remote")); + + var wireGuardLive = new WireGuardLive(new File(config.getString("wireguard.directory"))); + var packetHandler = new PacketHandler(wireGuardLive); var client = new MyWebsocketClient(serverUri, packetHandler); - var delay = 1000; - - while (true) { - var success = client.connectBlocking(); - System.out.println("Reconnecting"); - if (success) { - delay = 1000; - } else { - delay *= 2; - Thread.sleep(delay); - } - } + client.connect(); } } \ 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 039b76e..316312d 100644 --- a/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java +++ b/src/main/java/eu/m724/autopeerer/client/MyWebsocketClient.java @@ -1,7 +1,7 @@ package eu.m724.autopeerer.client; import eu.m724.autopeerer.common.packet.Packets; -import eu.m724.autopeerer.common.packet.client.LoginPacket; +import eu.m724.autopeerer.common.packet.c2s.LoginPacket; import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; diff --git a/src/main/java/eu/m724/autopeerer/client/PacketHandler.java b/src/main/java/eu/m724/autopeerer/client/PacketHandler.java index 1225ada..c979700 100644 --- a/src/main/java/eu/m724/autopeerer/client/PacketHandler.java +++ b/src/main/java/eu/m724/autopeerer/client/PacketHandler.java @@ -1,27 +1,32 @@ package eu.m724.autopeerer.client; +import eu.m724.autopeerer.client.wireguard.WireGuardKeys; import eu.m724.autopeerer.client.wireguard.WireGuardLive; import eu.m724.autopeerer.client.wireguard.WireGuardSession; 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 eu.m724.autopeerer.common.packet.c2s.PingRequestPacket; +import eu.m724.autopeerer.common.packet.c2s.SessionRequestPacket; +import eu.m724.autopeerer.common.packet.s2c.PingResponsePacket; +import eu.m724.autopeerer.common.packet.s2c.SessionResponsePacket; import java.io.BufferedReader; -import java.io.File; import java.io.IOException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; +import java.nio.file.FileAlreadyExistsException; import java.util.Base64; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; public class PacketHandler { Consumer sender; - // TODO not here - private final WireGuardLive wireGuardLive = new WireGuardLive(new File("configs")); + + private final WireGuardLive wireGuardLive; + + public PacketHandler(WireGuardLive wireGuardLive) { + this.wireGuardLive = wireGuardLive; + } void handle(ByteBuffer bytes) { Packet p; @@ -84,9 +89,19 @@ public class PacketHandler { } private void handleVpnRequest(SessionRequestPacket packet) { - var session = new WireGuardSession(12345, "serverpoecjteta", "fefe:fefe::fefe", packet.linkLocal.toCompressedString(), packet.endpointHost + ":" + packet.endpointPort, packet.publicKey); + var privateKey = WireGuardKeys.generatePrivateKey(); + var publicKey = WireGuardKeys.derivePublicKey(privateKey); + + // TODO fill port and link local + var session = new WireGuardSession(12345, privateKey, "fefe:fefe::fefe", packet.linkLocal.toCompressedString(), packet.endpointHost + ":" + packet.endpointPort, packet.publicKey); + try { wireGuardLive.saveSession(packet.sessionId, session); + System.out.printf("Created session #%d to %s\n", packet.sessionId, packet.endpointHost); + Packets.send(new SessionResponsePacket(packet.sessionId, SessionResponsePacket.SessionResult.OK, session.listenPort(), publicKey), sender); + } catch (FileAlreadyExistsException e) { + System.err.println("Tried to create a session which already exists: #" + packet.sessionId); + Packets.send(new SessionResponsePacket(packet.sessionId, SessionResponsePacket.SessionResult.ERROR, -1, null), sender); } catch (IOException e) { 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/client/wireguard/WireGuardLive.java b/src/main/java/eu/m724/autopeerer/client/wireguard/WireGuardLive.java index 2bd4227..a83a63b 100644 --- a/src/main/java/eu/m724/autopeerer/client/wireguard/WireGuardLive.java +++ b/src/main/java/eu/m724/autopeerer/client/wireguard/WireGuardLive.java @@ -2,27 +2,30 @@ package eu.m724.autopeerer.client.wireguard; import java.io.*; import java.nio.file.Files; +import java.nio.file.StandardOpenOption; public class WireGuardLive { private final File configsPath; public WireGuardLive(File configsPath) { + System.out.println(configsPath.getAbsolutePath()); this.configsPath = configsPath; } - public void saveSession(int connectionId, WireGuardSession session) throws IOException { - File file = new File(configsPath, "ap_" + connectionId + ".conf"); - file.createNewFile(); - - try (FileWriter writer = new FileWriter(file)) { - writer.write(session.config()); - } + public void saveSession(int sessionId, WireGuardSession session) throws IOException { + File file = new File(configsPath, "ap_" + sessionId + ".conf"); + Files.writeString(file.toPath(), session.config(), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); } - public WireGuardSession getSession(int connectionId) throws IOException { - File file = new File(configsPath, "ap_" + connectionId + ".conf"); + public WireGuardSession getSession(int sessionId) throws IOException { + File file = new File(configsPath, "ap_" + sessionId + ".conf"); String s = Files.readString(file.toPath()); return WireGuardSession.fromString(s); } + + public boolean existsSession(int sessionId) { + File file = new File(configsPath, "ap_" + sessionId + ".conf"); + return file.exists(); + } } diff --git a/src/main/java/eu/m724/autopeerer/common/packet/Packets.java b/src/main/java/eu/m724/autopeerer/common/packet/Packets.java index fd3594b..1681b50 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/Packets.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/Packets.java @@ -1,11 +1,11 @@ package eu.m724.autopeerer.common.packet; -import eu.m724.autopeerer.common.packet.client.LoginPacket; -import eu.m724.autopeerer.common.packet.client.PingRequestPacket; -import eu.m724.autopeerer.common.packet.client.SessionRequestPacket; -import eu.m724.autopeerer.common.packet.server.LoginResponsePacket; -import eu.m724.autopeerer.common.packet.server.PingResponsePacket; -import eu.m724.autopeerer.common.packet.server.SessionResponsePacket; +import eu.m724.autopeerer.common.packet.c2s.LoginPacket; +import eu.m724.autopeerer.common.packet.c2s.PingRequestPacket; +import eu.m724.autopeerer.common.packet.c2s.SessionRequestPacket; +import eu.m724.autopeerer.common.packet.s2c.LoginResponsePacket; +import eu.m724.autopeerer.common.packet.s2c.PingResponsePacket; +import eu.m724.autopeerer.common.packet.s2c.SessionResponsePacket; import java.nio.ByteBuffer; import java.util.function.Consumer; diff --git a/src/main/java/eu/m724/autopeerer/common/packet/client/LoginPacket.java b/src/main/java/eu/m724/autopeerer/common/packet/c2s/LoginPacket.java similarity index 92% rename from src/main/java/eu/m724/autopeerer/common/packet/client/LoginPacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/c2s/LoginPacket.java index 31bbfd4..30075ee 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/client/LoginPacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/c2s/LoginPacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.client; +package eu.m724.autopeerer.common.packet.c2s; import eu.m724.autopeerer.common.packet.Packet; diff --git a/src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java b/src/main/java/eu/m724/autopeerer/common/packet/c2s/PingRequestPacket.java similarity index 96% rename from src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/c2s/PingRequestPacket.java index 88ece40..c1432c7 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/client/PingRequestPacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/c2s/PingRequestPacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.client; +package eu.m724.autopeerer.common.packet.c2s; import eu.m724.autopeerer.common.packet.Packet; diff --git a/src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java b/src/main/java/eu/m724/autopeerer/common/packet/c2s/SessionRequestPacket.java similarity index 81% rename from src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/c2s/SessionRequestPacket.java index cf3288c..28520af 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/client/SessionRequestPacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/c2s/SessionRequestPacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.client; +package eu.m724.autopeerer.common.packet.c2s; import eu.m724.autopeerer.common.packet.Packet; import inet.ipaddr.HostName; @@ -17,8 +17,9 @@ public class SessionRequestPacket implements Packet { public final String publicKey; public final String endpointHost; public final int endpointPort; + public final long asn; - public SessionRequestPacket(short sessionId, IPv6Address linkLocal, String publicKey, String endpointHost, int endpointPort) { + public SessionRequestPacket(short sessionId, IPv6Address linkLocal, String publicKey, String endpointHost, int endpointPort, long asn) { this.sessionId = sessionId; this.linkLocal = linkLocal; @@ -36,6 +37,9 @@ public class SessionRequestPacket implements Packet { this.endpointPort = endpointPort; assert endpointPort > 0 && endpointPort < 65536; + + this.asn = asn; + assert asn < 0xFFFFFFFFL; } @Override @@ -54,26 +58,29 @@ public class SessionRequestPacket implements Packet { buffer.get(pk); var publicKey = Base64.getEncoder().encodeToString(pk); - var endpointPort = buffer.getShort(); + var endpointPort = buffer.getShort() & 0xFFFF; var epl = buffer.get() & 0xFF; var ep = new byte[epl]; buffer.get(ep); var endpointHost = new String(ep, StandardCharsets.US_ASCII); - return new SessionRequestPacket(id, linkLocal, publicKey, endpointHost, endpointPort); + var asn = Integer.toUnsignedLong(buffer.getInt()); + + return new SessionRequestPacket(id, linkLocal, publicKey, endpointHost, endpointPort, asn); } @Override public ByteBuffer serialize() { - var buffer = ByteBuffer.allocate(53 + endpointHost.length()); + var buffer = ByteBuffer.allocate(57 + endpointHost.length()); buffer.putShort(sessionId); // 2b buffer.put(linkLocal.getBytes()); // 16b buffer.put(Base64.getDecoder().decode(publicKey)); // 32b - buffer.putShort((short)endpointPort); // 2b + buffer.putShort((short) endpointPort); // 2b buffer.put((byte) endpointHost.length()); // 1b buffer.put(endpointHost.getBytes(StandardCharsets.US_ASCII)); + buffer.putInt((int) asn); return buffer; } diff --git a/src/main/java/eu/m724/autopeerer/common/packet/server/LoginResponsePacket.java b/src/main/java/eu/m724/autopeerer/common/packet/s2c/LoginResponsePacket.java similarity index 95% rename from src/main/java/eu/m724/autopeerer/common/packet/server/LoginResponsePacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/s2c/LoginResponsePacket.java index 372eb64..c524edb 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/server/LoginResponsePacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/s2c/LoginResponsePacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.server; +package eu.m724.autopeerer.common.packet.s2c; import eu.m724.autopeerer.common.packet.Packet; diff --git a/src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java b/src/main/java/eu/m724/autopeerer/common/packet/s2c/PingResponsePacket.java similarity index 97% rename from src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/s2c/PingResponsePacket.java index 87be440..010c06d 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/server/PingResponsePacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/s2c/PingResponsePacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.server; +package eu.m724.autopeerer.common.packet.s2c; import eu.m724.autopeerer.common.packet.Packet; diff --git a/src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java b/src/main/java/eu/m724/autopeerer/common/packet/s2c/SessionResponsePacket.java similarity index 97% rename from src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java rename to src/main/java/eu/m724/autopeerer/common/packet/s2c/SessionResponsePacket.java index a33737a..52bdc4b 100644 --- a/src/main/java/eu/m724/autopeerer/common/packet/server/SessionResponsePacket.java +++ b/src/main/java/eu/m724/autopeerer/common/packet/s2c/SessionResponsePacket.java @@ -1,4 +1,4 @@ -package eu.m724.autopeerer.common.packet.server; +package eu.m724.autopeerer.common.packet.s2c; import eu.m724.autopeerer.common.packet.Packet; diff --git a/src/main/java/eu/m724/autopeerer/server/Main.java b/src/main/java/eu/m724/autopeerer/server/Main.java index 5a0ac47..215ea8b 100644 --- a/src/main/java/eu/m724/autopeerer/server/Main.java +++ b/src/main/java/eu/m724/autopeerer/server/Main.java @@ -5,28 +5,28 @@ import java.net.InetSocketAddress; import java.util.Set; public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { System.out.println("Hello world!"); var config = new ServerConfiguration(); Set nodes; try { - config.init(); + config.load(); nodes = config.loadNodes(); if (nodes.isEmpty()) System.err.println("Loaded 0 nodes. No client will be able to connect."); else System.out.printf("Loaded %d nodes.\n", nodes.size()); } catch (IOException e) { - throw new RuntimeException("Failed to init configuration", e); + throw new RuntimeException("Failed to load configuration", e); } var packetHandler = new PacketHandler(nodes); - var client = new MyWebsocketServer( + var server = new MyWebsocketServer( new InetSocketAddress(config.getString("listen.address"), config.getInt("listen.port")), packetHandler ); - client.start(); + server.start(); } } diff --git a/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java b/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java index 95fe79a..2397a35 100644 --- a/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java +++ b/src/main/java/eu/m724/autopeerer/server/MyWebsocketServer.java @@ -1,7 +1,7 @@ package eu.m724.autopeerer.server; -import eu.m724.autopeerer.common.packet.client.PingRequestPacket; -import eu.m724.autopeerer.common.packet.client.SessionRequestPacket; +import eu.m724.autopeerer.common.packet.c2s.PingRequestPacket; +import eu.m724.autopeerer.common.packet.c2s.SessionRequestPacket; import inet.ipaddr.IPAddressString; import org.java_websocket.WebSocket; import org.java_websocket.handshake.ClientHandshake; @@ -43,9 +43,10 @@ public class MyWebsocketServer extends WebSocketServer { state.send(new SessionRequestPacket( (short) 1, new IPAddressString("fe80::dead:fed").getAddress().toIPv6(), - "somepk", + "IBusHriGmiJaqbp0IGfClDDHXcei8+JL1MIHjueheUw=", "end.point", - 51820 + 51820, + 4242420000L )); } catch (UnknownHostException e) { throw new RuntimeException(e); diff --git a/src/main/java/eu/m724/autopeerer/server/PacketHandler.java b/src/main/java/eu/m724/autopeerer/server/PacketHandler.java index feb57c5..4147ac3 100644 --- a/src/main/java/eu/m724/autopeerer/server/PacketHandler.java +++ b/src/main/java/eu/m724/autopeerer/server/PacketHandler.java @@ -2,9 +2,9 @@ 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.client.LoginPacket; -import eu.m724.autopeerer.common.packet.server.PingResponsePacket; -import eu.m724.autopeerer.common.packet.server.SessionResponsePacket; +import eu.m724.autopeerer.common.packet.c2s.LoginPacket; +import eu.m724.autopeerer.common.packet.s2c.PingResponsePacket; +import eu.m724.autopeerer.common.packet.s2c.SessionResponsePacket; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; diff --git a/src/main/java/eu/m724/autopeerer/server/ServerConfiguration.java b/src/main/java/eu/m724/autopeerer/server/ServerConfiguration.java index 2543d10..144e47f 100644 --- a/src/main/java/eu/m724/autopeerer/server/ServerConfiguration.java +++ b/src/main/java/eu/m724/autopeerer/server/ServerConfiguration.java @@ -1,33 +1,18 @@ package eu.m724.autopeerer.server; +import eu.m724.autopeerer.common.Configuration; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.file.Files; import java.util.HashSet; import java.util.Properties; import java.util.Set; -public class ServerConfiguration { - private final File directory = new File("config"); - private final File configFile = new File(directory, "server.properties"); - - private final Properties properties = new Properties(); - - public void init() throws IOException { - directory.mkdir(); - - if (!configFile.exists()) { - try (var is = getClass().getClassLoader().getResourceAsStream("server.properties")) { - Files.write(configFile.toPath(), is.readAllBytes()); - properties.load(is); - } - } - - try (var is = new FileInputStream(configFile)) { - properties.load(is); - } +public class ServerConfiguration extends Configuration { + public ServerConfiguration() { + super("server"); } public Set loadNodes() throws IOException { @@ -50,20 +35,4 @@ public class ServerConfiguration { return nodes; } - - public String getString(String property) { - return properties.getProperty(property); - } - - public String getString(String property, String def) { - return properties.getProperty(property, def); - } - - public int getInt(String property) { - return Integer.parseInt(getString(property)); - } - - public int getInt(String property, int def) { - return Integer.parseInt(getString(property, String.valueOf(def))); - } } diff --git a/src/main/resources/client.properties b/src/main/resources/client.properties new file mode 100644 index 0000000..b929aa5 --- /dev/null +++ b/src/main/resources/client.properties @@ -0,0 +1,2 @@ +remote=ws://127.0.0.1:8002 +wireguard.directory=config/wg \ No newline at end of file