NetworkUtils/src/dorkbox/netUtil/Dns.kt

107 lines
3.5 KiB
Kotlin

package dorkbox.netUtil
import dorkbox.executor.Executor
import dorkbox.netUtil.dnsUtils.DefaultHostsFileResolver
import dorkbox.netUtil.dnsUtils.ResolveConf
import dorkbox.netUtil.dnsUtils.ResolvedAddressTypes
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress
import java.net.InetSocketAddress
object Dns {
/**
* Gets the version number.
*/
const val version = "2.9.1"
const val DEFAULT_SEARCH_DOMAIN = ""
/**
* @throws IOException if the DNS resolve.conf file cannot be read
*/
fun setDNSServers(dnsServersString: String) {
if (Common.OS_LINUX) {
val dnsServers = dnsServersString.split(",")
val dnsFile = File("/etc/resolvconf/resolv.conf.d/head")
if (!dnsFile.canRead()) {
throw IOException("Unable to initialize dns server file. Something is SERIOUSLY wrong")
}
BufferedWriter(FileWriter(dnsFile)).use {
it.write("# File location: /etc/resolvconf/resolv.conf.d/head\n")
it.write("# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)\n")
dnsServers.forEach { dns ->
it.write("nameserver $dns\n")
}
it.flush();
}
Executor().command("resolvconf", "-u").startBlocking()
} else {
throw RuntimeException("NOT IMPL.")
}
}
/**
* Resolve the address of a hostname against the entries in a hosts file, depending on some address types.
*
* @param inetHost the hostname to resolve
* @param resolvedAddressTypes the address types to resolve
*
* @return the first matching address or null
*/
fun resolveFromHosts(inetHost: String, resolvedAddressTypes: ResolvedAddressTypes = ResolvedAddressTypes.IPV4_PREFERRED): InetAddress? {
return DefaultHostsFileResolver.address(inetHost, resolvedAddressTypes)
}
/** Returns all name servers, including the default ones. */
val nameServers: Map<String, List<InetSocketAddress>> by lazy {
ResolveConf.getUnsortedNameServers()
}
/** Returns all default name servers. */
val defaultNameServers: List<InetSocketAddress> by lazy {
val defaultServers = nameServers[DEFAULT_SEARCH_DOMAIN]!!
if (IPv6.isPreferred) {
// prefer IPv6: return IPv6 first, then IPv4 (each in the order added)
defaultServers.filter { it.address is Inet6Address } + defaultServers.filter { it.address is Inet4Address }
} else if (IPv4.isPreferred) {
// skip IPv6 addresses
defaultServers.filter { it.address is Inet4Address }
} else {
// neither is specified, return in the order added
defaultServers
}
}
/**
* Gets the threshold for the number of dots which must appear in a name before it is considered
* absolute. The default is 1.
*/
val numberDots: Int by lazy {
if (Common.OS_WINDOWS) {
1
} else {
// first try the default unix config path
var tryParse = ResolveConf.tryParseResolvConfNDots("/etc/resolv.conf")
if (!tryParse.first) {
// then fallback to netware
tryParse = ResolveConf.tryParseResolvConfNDots("sys:/etc/resolv.cfg")
}
tryParse.second
}
}
}
//TODO add domain TLD, etc util tools