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:

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

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.

Makala zinazohusiana