quarta-feira, 28 de novembro de 2018

OkHttpClient - Pra resolver o problema do IPv6 (Kottlin)

Uma solução encontrada, e testada.

class DnsSelector(private val mode: Mode) : Dns {
 
   enum class Mode {
        SYSTEM,
        IPV6_FIRST,
        IPV4_FIRST,
        IPV6_ONLY,
        IPV4_ONLY
    }
   
  private val overrides = HashMap<String, MutableList<InetAddress>>()

  override fun lookup(hostname: String): MutableList<InetAddress> {
        var addresses: MutableList<InetAddress>? = overrides[hostname.toLowerCase()]
        if (addresses != null) {
            return addresses
        }
        addresses = Dns.SYSTEM.lookup(hostname)
        val sortedList = when (mode) {
            DnsSelector.Mode.IPV4_FIRST -> addresses.sortedBy { it is Inet4Address }.toMutableList()
            DnsSelector.Mode.IPV6_FIRST -> addresses.sortedBy { it is Inet6Address }.toMutableList()
            DnsSelector.Mode.IPV4_ONLY -> addresses.filter { it is Inet4Address }.toMutableList()
            DnsSelector.Mode.IPV6_ONLY -> addresses.filter { it is Inet6Address }.toMutableList()
            else -> throw IllegalArgumentException("Invalid $mode Mode!")
        }
        return sortedList
    }
 
   /**
     * Replaces System InetAddress list for a specific hostname.
     */
    fun addOverride(hostname: String, address: InetAddress) {
        overrides[hostname.toLowerCase()] = mutableListOf(address)
    }

    companion object {
        fun byName(ipMode: String): Dns {
            val selectedMode: Mode = when (ipMode) {
                "ipv6" -> Mode.IPV6_FIRST
                "ipv4" -> Mode.IPV4_FIRST
                "ipv6only" -> Mode.IPV6_ONLY
                "ipv4only" -> Mode.IPV4_ONLY
                else -> Mode.SYSTEM
            }
            return DnsSelector(selectedMode)
        }
    }
}

// Na criação do seu OkHttp
OkHttpClient.Builder().dns(DnsSelector.byName("ipv4only"))

Nenhum comentário:

Postar um comentário