addDnsServer Bad Address: ano talaga ang vine-verify ng Android
Ang Bad address error mula sa addDnsServer ay lokal na pagsusuri ng format, hindi pagkawala ng DNS. Suriin ang literal, alisin ang loopback at wildcard, pagkatapos subukan ang pag-abot.
Umabot ang halaga sa VpnService.Builder.addDnsServer bilang string at tinanggihan ito ng builder doon bago pa may naitatag. Lokal ang pagtanggi: walang resolver na nakontak, walang tunnel, at ang nabigo ay pagsusuri ng format, hindi DNS.
Mahalaga ito dahil ang karaniwang VPN app ay may tatlong magkatulad na DNS input: halaga sa profile, halagang ipinapadala ng server, at Private DNS sa antas ng system. Ang unang dalawa lang ang umabot sa tawag na ito.
Sinusuri agad ng preparatory object ang argument
VpnService.Builder ay hindi ang tunnel. Ito ay preparatory object na nangongolekta ng address, ruta at server, at establish() lang ang nagpapalit ng mga listahan sa buhay na ParcelFileDescriptor at interface. Sinusuri ang DNS entry kapag tinawag ang addDnsServer.
Dalawang resulta: maikli at sadyang walang impormasyon ang stack trace, at ang pabayang catch ay nag-iiwan ng tunnel na walang resolver.
Hinihintay ng builder ang anumang listahan; ang pagdagdag ng server na pumasa sa pagsusuri ay nagpapatunay lamang na ang string ay sinuri bilang address literal sa pagbuo.
Ano ang maaaring maging argument
Ang parameter ay address, hindi endpoint. Ang Builder reference ay tumatanggap ng IPv4 o IPv6 literal, at ang pagsusuri ay numeric lamang: android.net.InetAddresses.parseNumericAddress ang pampublikong mukha ng parser na iyon mula API 29.
Ganito ang praktikal na mapping:
| Input | Result | Reason |
|---|---|---|
10.8.0.1 | accepted | IPv4 literal |
2606:4700:4700::1111 | accepted | IPv6 literal |
dns.example.com | rejected | hostname; numeric parsing does not resolve it |
10.8.0.1:53 | rejected | port belongs to your own config model |
https://dns.example.com/dns-query | rejected | DoH URL, a different configuration path |
127.0.0.1 | rejected | loopback is not a remote resolver |
0.0.0.0 or :: | accepted by the builder | parses fine, but names no destination; only your own validator rejects it |
Ang bersyon ay nakakaapekto sa paraan ng pag-verify, hindi sa tinatanggap ng builder. Available ang InetAddresses mula API 29, kaya sa Android 10 isang tawag ang pagsusuri; addDnsServer(InetAddress) ang orihinal na anyo, String ang mas bagong dagdag. Sa ilalim ng API 29, isasagawa ng InetAddress.getByName ang hostname sa blocking network lookup.
Tinatanggihan ang loopback dito, ang wildcard ay hindi
Madalas ituro ng desktop VPN clients ang kanilang stub resolver sa 127.0.0.1:53; kapag kinopya iyon sa Android profile, may halagang naglalarawan sa lokal na makina, at walang lokal na makina dito. Ang builder lang ang tumatanggi sa kasong ito: ang null o loopback address ay naglalabas ng IllegalArgumentException.
Ang wildcard ay ang kabaligtaran at dito nagkakamali ang karamihan. Hindi loopback ang 0.0.0.0 at ::, kaya tinatanggap sila ng builder; walang inilalabas sa pagbuo. Pagkatapos ay tumatayo ang interface na may entry na walang tinutukoy na destinasyon. Paghuli niyon ang trabaho ng iyong validator: ituring ang isAnyLocalAddress na di-wastong input.
Suriin nang isang beses sa hangganan ng configuration
Ang murang solusyon ay i-verify kung saan pumapasok ang string sa iyong modelo:
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 }
}
Ang null na resulta ay nagiging field-level error na may dalang maling teksto, at iyon lang ang anyong kayang aksyunan ng suporta. Sa matagumpay na landas, dumiretso ang object sa builder.addDnsServer(address), at hulihin ang IllegalArgumentException nang tiyak, hindi ang Exception.
Huwag palitan ng pampublikong resolver kapag tinanggihan ang gustong halaga; ang profile na tahimik na naglalagay ng pampublikong DNS ay kumokonekta, ngunit tumitigil ang pag-resolve ng panloob na pangalan.
Kumpirmahin ang pag-abot kapag may interface na
Ang pagtanggap ng builder ay unang checkpoint, hindi huli. Kapag nakatayo na ang interface, iniuulat ng LinkProperties.getDnsServers() ang aktwal na natanggap ng network, at ipiniprint ng adb shell dumpsys connectivity ang parehong katangian mula sa labas.
Ang Private DNS ay hiwalay na kontrol at hindi dumadaan sa argument na ito; ang hostname ng DoT provider ay para sa system setting, hindi sa IP field.
Bago muling baguhin ang profile parser, i-log ang raw string at pinagmulan nito, kumpirmahin na literal ito at hindi hostname, na hindi loopback o wildcard, at ipasa ang nasuri na object.