Last active
August 29, 2015 14:16
-
-
Save tekgator/fd39017561b506139962 to your computer and use it in GitHub Desktop.
Resolving Minecraft server hostname address and port by different inputs, e.g. hostname:port, hostname, port etc. If no port is provided try to get the port via the Minecraft specific SRV record. Used for an Androis project (dependency can be removed by remove logging and IP address pattern). Uses xbill.org DNS class for DNS resolving purposes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.util.Log; | |
import android.util.Patterns; | |
import org.xbill.DNS.Lookup; | |
import org.xbill.DNS.Record; | |
import org.xbill.DNS.ARecord; | |
import org.xbill.DNS.SRVRecord; | |
import org.xbill.DNS.TextParseException; | |
import org.xbill.DNS.Type; | |
import java.net.InetAddress; | |
import java.net.UnknownHostException; | |
/** | |
* Created by tekgator on 07-Mar-2015. | |
*/ | |
public class MinecraftServerDns { | |
private static final String TAG = "MinecraftServerDns"; | |
private static final int DEFAULT_PORT = 25565; | |
private static final String SRV_STR = "_minecraft._tcp."; | |
private String ipAddress = ""; | |
private String hostName = ""; | |
private int port = 0; | |
public MinecraftServerDns(String hostName, int port) throws | |
UnknownHostException { | |
this.resolve(hostName, port); | |
} | |
public MinecraftServerDns(String hostName) throws | |
UnknownHostException { | |
this.resolve(hostName, 0); | |
} | |
private void resolve(String hostName, int port) throws | |
UnknownHostException { | |
// check whether the port is encoded within the hostname string | |
String[] parts = hostName.split(":"); | |
if (parts.length > 1) { | |
this.hostName = parts[0]; | |
try { | |
this.port = Integer.parseInt(parts[1]); | |
} catch (NumberFormatException e) { | |
Log.d(TAG, String.format("Invalid port within hostname '%s' provided, use port from second parameter '%d'", hostName, port)); | |
this.port = port; | |
} | |
} else { | |
this.hostName = hostName; | |
this.port = port; | |
} | |
if (!Patterns.IP_ADDRESS.matcher(this.hostName).matches() && | |
this.hostName != InetAddress.getLocalHost().getHostName() && | |
this.port == 0) { | |
// input is an hostname, but no port submitted, try to resolve via SRV record | |
try { | |
SRVRecord srvRecord = (SRVRecord) lookupRecord(SRV_STR + hostName, Type.SRV); | |
this.hostName = srvRecord.getTarget().toString().replaceFirst("\\.$",""); | |
this.port = srvRecord.getPort(); | |
} catch (UnknownHostException e) { | |
// no SRV record found at the moment, just continue | |
} | |
} | |
if (Patterns.IP_ADDRESS.matcher(this.hostName).matches()) { | |
// hostname provided is a IP address | |
this.ipAddress = this.hostName; | |
} else { | |
// hostname provided is an actual hostname, resolve IP address | |
this.ipAddress = ((ARecord) lookupRecord(this.hostName, Type.A)).getAddress().getHostAddress(); | |
} | |
if (this.port == 0) { | |
// couldn't resolve via SVR record, therefore use default minecraft port | |
this.port = DEFAULT_PORT; | |
} | |
} | |
private Record lookupRecord(String hostName, int type) throws | |
UnknownHostException { | |
Record record = null; | |
Lookup lookup; | |
int result; | |
try { | |
lookup = new Lookup(hostName, type); | |
} catch (TextParseException e) { | |
throw new UnknownHostException(String.format("Host '%s' parsing error:%s", hostName, e.getMessage())); | |
} | |
lookup.run(); | |
result = lookup.getResult(); | |
if (result == Lookup.SUCCESSFUL) { | |
Log.i(TAG, String.format("Successfully got DNS record of type '%d' for hostname '%s'", type, hostName)); | |
record = lookup.getAnswers()[0]; | |
} else { | |
Log.d(TAG, String.format("Failed to get DNS record of type '%d' for hostname '%s'", type, hostName)); | |
switch (result) { | |
case Lookup.HOST_NOT_FOUND: | |
throw new UnknownHostException(String.format("Host '%s' not found", hostName)); | |
case Lookup.TYPE_NOT_FOUND: | |
throw new UnknownHostException(String.format("Host '%s' not found (no A record)", hostName)); | |
case Lookup.UNRECOVERABLE: | |
throw new UnknownHostException(String.format("Cannot lookup host '%s'", hostName)); | |
case Lookup.TRY_AGAIN: | |
throw new UnknownHostException(String.format("Temporary failure to lookup host '%s'", hostName)); | |
default: | |
throw new UnknownHostException(String.format("Unknown error %d in host lookup of '%s'", result, hostName)); | |
} | |
} | |
return record; | |
} | |
public int getPort() { | |
return this.port; | |
} | |
public String getHostName() { | |
return this.hostName; | |
} | |
public String getIpAddress() { | |
return this.ipAddress; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment