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> by lazy { ResolveConf.getUnsortedNameServers() } /** Returns all default name servers. */ val defaultNameServers: List 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