മൂല്യം VpnService.Builder.addDnsServer ലേക്ക് സ്ട്രിംഗായി എത്തി, എന്തും സ്ഥാപിക്കുന്നതിന് മുമ്പ് builder അത് അവിടെ നിരസിച്ചു. ഈ നിരസിക്കൽ പ്രാദേശികമാണ്: ഒരു resolver-മായും ബന്ധപ്പെട്ടിട്ടില്ല, tunnel ഇല്ല, പരാജയപ്പെട്ടത് ഫോർമാറ്റ് പരിശോധനയാണ്, DNS അല്ല.

സാധാരണ VPN ആപ്പിൽ മൂന്ന് സമാന DNS ഇൻപുട്ടുകൾ ഉള്ളതിനാൽ ഇത് പ്രധാനമാണ്: പ്രൊഫൈലിലെ മൂല്യം, സർവർ അയക്കുന്ന മൂല്യം, സിസ്റ്റം തലത്തിലെ Private DNS. ആദ്യ രണ്ടെണ്ണം മാത്രമാണ് ഈ കോളിൽ എത്തുന്നത്.

തയ്യാറെടുപ്പ് ഒബ്ജക്ട് ആർഗ്യുമെന്റ് ഉടൻ പരിശോധിക്കുന്നു

VpnService.Builder tunnel അല്ല. വിലാസങ്ങളും റൂട്ടുകളും സർവറുകളും ശേഖരിക്കുന്ന തയ്യാറെടുപ്പ് ഒബ്ജക്ട് ആണ് ഇത്, establish() മാത്രമാണ് ആ പട്ടികകളെ ജീവനുള്ള ParcelFileDescriptor ഉം ഇന്റർഫേസും ആക്കുന്നത്. DNS എൻട്രി addDnsServer വിളിക്കുമ്പോൾ പരിശോധിക്കുന്നു.

രണ്ട് ഫലങ്ങൾ: സ്റ്റാക്ക് ട്രെയ്സ് ചെറുതും ബോധപൂർവം വിവരരഹിതവുമാണ്, അശ്രദ്ധയുള്ള catch resolver ഇല്ലാത്ത tunnel വിടുന്നു.

builder നൽകുന്ന ഏത് പട്ടികയും സൂക്ഷിക്കുന്നു; പരിശോധന കടക്കുന്ന സർവർ ചേർക്കുന്നത് നിർമ്മാണ സമയത്ത് സ്ട്രിംഗ് വിലാസ ലിറ്ററലായി വിശകലനം ചെയ്തു എന്ന് മാത്രം തെളിയിക്കുന്നു.

ആർഗ്യുമെന്റ് എന്താകാം

പാരാമീറ്റർ വിലാസമാണ്, endpoint അല്ല. Builder റഫറൻസ് IPv4 അല്ലെങ്കിൽ IPv6 ലിറ്ററൽ സ്വീകരിക്കുന്നു, വിശകലനം സംഖ്യാപരം മാത്രം: android.net.InetAddresses.parseNumericAddress API 29 മുതൽ ആ parser-ന്റെ പൊതുമുഖം.

പ്രായോഗിക മാപ്പിംഗ് ഇങ്ങനെയാണ്:

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

പതിപ്പ് നിങ്ങൾ എങ്ങനെ സാധൂകരിക്കുന്നു എന്നതിനെ ബാധിക്കുന്നു, builder എന്ത് സ്വീകരിക്കുന്നു എന്നതിനെയല്ല. InetAddresses API 29 മുതൽ ലഭ്യമാണ്, അതിനാൽ Android 10-ൽ വിശകലനം ഒരു കോളാണ്; addDnsServer(InetAddress) യഥാർത്ഥ രൂപം, String പുതിയ കൂട്ടിച്ചേർക്കൽ. API 29-ന് താഴെ InetAddress.getByName തടയുന്ന നെറ്റ്‌വർക്ക് തിരയലിലൂടെ ഹോസ്റ്റ്നെയിം പരിഹരിക്കും.

loopback ഇവിടെ നിരസിക്കപ്പെടുന്നു, wildcard അല്ല

ഡെസ്ക്ടോപ്പ് VPN ക്ലയന്റുകൾ സ്വന്തം stub resolver 127.0.0.1:53 ലേക്ക് അയക്കുന്നു; അത് Android പ്രൊഫൈലിലേക്ക് പകർത്തിയാൽ പ്രാദേശിക മെഷീനെ വിവരിക്കുന്ന മൂല്യം കടക്കും, ഇവിടെ പ്രാദേശിക മെഷീൻ ഇല്ല. builder ഈ സാഹചര്യം മാത്രം നിരസിക്കുന്നു: null അല്ലെങ്കിൽ loopback വിലാസം IllegalArgumentException എറിയുന്നു.

wildcard വിപരീത സാഹചര്യമാണ്, ഇവിടെയാണ് ഈ പിശകിന്റെ മിക്ക വായനകളും തെറ്റുന്നത്. 0.0.0.0 ഉം :: ഉം loopback അല്ല, അതിനാൽ builder അവ സ്വീകരിക്കുന്നു; നിർമ്മാണത്തിൽ ഒന്നും എറിയുന്നില്ല. പിന്നീട് ഇന്റർഫേസ് ഒരു ലക്ഷ്യവും പേരിടാത്ത എൻട്രിയുമായി ഉയരുന്നു. അത് പിടിക്കേണ്ടത് നിങ്ങളുടെ വാലിഡേറ്ററിന്റെ ജോലിയാണ്: isAnyLocalAddress അസാധുവായ ഇൻപുട്ടായി കാണുക.

കോൺഫിഗറേഷൻ അതിരിൽ ഒരിക്കൽ വിശകലനം ചെയ്യുക

വിലകുറഞ്ഞ പരിഹാരം സ്ട്രിംഗ് നിങ്ങളുടെ മോഡലിലേക്ക് കടക്കുന്നിടത്ത് സാധൂകരിക്കുകയാണ്:

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

null ഫലം കുറ്റക്കാരനായ പാഠം വഹിക്കുന്ന ഫീൽഡ് തല പിശകാകുന്നു, പിന്തുണയ്ക്ക് പ്രവർത്തിക്കാനാകുന്ന ഏക രൂപം അതാണ്. വിജയ പാതയിൽ ഒബ്ജക്ട് നേരിട്ട് builder.addDnsServer(address) ലേക്ക് പോകുന്നു, IllegalArgumentException നിർദ്ദിഷ്ടമായി പിടിക്കുക, Exception അല്ല.

ലക്ഷ്യമിട്ട മൂല്യം നിരസിക്കപ്പെടുമ്പോൾ പൊതു resolver ഉപയോഗിച്ച് മാറ്റരുത്; നിശബ്ദമായി പൊതു DNS ഇടുന്ന പ്രൊഫൈൽ കണക്ട് ചെയ്യും, പക്ഷേ ആന്തരിക നാമങ്ങൾ പരിഹരിക്കപ്പെടുന്നത് നിലയ്ക്കും.

ഇന്റർഫേസ് ഉണ്ടായതിന് ശേഷം എത്തിച്ചേരൽ സ്ഥിരീകരിക്കുക

builder-ന്റെ സ്വീകാര്യത ആദ്യ പരിശോധനാ പോയിന്റാണ്, അവസാനമല്ല. ഇന്റർഫേസ് ഉയർന്ന ശേഷം LinkProperties.getDnsServers() നെറ്റ്‌വർക്ക് യഥാർത്ഥത്തിൽ എന്ത് ലഭിച്ചു എന്ന് കാണിക്കുന്നു, adb shell dumpsys connectivity അതേ ഗുണങ്ങൾ പുറത്തുനിന്ന് പ്രിന്റ് ചെയ്യുന്നു.

Private DNS വേറിട്ട നിയന്ത്രണമാണ്, ഈ ആർഗ്യുമെന്റിലൂടെ കടക്കുന്നില്ല; DoT ദാതാവിന്റെ ഹോസ്റ്റ്നെയിം സിസ്റ്റം ക്രമീകരണത്തിന്റേതാണ്, IP ഫീൽഡിന്റേതല്ല.

പ്രൊഫൈൽ parser വീണ്ടും മാറ്റുന്നതിന് മുമ്പ് അസംസ്കൃത സ്ട്രിംഗും അതിന്റെ ഉറവിടവും രേഖപ്പെടുത്തുക, അത് ഹോസ്റ്റ്നെയിം അല്ലാത്ത ലിറ്ററലാണെന്ന്, loopback അല്ലെങ്കിൽ wildcard അല്ലെന്ന് ഉറപ്പാക്കുക, വിശകലനം ചെയ്ത ഒബ്ജക്ട് കൈമാറുക.

അനുബന്ധ ലേഖനങ്ങൾ