Gildið náði í VpnService.Builder.addDnsServer sem strengur og builder hafnaði því þar áður en nokkuð var sett upp. Þessi höfnun er staðbundin: enginn resolver var hafður samband við, enginn göng er til og það sem brást er sniðathugun, ekki DNS-bilun.

Þetta skiptir máli því dæmigert VPN-forrit hefur þrjár svipaðar DNS-inntaksleiðir: gildi í sniðinu, gildi sem þjónninn sendir og Private DNS á kerfisstigi. Aðeins fyrstu tvær ná þessu kalli.

Undirbúningshlutur athugar röksemdina samstundis

VpnService.Builder er ekki göngin. Það er undirbúningshlutur sem safnar vistföngum, leiðum og þjónum og aðeins establish() breytir þessum listum í lifandi ParcelFileDescriptor og viðmót. DNS-færslan er athuguð þegar addDnsServer er kallað.

Tvær afleiðingar: slóðin er stutt og viljandi innihaldslítil, og kærulaus catch skilur eftir göng með vistföngum en án resolver.

Builder geymir hvaða lista sem þú gefur; að bæta við þjóni sem stenst athugun sannar aðeins að strengurinn hafi verið greindur sem vistfangs-literali.

Hvað röksemdin má vera

Færibreytan er vistfang, ekki endpoint. Builder-tilvísun tekur IPv4 eða IPv6 literal og greiningin er aðeins töluleg: android.net.InetAddresses.parseNumericAddress er opinbert andlit þess parsers frá API 29.

Hagnýta vörpunin lítur svona út:

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

Útgáfan hefur áhrif á hvernig þú staðfestir, ekki hvað builder tekur. InetAddresses er fáanlegt frá API 29, svo á Android 10 er greiningin eitt kall; addDnsServer(InetAddress) er upprunalega formið, String nýrri viðbótin. Undir API 29 leysir InetAddress.getByName hýslinafn með blokkkandi netleitarbeiðni.

Loopback er hafnað hér, wildcard ekki

Skjáborðs-VPN-biðlar senda stub resolver sinn á 127.0.0.1:53; að afrita það í Android-snið flytur inn gildi sem lýsir staðbundinni vél, og hér er engin staðbundin vél. Builder hafnar aðeins þessu tilviki: null eða loopback vistfang kastar IllegalArgumentException.

Wildcard er hið gagnstæða tilvik og hér fara flestar lestrar þessarar villu úrskeiðis. 0.0.0.0 og :: eru ekki loopback, svo builder tekur þau; engu er kastað. Viðmótið rís svo með færslu sem tilgreinir engan áfangastað. Að grípa það er verk þíns validator: meðhöndlaðu isAnyLocalAddress sem ógilt inntak.

Greindu einu sinni við stillingarmörkin

Ódýra lausnin er að staðfesta þar sem strengurinn fer inn í líkanið:

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 }
}

Null-niðurstaða verður villa á reitastigi með saknæma textanum og er eina formið sem stuðningur getur unnið með. Á árangursríkri leið fer hluturinn beint í builder.addDnsServer(address) og gríptu IllegalArgumentException sérstaklega, ekki Exception.

Ekki skipta út fyrir opinberan resolver þegar ætlaða gildinu er hafnað; snið sem setur hljóðlega opinbert DNS tengist en innri nöfn leysast ekki.

Staðfestu aðgengi þegar viðmótið er til

Samþykki builders er fyrsti kontrollpunkturinn, ekki sá síðasti. Þegar viðmótið er komið upp sýnir LinkProperties.getDnsServers() hvað netið fékk í raun og adb shell dumpsys connectivity prentar sömu eiginleika að utan.

Private DNS er aðskilin stýring og fer ekki í gegnum þessa röksemd; hýslinafn DoT-veitanda tilheyrir kerfisstillingu, ekki IP-reit.

Áður en þú breytir sniðsparsernum aftur skaltu skrá hráa strenginn og uppruna hans, staðfesta að hann sé literal en ekki hýslinafn, að hann sé hvorki loopback né wildcard, og senda greinda hlutinn áfram.

Tengdir greinar