addDnsServer Bad Address: Android чын эле эмнени текшерет
addDnsServer катасы Bad address жергиликтүү формат текшерүүсү, DNS бузулушу эмес. Литералды талдап, loopback жана wildcard алып салыңыз, анан жетүү мүмкүнчүлүгүн текшериңиз.
Маани VpnService.Builder.addDnsServer ичине сап катары жетти жана builder аны ошол жерде четке какты, эч нерсе орнотулмай туруп. Бул четке кагуу жергиликтүү: эч кандай resolver менен байланыш болгон жок, туннель жок, ийгиликсиз болгону формат текшерүү, DNS эмес.
Бул маанилүү, анткени кадимки VPN колдонмосунда үч окшош DNS кирүүсү бар: профилдеги маани, сервер жиберген маани жана система деңгээлиндеги Private DNS. Бул чакырууга биринчи экөө гана жетет.
Даярдоо объектиси аргументти дароо текшерет
VpnService.Builder туннель эмес. Ал даректерди, маршруттарды жана серверлерди жыйнаган даярдоо объектиси, жана establish() гана ошол тизмелерди тирүү ParcelFileDescriptor жана интерфейске айландырат. DNS жазуусу addDnsServer чакырганда текшерилет.
Эки натыйжа: стек изи кыска жана атайын маалыматсыз, ал эми этиятсыз catch resolver жок туннелди калтырат.
Builder ар кандай тизмени сактайт; текшерүүдөн өткөн сервер кошуу сап куруу учурунда дарек литералы катары талдангандыгын гана далилдейт.
Аргумент эмне боло алат
Параметр — дарек, endpoint эмес. Builder маалымдамасы IPv4 же IPv6 литералын алат, талдоо сандык гана: android.net.InetAddresses.parseNumericAddress API 29дан тартып ошол парсердин ачык бети.
Практикалык дал келүү мындай көрүнөт:
| 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 |
Версия кантип текшерериңизге таасир этет, builder эмнени аларына эмес. InetAddresses API 29дан жеткиликтүү, ошондуктан Android 10до талдоо бир чакыруу; addDnsServer(InetAddress) баштапкы форма, String жаңы кошумча. API 29дан төмөн InetAddress.getByName хост атын тосуучу тармактык издөө менен чечет.
Loopback бул жерде четке кагылат, wildcard эмес
Десктоп VPN кардарлары өз stub resolverин 127.0.0.1:53кө жиберет; аны Android профилине көчүрүү жергиликтүү машинаны сүрөттөгөн маанини киргизет, бул жерде жергиликтүү машина жок. Builder ушул учурду гана четке кагат: null же loopback дареги IllegalArgumentException ыргытат.
Wildcard — тескери учур, ошондуктан бул катанын көп окуулары жаңылышат. 0.0.0.0 жана :: loopback эмес, ошондуктан builder аларды кабыл алат; курууда эч нерсе ыргытылбайт. Андан кийин интерфейс эч кандай багытты атабаган жазуу менен көтөрүлөт. Муну кармоо валидаторуңуздун иши: isAnyLocalAddress жараксыз кирүү деп эсептеңиз.
Конфигурация чегинде бир жолу талдаңыз
Арзан чечим — сап моделге кирген жерде текшерүү:
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 натыйжа күнөөлүү текстти көтөргөн талаа деңгээлиндеги катага айланат жана колдоо иштей ала турган жалгыз форма ушул. Ийгилик жолунда объект түз builder.addDnsServer(address) ичине кирет, ал эми IllegalArgumentException так кармаңыз, Exception эмес.
Максаттуу маани четке кагылганда аны ачык resolver менен алмаштырбаңыз; үнсүз ачык DNS койгон профиль туташат, бирок ички аттар чечилбейт.
Интерфейс пайда болгондон кийин жетүүнү ырастаңыз
Builderдин кабыл алышы биринчи көзөмөл пункту, акыркысы эмес. Интерфейс көтөрүлгөндөн кийин LinkProperties.getDnsServers() тармак чын эле эмне алганын көрсөтөт, adb shell dumpsys connectivity ошол эле касиеттерди сырттан басып чыгарат.
Private DNS өзүнчө башкаруу жана бул аргументтен өтпөйт; DoT провайдеринин хост аты система жөндөөсүнө таандык, IP талаасына эмес.
Профиль парсерин кайра өзгөртүүдөн мурун чийки сапты жана анын булагын жазыңыз, анын хост аты эмес литерал экенин, loopback же wildcard эмес экенин ырастап, талданган объектини өткөрүңүз.