Qiimuhu wuxuu gaadhay VpnService.Builder.addDnsServer isagoo xarriiq ah, builder-na halkaas ayuu diiday ka hor inta aan wax la dhisin. Diidmadaas waa gudaha: resolver lama xiriirin, tunnel ma jiro, wixii guuldarraystayna waa hubin qaab, ma aha DNS.

Tan waa muhiim sababtoo ah app-ka VPN caadiga ah wuxuu leeyahay saddex gelitaan DNS oo isku mid ah: qiime ku jira profile-ka, qiime uu server-ku diro, iyo Private DNS heerka nidaamka. Kaliya labada hore ayaa gaadha wicitaankan.

Shayga diyaarinta wuxuu isla markiiba hubiyaa doodda

VpnService.Builder ma aha tunnel-ka. Waa shay diyaarin ah oo ururiya cinwaanno, waddooyin iyo serverro, kaliya establish() ayaa u beddela liisaskaas ParcelFileDescriptor nool iyo interface. Gelitaanka DNS waxaa la hubiyaa marka aad wacdo addDnsServer.

Laba cawaaqib: raadku waa gaaban yahay oo si ula kac ah macluumaad la aan, iyo catch taxaddar la aan wuxuu ka tagaa tunnel resolver la aan.

Builder wuxuu hayaa liis kasta oo aad siiso; ku darista server dhaafa hubinta waxay kaliya caddaynaysaa in xarriiqda loo falanqeeyay sida cinwaan literal markii la dhisayay.

Dooddu maxay noqon kartaa

Halbeeggu waa cinwaan, ma aha endpoint. Tixraaca Builder wuxuu qaataa literal IPv4 ama IPv6, falanqayntuna waa tiro kaliya: android.net.InetAddresses.parseNumericAddress waa wejiga dadweynaha ee parser-kaas laga bilaabo API 29.

Khariitadaha waxqabadku sidan ayay u eg yihiin:

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

Nooca wuxuu saameeyaa sida aad u xaqiijiso, ma aha waxa builder-ku aqbalao. InetAddresses waa la heli karaa laga bilaabo API 29, sidaas darteed Android 10 falanqayntu waa hal wicitaan; addDnsServer(InetAddress) waa qaabka asalka ah, String waa lagu daray cusub. API 29 ka hoose InetAddress.getByName wuxuu xallin doonaa magaca martigeliyaha iyadoo raadinta shabakad xannibaysa.

Loopback waa la diidayaa halkan, wildcard ma aha

Macaamiisha VPN ee desktop waxay badanaa u diraan stub resolver-kooda 127.0.0.1:53; ku koobista taas profile Android waxay soo dejisaa qiime qeexaya mashiinka gudaha, halkanna ma jiro mashiin gudaha. Builder wuxuu diidayaa kaliya xaaladdan: cinwaan null ama loopback wuxuu tuuraa IllegalArgumentException.

Wildcard waa xaaladda ka soo horjeeda halkanna ayaa akhrinta badan khaladno. 0.0.0.0 iyo :: ma aha loopback, sidaas darteed builder wuu aqbalaa; wax lama tuuro marka la dhisayo. Interface-ku wuxuu kor u kacaa isagoo leh gelitaan aan magacaabin meel. Qabashada taas waa shaqada validator-kaaga: u qaado isAnyLocalAddress gelitaan aan ansax ahayn.

Falanqee hal mar xadka habaynta

Daaweynta jaban waa in la xaqiijiyo halka xarriiqdu u gasho model-kaaga:

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 }
}

Natiijada null waxay noqotaa khalad heer goob ah oo sita qoraalka dembiga, waana qaabka kaliya ee taageeradu wax ka qaban karto. Jidka guusha shaygu si toos ah ayuu u galaa builder.addDnsServer(address), oo qabo IllegalArgumentException si gaar ah, ma aha Exception.

Ha ku beddelin resolver dadweyne marka qiimaha loogu talagalay la diido; profile si aamusnaan ah u dhigta DNS dadweyne wuu isku xiraa, laakiin magacyada gudaha way joogsadaan xallinta.

Xaqiiji gaadhista marka interface-ku jiro

Aqbalidda builder waa barta hubinta koowaad, ma aha tan ugu dambeysa. Marka interface-ku kaco, LinkProperties.getDnsServers() wuxuu muujinayaa waxa shabakaddu runtii heshay, adb shell dumpsys connectivity-na wuxuu daabacaa isla sifooyinka dibadda.

Private DNS waa kontorool gaar ah oo kama gudbo dooddan; magaca martigeliyaha DoT waa habaynta nidaamka, ma aha goob IP.

Ka hor inta aadan mar kale beddelin parser-ka profile-ka, diiwaangeli xarriiqda ceeriin iyo isheeda, xaqiiji in ay tahay literal ma aha magac martigeliye, in aanay ahayn loopback ama wildcard, oo gudbi shayga la falanqeeyay.

Maqaallo la xiriira