Qiymat VpnService.Builder.addDnsServer ga satr sifatida yetib keldi va builder uni hech narsa ornatilmasdan turib osha yerda rad etdi. Bu rad etish mahalliy: hech qanday resolver bilan aloqa qilinmadi, tunnel yoq, va muvaffaqiyatsiz bolgan narsa format tekshiruvi, DNS emas.

Bu muhim, chunki odatiy VPN ilovasida uchta oxshash DNS kirishi bor: profildagi qiymat, server yuboradigan qiymat va tizim darajasidagi Private DNS. Faqat birinchi ikkitasi bu chaqiruvga yetib boradi.

Tayyorlash obyekti argumentni darhol tekshiradi

VpnService.Builder tunnel emas. U manzillar, marshrutlar va serverlarni toplaydigan tayyorlash obyekti, va faqat establish() bu royxatlarni tirik ParcelFileDescriptor va interfeysga aylantiradi. DNS yozuvi addDnsServer chaqirilganda tekshiriladi.

Ikki natija: stack izi qisqa va ataylab malumotsiz, beparvo catch esa resolver siz tunnel qoldiradi.

Builder berilgan har qanday royxatni saqlaydi; tekshiruvdan otgan server qoshish satr qurish paytida manzil literali sifatida tahlil qilinganini isbotlaydi xolos.

Argument nima bolishi mumkin

Parametr manzil, endpoint emas. Builder manbasi IPv4 yoki IPv6 literalini oladi va tahlil faqat sonli: android.net.InetAddresses.parseNumericAddress API 29 dan beri osha parserniнг ommaviy yuzi.

Amaliy moslik shunday korinadi:

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

Versiya qanday tekshirishingizga tasir qiladi, builder nima qabul qilishiga emas. InetAddresses API 29 dan mavjud, shuning uchun Android 10 da tahlil bitta chaqiruv; addDnsServer(InetAddress) asl shakl, String yangi qoshimcha. API 29 dan pastda InetAddress.getByName xost nomini bloklovchi tarmoq qidiruvi bilan hal qiladi.

Loopback bu yerda rad etiladi, wildcard emas

Ish stoli VPN mijozlari oz stub resolverlarini 127.0.0.1:53 ga yuboradi; uni Android profiliga ko chirish mahalliy mashinani tasvirlovchi qiymat kiritadi, bu yerda esa mahalliy mashina yoq. Builder faqat shu holatni rad etadi: null yoki loopback manzil IllegalArgumentException tashlaydi.

Wildcard buning aksi va aynan shu yerda bu xatoning kop talqinlari xato qiladi. 0.0.0.0 va :: loopback emas, shuning uchun builder ularni qabul qiladi; qurishda hech narsa tashlanmaydi. Song interfeys hech qanday manzilni nomlamaydigan yozuv bilan kotariladi. Buni tutish validatoringiz ishi: isAnyLocalAddress ni notogri kirish deb biling.

Konfiguratsiya chegarasida bir marta tahlil qiling

Arzon yechim satr modelingizga kiradigan joyda tekshirish:

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 natija aybdor matnni olib yuruvchi maydon darajasidagi xatoga aylanadi va qollab-quvvatlash faqat shu shaklda harakat qila oladi. Muvaffaqiyat yolda obyekt togri builder.addDnsServer(address) ichiga kiradi, IllegalArgumentException ni aniq tuting, Exception ni emas.

Kutilgan qiymat rad etilganda ommaviy resolver bilan almashtirmang; jimgina ommaviy DNS qoyadigan profil ulanadi, lekin ichki nomlar hal bolmaydi.

Interfeys paydo bolgach yetib borishni tasdiqlang

Builderning qabul qilishi birinchi nazorat nuqtasi, oxirgisi emas. Interfeys kotarilgach LinkProperties.getDnsServers() tarmoq aslida nima olganini korsatadi, adb shell dumpsys connectivity esa osha xossalarni tashqaridan chop etadi.

Private DNS alohida boshqaruv va bu argumentdan otmaydi; DoT provayderining xost nomi tizim sozlamasiga tegishli, IP maydoniga emas.

Profil parserini yana ozgartirishdan oldin xom satrni va uning manbasini yozib oling, u xost nomi emas literal ekanini, loopback yoki wildcard emasligini tasdiqlang va tahlil qilingan obyektni uzating.

O'xshash maqolalar