ಮೌಲ್ಯವು 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 ಕ್ಷೇತ್ರದದ್ದಲ್ಲ.

ಪ್ರೊಫೈಲ್ ಪಾರ್ಸರ್ ಮತ್ತೆ ಬದಲಿಸುವ ಮೊದಲು ಕಚ್ಚಾ ಸ್ಟ್ರಿಂಗ್ ಮತ್ತು ಅದರ ಮೂಲವನ್ನು ದಾಖಲಿಸಿ, ಅದು ಹೋಸ್ಟ್‌ಹೆಸರು ಅಲ್ಲದ ಲಿಟರಲ್ ಎಂದು, loopback ಅಥವಾ wildcard ಅಲ್ಲ ಎಂದು ಖಚಿತಪಡಿಸಿ, ವಿಶ್ಲೇಷಿತ ವಸ್ತುವನ್ನು ಮುಂದೆ ಕಳುಹಿಸಿ.

ಸಂಬಂಧಿತ ಲೇಖನಗಳು