addDnsServer Bad Address: kile Android hukagua kwa kweli
Hitilafu ya Bad address kutoka addDnsServer ni ukaguzi wa muundo wa ndani, si kushindwa kwa DNS. Changanua literal, ondoa loopback na wildcard, kisha jaribu ufikivu.
Thamani ilifikia VpnService.Builder.addDnsServer kama mfuatano na builder ilikataa hapo kabla ya kitu chochote kuanzishwa. Ukataaji huu ni wa ndani: hakuna resolver iliyowasiliana, hakuna tunnel, na kilichoshindikana ni ukaguzi wa muundo, si DNS.
Hii ni muhimu kwa sababu programu ya VPN kwa kawaida ina pembejeo tatu za DNS zinazofanana: thamani kwenye wasifu, thamani inayotumwa na seva, na Private DNS katika ngazi ya mfumo. Mbili za kwanza tu hufikia wito huu.
Kitu cha maandalizi hukagua hoja mara moja
VpnService.Builder si tunnel. Ni kitu cha maandalizi kinachokusanya anwani, njia na seva, na establish() pekee hubadilisha orodha hizo kuwa ParcelFileDescriptor hai na kiolesura. Ingizo la DNS hukaguliwa unapopiga addDnsServer.
Matokeo mawili: alama ni fupi na kwa makusudi haina taarifa, na catch ya uzembe huacha tunnel bila resolver.
Builder huhifadhi orodha yoyote; kuongeza seva inayopita ukaguzi huthibitisha tu kwamba mfuatano ulichanganuliwa kama literal ya anwani wakati wa kujenga.
Hoja inaweza kuwa nini
Kigezo ni anwani, si endpoint. Rejea ya Builder hupokea literal ya IPv4 au IPv6, na uchanganuzi ni wa nambari pekee: android.net.InetAddresses.parseNumericAddress ni uso wa umma wa parser hiyo tangu API 29.
Ramani ya vitendo inaonekana hivi:
| 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 |
Toleo huathiri jinsi unavyothibitisha, si kile builder inakubali. InetAddresses inapatikana tangu API 29, kwa hiyo kwenye Android 10 uchanganuzi ni wito mmoja; addDnsServer(InetAddress) ni umbo la awali, String ni nyongeza mpya. Chini ya API 29 InetAddress.getByName itatatua jina la mwenyeji kwa utafutaji wa mtandao unaozuia.
Loopback hukataliwa hapa, wildcard hapana
Wateja wa VPN wa kompyuta hupeleka stub resolver yao kwa 127.0.0.1:53; kunakili hilo kwenye wasifu wa Android huingiza thamani inayoelezea mashine ya ndani, na hapa hakuna mashine ya ndani. Builder hukataa hali hii pekee: anwani ya null au loopback hutupa IllegalArgumentException.
Wildcard ni hali kinyume na hapa ndipo wasomaji wengi hukosea. 0.0.0.0 na :: si loopback, kwa hiyo builder huzikubali; hakuna kinachotupwa wakati wa kujenga. Kiolesura huinuka na ingizo lisilotaja lengo. Kuikamata ni kazi ya validator yako: chukulia isAnyLocalAddress kama pembejeo batili.
Changanua mara moja kwenye ukingo wa usanidi
Suluhisho la bei nafuu ni kuthibitisha mahali mfuatano unapoingia kwenye modeli yako:
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 }
}
Tokeo la null huwa hitilafu ya ngazi ya uwanja inayobeba maandishi yenye kosa, na ndiyo aina pekee ambayo msaada unaweza kuchukua hatua. Kwenye njia ya mafanikio kitu huingia moja kwa moja kwenye builder.addDnsServer(address), na kamata IllegalArgumentException mahususi, si Exception.
Usibadilishe na resolver ya umma wakati thamani inayokusudiwa inakataliwa; wasifu unaoweka DNS ya umma kwa kimya huunganisha, lakini majina ya ndani huacha kutatuliwa.
Thibitisha ufikivu baada ya kiolesura kuwepo
Kukubaliwa na builder ni kituo cha kwanza cha ukaguzi, si cha mwisho. Kiolesura kinapoinuka LinkProperties.getDnsServers() huonyesha kile mtandao ulipokea kweli, na adb shell dumpsys connectivity huchapisha sifa zilezile kutoka nje.
Private DNS ni udhibiti tofauti na haupiti kwenye hoja hii; jina la mwenyeji la mtoa huduma wa DoT ni la mpangilio wa mfumo, si uwanja wa IP.
Kabla ya kubadilisha parser ya wasifu tena, andika mfuatano mbichi na chanzo chake, thibitisha kuwa ni literal si jina la mwenyeji, kwamba si loopback wala wildcard, na pitisha kitu kilichochanganuliwa.