Il-valur wasal għand VpnService.Builder.addDnsServer bħala string, u l-builder rrifjutah hemmhekk, qabel ma ġie stabbilit xejn. Dan ir-rifjut huwa lokali: l-ebda resolver ma ġie kkuntattjat, l-ebda tunnel ma jeżisti, u li falla huwa verifika tal-format, mhux waqfa tad-DNS. Jekk taqra t-trace bħala konflitt tal-ġestjoni tal-enerġija jew problema fuq in-naħa tas-server, tmur fil-layer ħażin. Il-frame issemmi l-argument li ġie rrifjutat, mhux is-setting li pproduċieh.

Dan huwa importanti għax app VPN tipika għandha tliet inputs tad-DNS li jixbħu lil xulxin: valur miktub jew importat fil-profil, valur li s-server jimbotta waqt il-konfigurazzjoni, u Private DNS ikkonfigurat fil-livell tas-sistema. L-ewwel tnejn biss jistgħu jaslu għal din is-sejħa, u normalment wieħed minnhom biss huwa minn fejn tiġi l-string ħażina.

Oġġett ta' staging jivverifika l-argument fuq il-post

VpnService.Builder mhuwiex it-tunnel. Huwa oġġett ta' staging li jiġbor indirizzi, rotot u servers, u establish() biss ibiddel dawk il-listi f'ParcelFileDescriptor ħaj u f'interface. Id-dħul tad-DNS jiġi vverifikat meta ssejjaħ addDnsServer, mhux meta tistabbilixxi, u għalhekk l-eċċezzjoni tinxteħet diversi linji 'l fuq mill-kodiċi li kont qed tiddibaggja.

Isiru żewġ konsegwenzi. Ix-stack trace huwa qasir u mhux ta' għajnuna apposta: il-valur wasal bħala string sempliċi, u l-framework ma jistax ikun jaf jekk ġiex minn importazzjoni QR, minn payload tas-server jew minn override tas-settings. U għax kull ħaġa oħra fil-builder tgħaddi mis-sejħa li falliet, catch traskurat madwar il-build kollu jħallik b'tunnel li għandu indirizzi u rotot imma xejn resolver.

Il-builder iżomm ukoll kull lista li tagħtih. Iżżid server li jgħaddi mill-verifika jipprova biss li l-string ġiet ipparsjata bħala literal tal-indirizz fil-ħin tal-build, u l-każ tal-wildcard hawn taħt juri li ma jipprovax lanqas li l-valur huwa użabbli.

X'inhu permess li jkun l-argument

Il-parametru huwa indirizz, mhux endpoint. Il-referenza tal-Builder ta' Android tistipula literal IPv4 jew IPv6, u l-parse warajh huwa numeriku biss: android.net.InetAddresses.parseNumericAddress huwa l-wiċċ pubbliku ta' dak il-parser mill-API 29, u s-sejħa tal-framework stess tasal fl-istess rutina. Hostname mhuwiex indirizz bil-mod hawnhekk; huwa string li ma tistax tiġi pparsjata, u dak il-falliment tal-parse huwa li jiġi f'wiċċ l-ilma bħala eċċezzjoni ta' bad address.

Il-mappa prattika tidher hekk:

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

Il-verżjoni hija importanti għal kif tivvalida, mhux għal dak li l-builder jaċċetta. InetAddresses huwa disponibbli mill-API 29, għalhekk fuq Android 10 u wara l-parse tal-literal hija sejħa waħda. L-overload huwa importanti wkoll: addDnsServer(InetAddress) hija l-forma oriġinali, filwaqt li l-overload String hija l-addizzjoni l-ġdida, għalhekk kampjun ta' string ippejstjat mhux se jikkompila ma' SDK anzjani. Taħt l-API 29, is-sostitut ovvju, InetAddress.getByName, se jirrisolvi hostname b'lookup tan-netwerk li jimblokka, u dan ibiddel typo f'tnedija bil-mod minflok żball ċar. Jekk għadek tipprovdi għal dawk il-verżjonijiet, agħmel test espliċitu tal-literal qabel ma tmiss l-API anzjana.

Loopback jiġi rrifjutat hawn, wildcard le

Il-klijenti VPN tad-desktop spiss idawwru l-istub resolver tagħhom lejn 127.0.0.1:53 u jħallu l-klijent tat-tunnel jgħaddi l-queries. L-ikkupjar ta' dak l-arranġament fi profil Android jimporta valur li jiddeskrivi l-magna lokali, u hawn m'hemm l-ebda magna lokali lil min tagħtiha: ir-resolver tat-tunnel irid ikun reachable fuq in-naħa l-oħra tal-interface. Dan huwa l-unika każ li l-builder stess jirrifjuta: indirizz null jew loopback iniżżel IllegalArgumentException, kif jgħid il-kuntratt ta' referenza.

Wildcard huwa l-każ oppost, u hawn fejn ħafna qarigiet ta' din l-eċċezzjoni jmorru ħażin. 0.0.0.0 u :: mhumiex loopback, għalhekk il-builder jaċċettahom u jżidhom bħal kull literal ieħor; xejn ma jinxteħet fil-ħin tal-build. L-interface imbagħad titla' b'dħul ta' resolver li ma jsemmi l-ebda destinazzjoni, u l-falliment jgħaddi minn eċċezzjoni għal queries li bil-kwiet ma jmorru imkien. Li taqbad dan huwa xogħol tal-validator tiegħek, mhux tal-framework: ittratta isAnyLocalAddress bħala input invalid fil-helper hawn taħt u urih bħala żball fil-livell tal-field.

Ipparsja darba fil-konfini tal-konfigurazzjoni

Is-soluzzjoni rħisa hija li tivvalida fejn il-string tidħol fil-mudell tiegħek u tgħaddi l-oġġett ipparsjat 'il quddiem, sabiex il-valur li jara l-builder ikun eżattament il-valur li vvalidajt:

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

Riżultat null imbagħad isir żball fil-livell tal-field li jġorr it-test offensiv, u din hija l-unika forma li konversazzjoni ta' appoġġ tista' taġixxi fuqha. Fil-passaġġ ta' suċċess l-oġġett irritornat jidħol direttament f'builder.addDnsServer(address), u għalhekk il-valur li vvalidajt huwa l-valur li jinħareġ. Aqbad IllegalArgumentException b'mod speċifiku minflok Exception: catch wiesa' fuq kodiċi ta' konfigurazzjoni jibla' wkoll il-bugs tan-null-pointer u tal-istat li trid tara f'build ta' debug.

Irreżisti l-fallback li tissostitwixxi resolver pubbliku meta l-valur maħsub jiġi rrifjutat. Profil li bil-kwiet ibiddel għal servizz DNS pubbliku xorta jikkonnettja, imma l-ismijiet interni jieqfu jirrisolvu u kull query toħroġ minn resolver li l-utent ma għażilx. Żball viżibbli jiswa tweġiba waħda ta' appoġġ; is-sostituzzjoni silenzjuża tiswa l-fiduċja li t-tunnel iżomm il-queries fejn jgħid il-profil.

Ikkonferma r-reachability wara li jkun jeżisti l-interface

L-aċċettazzjoni mill-builder hija l-ewwel checkpoint, mhux l-aħħar. Meta l-interface tkun telgħet, LinkProperties.getDnsServers() jirrapporta dak li n-netwerk fil-fatt irċieva, u hawn fejn jidher nuqqas ta' qbil: lista vojta, inqas dħul milli żidt, jew familja li r-rotot tiegħek ma jġorrux. adb shell dumpsys connectivity jistampa l-istess proprjetajiet kull netwerk meta jkollok bżonn tara minn barra l-app.

Private DNS huwa kontroll separat u ma jgħaddix minn dan l-argument. Hostname ta' provider DoT jappartjeni għas-setting tas-sistema, jew għall-passaġġ tar-resolver encrypted tiegħek; mhuwiex valur li tpejstjah f'field tal-IP, u li tissewwi setting ta' Private DNS mhux se jneħħi eċċezzjoni imxettla mill-builder.

Qabel ma terġa' tbiddel il-parser tal-profil, ħadem dan l-ordni: illoggja l-string nejja u l-oriġini tagħha, ikkonferma li hija literal u mhux hostname jew URL, ikkonferma li mhijiex loopback u lanqas wildcard, għaddi l-oġġett ipparsjat minflok terġa' tipparsja t-test, u mbagħad biss qabbel l-interface stabbilita mal-valur li kellek f'moħħok.

Artikli relatati