மதிப்பு 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 அவற்றை ஏற்கிறது; கட்டும்போது எதுவும் வீசப்படுவதில்லை. பின்னர் இடைமுகம் இலக்கைக் குறிப்பிடாத உள்ளீட்டுடன் எழுகிறது. அதைப் பிடிப்பது உங்கள் validator இன் வேலை: 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 அல்ல என்பதையும் உறுதிப்படுத்தி, பகுப்பாய்வு செய்யப்பட்ட பொருளை அனுப்புங்கள்.

தொடர்புடைய கட்டுரைகள்