addDnsServer Bad Address: zer egiaztatzen du Androidek benetan
addDnsServer-en Bad address errorea formatu-egiaztapen lokala da, ez DNS etenaldia. Aztertu literala, kendu loopback eta wildcard, eta gero probatu irisgarritasuna.
Balioa VpnService.Builder.addDnsServer-ra kate gisa iritsi zen eta builder-ak han baztertu zuen ezer ezarri aurretik. Bazterketa hori lokala da: ez da resolverrik kontaktatu, ez dago tunelik eta huts egin duena formatu-egiaztapena da, ez DNS etenaldia.
Garrantzitsua da VPN aplikazio tipiko batek hiru DNS sarrera antzeko dituelako: profilean idatzitako edo inportatutako balioa, zerbitzariak konfigurazioan bidaltzen duena eta Private DNS sistema mailan. Lehenengo biak soilik iristen dira deialdi honetara.
Prestaketa-objektu batek argumentua berehala egiaztatzen du
VpnService.Builder ez da tunela. helbideak, ibilbideak eta zerbitzariak biltzen dituen prestaketa-objektua da, eta establish() soilik bihurtzen ditu zerrendok ParcelFileDescriptor bizia eta interfazea. DNS sarrera addDnsServer deitzean egiaztatzen da, ez ezartzean.
Bi ondorio datoz. Traza laburra eta nahita hutsa da: balioa kate soil gisa iritsi zen. Eta eraikuntza osoaren inguruko catch axolagabe batek helbideak eta ibilbideak dituen baina resolverrik ez duen tunela uzten du.
Builder-ak ematen diozun zerrenda oro gordetzen du. Egiaztapena gainditzen duen zerbitzari bat gehitzeak katea eraikuntza garaian helbide-literal gisa aztertu zela baino ez du frogatzen.
Zer izan daitekeen argumentua
Parametroa helbidea da, ez endpoint bat. Builder erreferentziak IPv4 edo IPv6 literala onartzen du, eta azterketa numerikoa soilik da: android.net.InetAddresses.parseNumericAddress API 29tik aurrera parser horren aurpegi publikoa da. Ostalari-izena hemen ez da helbide motela, aztertu ezin den katea baizik.
Mapeo praktikoa horrela da:
| 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 |
Bertsioak nola balioztatzen duzun eragiten du, ez builder-ak zer onartzen duen. InetAddresses API 29tik dago erabilgarri, beraz Android 10 eta berriagoetan azterketa dei bakarra da. addDnsServer(InetAddress) jatorrizko forma da eta String gehitze berriena. API 29 azpitik InetAddress.getByName ostalari-izena blokeatzen duen sare-kontsulta batekin ebatziko du eta hutsegite bat abiarazte motel bihurtuko du.
Loopback hemen baztertzen da, wildcard ez
Mahaigaineko VPN bezeroek beren stub resolverra 127.0.0.1:53-ra bideratzen dute sarritan. Hori Android profilera kopiatzeak makina lokala deskribatzen duen balioa inportatzen du, eta hemen ez dago makina lokalik. Builder-ak kasu hau soilik baztertzen du: null edo loopback helbideak IllegalArgumentException jaurtitzen du.
Wildcard-a kontrako kasua da eta hemen huts egiten dute irakurketa gehienek. 0.0.0.0 eta :: ez dira loopback, beraz builder-ak onartu egiten ditu; eraikuntza garaian ez da ezer jaurtitzen. Interfazea helmugarik aipatzen ez duen sarrera batekin igotzen da. Hori harrapatzea zure balioztatzailearen lana da: trata ezazu isAnyLocalAddress sarrera baliogabetzat.
Aztertu behin konfigurazioaren mugean
Konponbide merkea katea zure modelora sartzen den tokian balioztatzea da:
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 emaitza testu erruduna daraman eremu-mailako errorea bihurtzen da, eta hori da euskarriak landu dezakeen forma bakarra. Arrakasta-bidean objektua zuzenean builder.addDnsServer(address)-ra doa. Harrapatu IllegalArgumentException zehazki, ez Exception: harrapaketa zabalak null-erakuslearen erroreak ere irentsi egiten ditu.
Ez ordeztu resolver publiko batekin nahi den balioa baztertzen denean. Isilka DNS publiko batera aldatzen duen profila konektatu egiten da, baina barne-izenak ebazteari uzten diote.
Egiaztatu irisgarritasuna interfazea sortu ondoren
Builder-aren onarpena lehen kontrol-puntua da, ez azkena. Interfazea altxatuta dagoenean, LinkProperties.getDnsServers()-k sareak benetan zer jaso duen erakusten du. adb shell dumpsys connectivity-k propietate berak inprimatzen ditu kanpotik.
Private DNS kontrol bereizia da eta ez doa argumentu honetatik. DoT hornitzaile baten ostalari-izena sistemaren ezarpenekoa da, ez IP eremu batekoa.
Profilaren parserra berriro aldatu aurretik, egin hurrenkera honetan: erregistratu kate gordina eta bere iturria, egiaztatu literala dela eta ez ostalari-izena, ez dela loopback ez wildcard, eta pasa aztertutako objektua.