diff --git a/core/src/mindustry/net/ArcNetProvider.java b/core/src/mindustry/net/ArcNetProvider.java index 5780a32fba..d2e8183c59 100644 --- a/core/src/mindustry/net/ArcNetProvider.java +++ b/core/src/mindustry/net/ArcNetProvider.java @@ -5,10 +5,12 @@ import arc.func.*; import arc.math.*; import arc.net.*; import arc.net.FrameworkMessage.*; +import arc.net.dns.*; import arc.struct.*; import arc.util.*; import arc.util.Log.*; import arc.util.io.*; +import mindustry.*; import mindustry.game.EventType.*; import mindustry.net.Administration.*; import mindustry.net.Net.*; @@ -222,6 +224,35 @@ public class ArcNetProvider implements NetProvider{ @Override public void pingHost(String address, int port, Cons valid, Cons invalid){ + mainExecutor.submit(() -> { + + pingHostImpl(address, port, host -> Core.app.post(() -> valid.get(host)), e -> { + //raw IP addresses can't have SRV records, so don't bother checking + if(port == Vars.port && Addresses.getAddress(address) == null){ + Dns.resolveSrv("_mindustry._tcp." + address, records -> { + records.sort(); + pingRecords(records, 0, host1 -> Core.app.post(() -> valid.get(host1)), srvError -> Core.app.post(() -> invalid.get(e))); + }, srvError -> Core.app.post(() -> invalid.get(e))); + }else{ + Core.app.post(() -> invalid.get(e)); + } + }); + + }); + } + + private void pingRecords(Seq records, int index, Cons valid, Cons invalid){ + if(index >= records.size){ + invalid.get(new UnknownHostException()); + return; + } + + var record = records.get(index); + + pingHostImpl(record.target, record.port, valid, error -> pingRecords(records, index + 1, valid, invalid)); + } + + private void pingHostImpl(String address, int port, Cons valid, Cons error){ long time = Time.millis(); Dns.resolveAddress(address, inetaddr -> { @@ -230,44 +261,9 @@ public class ArcNetProvider implements NetProvider{ AsyncUdp.send(socket, 2000, 512, ByteBuffer.wrap(new byte[]{-2, 1}), data -> { Host host = NetworkIO.readServerData((int)Time.timeSinceMillis(time), socket.getAddress().getHostAddress(), data); host.port = port; - Core.app.post(() -> valid.get(host)); - }, e -> Core.app.post(() -> invalid.get(e))); - }, err -> Core.app.post(() -> invalid.get(err))); - - /* - try{ - var host = pingHostImpl(address, port); - Core.app.post(() -> valid.get(host)); - }catch(IOException e){ - if(port == Vars.port){ - for(var record : ArcDns.getSrvRecords("_mindustry._tcp." + address)){ - try{ - var host = pingHostImpl(record.target, record.port); - Core.app.post(() -> valid.get(host)); - return; - }catch(IOException ignored){ - } - } - } - Core.app.post(() -> invalid.get(e)); - }*/ - } - - private Host pingHostImpl(String address, int port) throws IOException{ - try(DatagramSocket socket = new DatagramSocket()){ - long time = Time.millis(); - - socket.send(new DatagramPacket(new byte[]{-2, 1}, 2, InetAddress.getByName(address), port)); - socket.setSoTimeout(2000); - - DatagramPacket packet = packetSupplier.get(); - socket.receive(packet); - - ByteBuffer buffer = ByteBuffer.wrap(packet.getData()); - Host host = NetworkIO.readServerData((int)Time.timeSinceMillis(time), packet.getAddress().getHostAddress(), buffer); - host.port = port; - return host; - } + valid.get(host); + }, error); + }, error); } @Override diff --git a/core/src/mindustry/net/AsyncUdp.java b/core/src/mindustry/net/AsyncUdp.java index 8e74aee22d..d392393ec2 100644 --- a/core/src/mindustry/net/AsyncUdp.java +++ b/core/src/mindustry/net/AsyncUdp.java @@ -50,7 +50,8 @@ public class AsyncUdp{ var channel = (DatagramChannel)key.channel(); var buffer = ByteBuffer.allocate(request.bufferSize); channel.receive(buffer); - buffer.flip(); + buffer.position(0); + buffer.limit(buffer.capacity()); request.received.get(buffer); request.close(); diff --git a/core/src/mindustry/net/Dns.java b/core/src/mindustry/net/Dns.java index 08f2651ca3..a59b803eff 100644 --- a/core/src/mindustry/net/Dns.java +++ b/core/src/mindustry/net/Dns.java @@ -39,13 +39,11 @@ public class Dns{ }, error); } - /* - TODO: SRV record support - - resolve(srvRecord, domain, bytes -> { + static void resolveSrv(String domain, Cons> result, Cons error){ + resolve(srvRecord, domain, bytes -> { int priority = bytes.getShort() & 0xFFFF; - int weight = bytes.getShort() & 0xFFFF; - int port = bytes.getShort() & 0xFFFF; + int weight = bytes.getShort() & 0xFFFF; + int port = bytes.getShort() & 0xFFFF; int len; StringBuilder builder = new StringBuilder(); @@ -55,15 +53,17 @@ public class Dns{ } builder.delete(builder.length() - 1, builder.length()); - return "SRV Record: " + builder + " " + priority + " " + weight + " port=" +port; + return new SRVRecord(0, priority, weight, port, builder.toString()); }, records -> { if(records.size > 0){ - Log.info("@ has SRV records: @", domain, records); + result.get(records); + }else{ + //no SRV records, just call it an error + error.get(new UnknownHostException()); } - }, e -> {}); - */ + }, error); + } - //TODO no SRV record support static void resolveAddress(String domain, Cons result, Cons error){ //since parsing the address may be slow, check the cache first. @@ -149,6 +149,7 @@ public class Dns{ buffer.flip(); AsyncUdp.send(addresses.get(index), 2000, 512, buffer, result -> { + short responseId = result.getShort(); if(responseId != id) { throw new ArcRuntimeException("Invalid response ID"); diff --git a/gradle.properties b/gradle.properties index e69588eb44..3d72e86dff 100644 --- a/gradle.properties +++ b/gradle.properties @@ -25,4 +25,4 @@ org.gradle.caching=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=137d14855f +archash=008e73aa33