SRV support

This commit is contained in:
Anuken 2024-01-27 17:46:52 -05:00
parent db4c861dde
commit a73b783d98
4 changed files with 49 additions and 51 deletions

View File

@ -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<Host> valid, Cons<Exception> 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<SRVRecord> records, int index, Cons<Host> valid, Cons<Exception> 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<Host> valid, Cons<Exception> 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

View File

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

View File

@ -39,13 +39,11 @@ public class Dns{
}, error);
}
/*
TODO: SRV record support
resolve(srvRecord, domain, bytes -> {
static void resolveSrv(String domain, Cons<Seq<SRVRecord>> result, Cons<Exception> 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<InetAddress> result, Cons<Exception> 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");

View File

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