Inani lafika ku-VpnService.Builder.addDnsServer njengombhalo, futhi i-builder yalinqaba lapho, ngaphambi kokuba kusungulwe noma yini. Ukunqatshwa lokho kungokwasendaweni: akukho resolver esexhumene nayo, akukho thumela elikhona, futhi okwehlulekile ukuhlola kwefomethi hhayi ukuphazamiseka kwe-DNS. Ukufunda i-trace njengokungqubuzana kokulawulwa kwamandla noma inkinga yohlangothi lweseva kukuthumela engxenyeni engafanele. I-frame isho i-argument enqatshiwe, hhayi isilungiselelo esiyikhiqizile.

Lokho kubalulekile ngoba uhlelo lokusebenza lwe-VPN olujwayelekile lunokokufaka kwe-DNS okuthathu okubukeka kufana: inani elithayiphwa noma elingeniswe kuphrofayela, inani iseva elilicindezelayo ngesikhathi sokulungiselela, kanye ne-Private DNS elungiselelwe ezingeni lesistimu. Kungokokuqala nokwesibili kuphela okungafinyelela leli cingo, futhi kuvamile ukuthi kungokunye kwazo kuphela lapho kuvela khona umbhalo omubi.

Into yokulungiselela ihlola i-argument khona lapho

I-VpnService.Builder akuyo ithumela. Into yokulungiselela eqoqa amakheli, imizila namaseva, futhi yi-establish() kuphela ephendula lezo zinhlu zibe i-ParcelFileDescriptor ephilayo kanye ne-interface. Okufakwa kwe-DNS kuhlolwa lapho ushayela i-addDnsServer, hhayi lapho usungula, yingakho i-exception iphonswa imigqa eminingana ngenhla kwekhodi obukade uyilungisa.

Imiphumela emibili iyalandela. I-stack trace ifushane futhi ayisizi ngamabomu: inani lafika njengombhalo ovamile, futhi i-framework ayikwazi ukwazi ukuthi lavela ekungenisweni kwe-QR, kumthwalo weseva noma ekudluliseni izilungiselelo. Futhi ngenxa yokuthi konke okunye ku-builder kuyasinda ecingweni elihlulekile, i-catch enganakile ezungeze ukwakhiwa okuphelele ikushiya nethumela elinamakheli nemizila kodwa lingenawo nhlobo i-resolver.

I-builder futhi igcina lonke uhlu oluyinika lona. Ukufaka iseva edlula ukuhlola kufakazela kuphela ukuthi umbhalo uhlaziywe njengombhalo wamakheli ngesikhathi sokwakha, futhi icala le-wildcard elingezansi libonisa ukuthi akufakazeli ngisho nokuthi inani liyasebenziseka.

I-argument ivunyelwe ukuba yini

I-parameter iyikheli, hhayi i-endpoint. Incwadi ye-Builder ka-Android yamukela umbhalo we-IPv4 noma we-IPv6, futhi ukuhlaziya okungemuva kwayo kungokwezinombolo kuphela: android.net.InetAddresses.parseNumericAddress iwubuso obala lwalowo mhlaziyi kusukela ku-API 29, futhi ucingo lwe-framework ngokwalo lufika kuyo leyo ndlela efanayo. I-hostname ayilona ikheli elihamba kancane lapha; iwumbhalo ongahlaziyekiyo, futhi ukwehluleka kwalokho kuhlaziya yikho okuvela njenge-exception yekheli elibi.

Ukuhlelwa okusebenzayo kubukeka kanje:

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

Inguqulo ibalulekile endleleni oqinisekisa ngayo, hhayi kulokho i-builder ekwamukelayo. InetAddresses iyatholakala kusukela ku-API 29, ngakho ku-Android 10 nangemuva kwalokho ukuhlaziya kombhalo kuwucingo olulodwa. I-overload nayo ibalulekile: addDnsServer(InetAddress) iyifomu yokuqala, kuyilapho i-overload ye-String iyisengezo esisha, ngakho isampula yombhalo enanyathiselwe ngeke ikwazi ukuhlanganiswa ne-SDK endala. Ngaphansi kwe-API 29, into esikhundleni esobala, InetAddress.getByName, izoxoxa ngokukhululekile i-hostname ngokusesha kwenethiwekhi okubambayo, okuphendula iphutha lokuthayipha libe ukuqala okunensayo esikhundleni sephutha elicacile. Uma usahambisa kulezo zinguqulo, yenza ukuhlola kombhalo ocacile ngaphambi kokuthinta i-API endala.

I-loopback iyanqatshwa lapha, i-wildcard ayinqatshwa

Amaklayenti e-VPN ekhompyutha yedeskithophu avame ukubhekisa i-stub resolver yawo ku-127.0.0.1:53 futhi avumele iklayenti lethumela lidlulise imibuzo. Ukukopisha lokho kuhlelo kuphrofayela ye-Android kungenisa inani elichaza umshini wasendaweni, futhi akukho mshini wasendaweni ongayinikela wona lapha: i-resolver yethumela kufanele ifinyeleleke ngakolunye uhlangothi lwe-interface. Leli yicala elilodwa i-builder ngokwayo eyinqabayo: ikheli eliyi-null noma i-loopback liphonsa i-IllegalArgumentException, njengoba isivumelwano sencwadi sisho.

I-wildcard iyicala eliphambene, futhi yilapho ukufundwa okuningi kwale exception kuphambuka khona. 0.0.0.0 kanye ne-:: akulona i-loopback, ngakho i-builder iyawamukela futhi iwanezela njenganoma yimuphi omunye umbhalo; akukho okuliphonsayo ngesikhathi sokwakha. I-interface bese ivuka nenkomba ye-resolver engasho ndawo eya khona, futhi ukwehluleka kusuka ku-exception kuya emibuzweni ethule engayi ndawo. Ukubamba lokho kuwumsebenzi womhloli wakho, hhayi owe-framework: thatha i-isAnyLocalAddress njengokokufaka okungavumelekile kumsizi ongezansi futhi ukuveze njengephutha lezinga lenkambu.

Hlaziya kanye emngceleni wokulungiselela

Ukulungisa okungabizi ukuhlola lapho umbhalo ungena khona kumodeli yakho bese udlulisa into ehlaziyiwe, ukuze inani i-builder elibonayo libe yinani eliqondile oluhlolisile:

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

Umphumela oyi-null bese uba iphutha lezinga lenkambu elithwala umbhalo oyinkinga, okuwukuphela kwendlela ingxoxo yosekelo engasebenza ngayo. Endleleni yempumelelo, into ebuyisiwe ingena ngqo ku-builder.addDnsServer(address), ngakho inani oluhlolisile yilo elihambayo. Bamba i-IllegalArgumentException ngokukhethekile hhayi i-Exception: ukubamba okubanzi ekhodini yokulungiselela kugwinya noshintsho lwe-null-pointer nezingqubo zesimo obufuna ukuzibona ekwakhiweni kwe-debug.

Phikisa isilinganiso sokufaka i-resolver yomphakathi esikhundleni lapho inani obekuhloswe lona linqatshiwe. Iphrofayela eshintsha ngokuthule ibe yisevisi ye-DNS yomphakathi isaxhuma, kodwa amagama angaphakathi ayeka ukuxazululeka futhi yonke imibuzo iphuma ngokusebenzisa i-resolver umsebenzisi angayikhethanga. Iphutha elibonakalayo libiza impendulo eyodwa yosekelo; ukushintsha okuthule kubiza ukuthembela kokuthi ithumela ligcina imibuzo lapho iphrofayela isho khona.

Qinisekisa ukufinyeleleka ngemuva kokuba i-interface ikhona

Ukumukelwa yi-builder iyindawo yokuqala yokuhlola, hhayi eyokugcina. Uma i-interface isiphakamile, i-LinkProperties.getDnsServers() ibika lokho inethiwekhi ekutholile ngempela, futhi yilapho ukungafani kuvela khona: uhlu olungenalutho, izinto ezimbalwa kunezokwengeza kwakho, noma umndeni imizila yakho engawuthwalayo. I-adb shell dumpsys connectivity inyathelisa izakhiwo ezifanayo zenethiwekhi ngayinye lapho udinga ukubuka ngaphandle kohlelo lokusebenza.

I-Private DNS iyisilawuli esihlukile futhi ayihambi ngale argument. I-hostname yomhlinzeki we-DoT ingeyokulungiselelwa kwesistimu, noma ingeyendlela yakho ye-resolver ebethelwe; akulona inani ongalinamathisela enkambini ye-IP, futhi ukulungisa ukulungiselelwa kwe-Private DNS ngeke kususe i-exception ephonswe yi-builder.

Ngaphambi kokushintsha umhlaziyi wephrofayela futhi, sebenza ngale ndlela: bhala umbhalo ongahlanjululwanga nomthombo wawo, qinisekisa ukuthi uwumbhalo ohambisanayo hhayi i-hostname noma i-URL, qinisekisa ukuthi awulona i-loopback noma i-wildcard, dlulisa into ehlaziyiwe esikhundleni sokuphinda uhlaziya umbhalo, futhi kube yilapho kuphela uqhathanisa i-interface esunguliwe nenani obekuhloswe lona.

Izihloko ezihlobene