Ikheli elibi le-addDnsServer: lokho i-Android ekuhlolayo ngempela
Iphutha lekheli elibi elivela ku-addDnsServer ukuhlola kwendawo kokuhlaziya, hhayi ukuphazamiseka kwe-DNS. Hlaziya umbhalo, susa i-loopback nama-wildcard, bese uhlola ukufinyeleleka.
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:
| Input | Result | Reason |
|---|---|---|
10.8.0.1 | accepted | IPv4 literal |
2606:4700:4700::1111 | accepted | IPv6 literal |
dns.example.com | rejected | hostname; numeric parsing does not resolve it |
10.8.0.1:53 | rejected | port belongs to your own config model |
https://dns.example.com/dns-query | rejected | DoH URL, a different configuration path |
127.0.0.1 | rejected | loopback is not a remote resolver |
0.0.0.0 or :: | accepted by the builder | parses 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.