Vrednost je prispela v VpnService.Builder.addDnsServer kot niz in builder jo je tam zavrnil, preden je bilo kaj vzpostavljeno. Ta zavrnitev je lokalna: noben resolver ni bil klican, tunela ni, in kar je spodletelo, je preverjanje oblike, ne DNS.

To je pomembno, ker ima tipična aplikacija VPN tri podobne vnose DNS: vrednost v profilu, vrednost, ki jo pošlje strežnik, in Private DNS na ravni sistema. Do tega klica prideta le prva dva.

Pripravljalni objekt preveri argument takoj

VpnService.Builder ni tunel. To je pripravljalni objekt, ki zbira naslove, poti in strežnike, in le establish() te sezname spremeni v živi ParcelFileDescriptor in vmesnik. Vnos DNS se preveri ob klicu addDnsServer.

Dve posledici: sled je kratka in namerno neinformativna, nepreviden catch pa pusti tunel brez resolverja.

Builder obdrži vsak seznam; dodajanje strežnika, ki prestane preverjanje, dokaže le, da je bil niz ob gradnji razčlenjen kot naslovni literal.

Kaj je lahko argument

Parameter je naslov, ne endpoint. Referenca Builder sprejme literal IPv4 ali IPv6, razčlenjevanje pa je le številsko: android.net.InetAddresses.parseNumericAddress je javni obraz tega razčlenjevalnika od API 29.

Praktično preslikavo izgleda takole:

InputResultReason
10.8.0.1acceptedIPv4 literal
2606:4700:4700::1111acceptedIPv6 literal
dns.example.comrejectedhostname; numeric parsing does not resolve it
10.8.0.1:53rejectedport belongs to your own config model
https://dns.example.com/dns-queryrejectedDoH URL, a different configuration path
127.0.0.1rejectedloopback is not a remote resolver
0.0.0.0 or ::accepted by the builderparses fine, but names no destination; only your own validator rejects it

Različica vpliva na to, kako preverjate, ne na to, kaj sprejme builder. InetAddresses je na voljo od API 29, zato je na Androidu 10 razčlenjevanje en klic; addDnsServer(InetAddress) je izvirna oblika, String novejši dodatek. Pod API 29 bo InetAddress.getByName razrešil ime gostitelja z blokirajočim omrežnim iskanjem.

Loopback se tu zavrne, wildcard ne

Namizni odjemalci VPN pogosto usmerijo svoj stub resolver na 127.0.0.1:53; kopiranje v profil Android vnese vrednost, ki opisuje lokalni stroj, lokalnega stroja pa tu ni. Builder zavrne le ta primer: naslov null ali loopback vrže IllegalArgumentException.

Wildcard je nasproten primer in tu se večina branj te napake zmoti. 0.0.0.0 in :: nista loopback, zato ju builder sprejme; ob gradnji se nič ne vrže. Vmesnik se nato dvigne z vnosom, ki ne navaja cilja. To ujeti je delo vašega validatorja: obravnavajte isAnyLocalAddress kot neveljaven vnos.

Razčlenite enkrat na meji konfiguracije

Poceni popravek je preverjanje tam, kjer niz vstopi v vaš model:

import android.net.InetAddresses
import java.net.InetAddress

private fun dnsLiteralOrNull(raw: String?): InetAddress? {
    val text = raw?.trim().orEmpty()
    if (text.isEmpty()) return null
    val address = try {
        InetAddresses.parseNumericAddress(text)
    } catch (e: IllegalArgumentException) {
        return null
    }
    return address.takeUnless { it.isAnyLocalAddress || it.isLoopbackAddress }
}

Rezultat null postane napaka na ravni polja z krivim besedilom in to je edina oblika, na katero lahko podpora reagira. Na poti uspeha gre objekt naravnost v builder.addDnsServer(address), IllegalArgumentException pa lovite posebej, ne Exception.

Ne nadomeščajte z javnim resolverjem, ko je želena vrednost zavrnjena; profil, ki tiho vstavi javni DNS, se poveže, a notranja imena se prenehajo razreševati.

Potrdite dosegljivost, ko vmesnik obstaja

Sprejem pri builderju je prva kontrolna točka, ne zadnja. Ko se vmesnik dvigne, LinkProperties.getDnsServers() pokaže, kaj je omrežje dejansko prejelo, adb shell dumpsys connectivity pa izpiše iste lastnosti od zunaj.

Private DNS je ločena kontrola in ne gre skozi ta argument; ime gostitelja ponudnika DoT spada v sistemsko nastavitev, ne v polje IP.

Preden znova spremenite razčlenjevalnik profila, zabeležite surov niz in njegov vir, potrdite, da je literal in ne ime gostitelja, da ni loopback ali wildcard, in posredujte razčlenjeni objekt.

Sorodni članki