చాలా Android యాప్లు VPN గుర్తించడానికి ఉపయోగించే పరిశీలన ఒక ఇంటర్ఫేస్ పేరు, అది ఎప్పుడూ VPN పరిశీలన కాదు. డెవలపర్ ఆశించిన స్ట్రింగ్తో ఏదో ఇంటర్ఫేస్ ఉందని అది నివేదిస్తుంది, అది ఒక పరికరంలో OpenVPN అని, మరొకదానిలో పూర్తిగా సంబంధం లేని ఏదో అని అర్థం. ping అదే రకమైన సాక్ష్యం: ఒక గమ్యం సమాధానం ఇచ్చిందని నిరూపిస్తుంది, ఒక సొరంగం ప్యాకెట్ను తీసుకెళ్లిందని కాదు. ప్లాట్ఫారమ్ నిజంగా బహిర్గతం చేసేది నెట్వర్క్ల సమితి మరియు ప్రతి ఒక్కటి ప్రకటించే రవాణా మార్గాలు, ఇది వేరే సమాధానం ఉన్న వేరే ప్రశ్న.

అపోహ: tun0 ఉంటే VPN అమలులో ఉంది

Android VPN యాప్లు సిస్టమ్కు tun ఫైల్ డిస్క్రిప్టర్ను అందించే VpnService అమలులు. ఇంటర్ఫేస్ పేరు దానిని సృష్టించిన వారి నుండి వస్తుంది: OpenVPN సాధారణంగా tun0 సృష్టిస్తుంది, PPTP మరియు L2TP ppp0 సృష్టిస్తాయి, WireGuard తన ఇంటర్ఫేస్కు సొరంగం పేరు పెడుతుంది, IPsec సొరంగం సాంప్రదాయ పేరునే చూపకపోవచ్చు. కాబట్టి /proc/net/dev చదవడం లేదా NetworkInterface వస్తువులను లెక్కించడం వాస్తవాన్ని కాదు, సంప్రదాయాన్ని వెతుకుతుంది.

లోపం యొక్క రెండు దిశలూ సజీవంగా ఉన్నాయి. పరికరంలో వినియోగదారు VPN కి ఎటువంటి సంబంధం లేని స్థానిక సొరంగానికి tun0 ఉండవచ్చు, పూర్తిగా ఆరోగ్యకరమైన WireGuard సొరంగం tun0 స్ట్రింగ్ మాత్రమే తెలిసిన పరిశీలనకు అదృశ్యంగా ఉండవచ్చు. ఒకే ఫంక్షన్లో తప్పుడు ధనాత్మక మరియు తప్పుడు ఋణాత్మక ఫలితాలు దానిని నిర్ధారణగా ఉపయోగించలేనిదిగా చేస్తాయి, ఎందుకంటే «VPN కనుగొనబడలేదు» అనే మద్దతు టికెట్ను ఏ దిశలోనూ నమ్మలేము.

ప్రవేశం కూడా ఇరుకైంది. కొత్త Android విడుదలలు సాధారణ యాప్ /proc నుండి ఏమి చదవగలదో పరిమితం చేస్తాయి, కాబట్టి Android 8 లో పనిచేసిన పేరు ఆధారిత పరిశీలన ఎటువంటి కోడ్ మార్పు లేకుండా తర్వాతి పరికరంలో ఖాళీ జాబితాను తిరిగి ఇవ్వవచ్చు. పరిశీలన నిశ్శబ్దంగా తెరిచిన వైపుకు విఫలమైనప్పుడు, సొరంగం బాగానే ఉన్న హార్డ్వేర్లో VPN లేదని యాప్ నిర్ధారిస్తుంది.

అపోహ: విజయవంతమైన ping అంటే సొరంగం ట్రాఫిక్ మోస్తోంది

అంతర్గత హోస్ట్కు ping ఆ హోస్ట్కు మార్గం ఉన్నప్పుడల్లా విజయవంతమవుతుంది. విభజిత సొరంగంలో సొరంగం నడుస్తూ పూర్తిగా వేరే పని చేస్తున్నప్పుడు హోస్ట్ Wi-Fi ద్వారా చేరుకోగలిగేదిగా ఉండవచ్చు. ప్రతి యాప్ VPN లో ping చేసే యాప్ సొరంగం నుండి మినహాయించబడవచ్చు, కాబట్టి ICMP ప్రతిధ్వని దాని బయటకు వెళ్లి తిరిగి వస్తుంది, ఇది పరిశీలన ఊహించినదానికి వ్యతిరేకంగా నిరూపిస్తుంది.

ICMP మరియు TCP కూడా విడివిడిగా ఫిల్టర్ అవుతాయి. ప్రతిధ్వని అభ్యర్థనలను అనుమతించి సేవకు అవసరమైన TCP పోర్టును వదిలేయు సొరంగం ping పరీక్షలో ఉత్తీర్ణమై యాప్లో విఫలమవుతుంది, అది పరికరం లక్షణం కాదు, ఎదురుగా ఉన్న ఫైర్వాల్ నియమం. విజయవంతమైన ping యొక్క ఏకైక నిజాయితీ పఠనం ఏమిటంటే ఈ గమ్యం ఈ క్షణంలో ఈ ప్రోటోకాల్కు సమాధానం ఇచ్చింది.

ప్లాట్ఫారమ్ నిజంగా ఏమి నివేదిస్తుంది

API 21 నుండి ConnectivityManager.getAllNetworks() సిస్టమ్కు తెలిసిన ప్రతి నెట్వర్క్ను తిరిగి ఇస్తుంది, getNetworkCapabilities(network) ఆ నెట్వర్క్ ఏమి ప్రకటిస్తుందో నివేదిస్తుంది. VPN నెట్వర్క్ TRANSPORT_VPN కలిగి ఉంటుంది. అన్ని నెట్వర్క్లపై లూప్ చేయడం ఒక ప్రశ్నకు సమాధానం ఇస్తుంది: ఈ పరికరంలో ఇప్పుడు ఏదైనా VPN నడుస్తోందా?

రెండవ, ఇరుకైన ప్రశ్నకు వేరే కాల్ అవసరం. getActiveNetwork() యాప్ ట్రాఫిక్ ఇప్పుడు ఉపయోగించే నెట్వర్క్ను తిరిగి ఇస్తుంది, దానిపై అదే సామర్థ్యాన్ని పరిశీలించడం సమాధానం ఇస్తుంది: నా ట్రాఫిక్ VPN ద్వారా వెళ్తుందా? రెండూ ఏకీభవించకపోవచ్చు, ఆ భేదం సమాచారప్రదం. నడుస్తున్నా ప్రస్తుతం కాని VPN ప్రతి యాప్ రూటింగ్ లేదా విభజిత సొరంగ కాన్ఫిగరేషన్ వైపు సూచిస్తుంది, లేని సొరంగం వైపు కాదు.

Network active = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(active);
boolean viaVpn = caps != null
    && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

రెండు కాల్లను రక్షించండి. జాబితా చేయడం మరియు అడగడం మధ్య అదృశ్యమైన నెట్వర్క్కు సామర్థ్యాలు null కావచ్చు, హ్యాండ్ఓవర్ సమయంలో క్రియాశీల నెట్వర్క్ null కావచ్చు. NET_CAPABILITY_NOT_VPN వ్యతిరేక దిశలో ఉపయోగకరం, నెట్వర్క్కు VPN రవాణా జెండా లేదు అని మాత్రమే కాదు, అది ఖచ్చితంగా సొరంగం కాదని నిర్ధారించడానికి.

NetworkInfo API తో అదే అపోహ

NetworkInfo తో ConnectivityManager.TYPE_VPN ఈ పరిశీలన యొక్క రెండవ తరం, అది ఒక కారణంతో వాడుకలో లేదు. ఆధునిక విడుదలలలో సొరంగం కనెక్ట్ అయి ఉన్నప్పుడు కూడా VPN కోసం తిరిగి ఇచ్చిన వస్తువు null కావచ్చు, కాబట్టి null ను «VPN లేదు» అని పరిగణించే కోడ్ సమాధానం అత్యంత ముఖ్యమైన పరికరాలలో నిశ్శబ్దంగా తప్పుడు ఋణాత్మకాన్ని నివేదిస్తుంది.

సాధారణంగా దానితో వచ్చే ప్రసారం కూడా మెరుగ్గా లేదు. CONNECTIVITY_CHANGE VPN మార్పులను కోల్పోయిన నమోదిత చరిత్రను కలిగి ఉంది, ప్రతి నెట్వర్క్ మార్పు వద్ద కాకుండా VPN కనెక్ట్ లేదా డిస్కనెక్ట్ అయినప్పుడు మాత్రమే ప్రేరేపించిన బిల్డ్లతో సహా. దానిపై నిర్మించిన శ్రోత తదుపరి పూర్తి పునఃకనెక్షన్ వరకు ప్లాట్ఫారమ్ దృష్టి నుండి దూరమయ్యే స్థితి చరాన్ని ఉత్పత్తి చేస్తుంది.

పోలింగ్కు బదులుగా కాల్బ్యాక్లకు స్పందించండి

TRANSPORT_VPN అవసరమయ్యే మరియు NET_CAPABILITY_NOT_VPN తొలగించే NetworkRequest నమోదు చేయండి, తర్వాత ఆ అభ్యర్థనతో registerNetworkCallback కాల్ చేయండి. అప్పుడు ప్రకటన ఎప్పుడు మారుతుందో onAvailable మరియు onLost మీకు చెబుతాయి, అదే మీకు నిజంగా ముఖ్యమైన సంఘటన. భాగం ఆగినప్పుడు కాల్బ్యాక్ నమోదును రద్దు చేయండి, లేకపోతే యాప్ చనిపోయిన స్క్రీన్కు సూచనను ఉంచుతుంది మరియు కాల్బ్యాక్ కొనసాగుతుంది.

NetworkRequest req = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();
cm.registerNetworkCallback(req, callback);

దీనికి ACCESS_NETWORK_STATE అవసరం, అది సాధారణ అనుమతి: root లేదు, వినియోగదారు సమ్మతి సంభాషణ లేదు, VPN అనుమతి లేదు. టైమర్పై పోలింగ్ ప్రజలు ఆశ్రయించే ప్రత్యామ్నాయం, అది బ్యాటరీని కాల్చుతుంది మరియు అంతరం కంటే చిన్న మార్పును కోల్పోతుంది, అదే వినియోగదారు నివేదించే మార్పు.

సమాధానం ఇంకా మీకు చెప్పలేనిది

ఈ API లలో ఏదీ సొరంగం ఆరోగ్యకరమా, ఏ సర్వర్లో ముగుస్తుంది, లేదా నిర్దిష్ట యాప్ ట్రాఫిక్ దానిలో ఉందా అని నివేదించదు. VPN నెట్వర్క్ ఉపయోగించగల మార్గాలు లేకుండా ఉండవచ్చు, ప్రతి యాప్ సొరంగం ప్రశ్న అడిగే యాప్ను మినహాయించవచ్చు.

కాబట్టి పరిశీలన చూసినదాన్ని నమోదు చేయండి, బూలియన్ మాత్రమే కాదు. నెట్వర్క్ గుర్తింపు, ప్రకటించిన రవాణా మార్గాలు, ఆ నెట్వర్క్ క్రియాశీలంగా ఉందా అనేది లాగ్ చేయండి. «VPN కనుగొనబడలేదు» అనే నివేదిక నిరుపయోగం, కానీ ఒక నెట్వర్క్ TRANSPORT_VPN ప్రకటించింది కానీ getActiveNetwork() Wi-Fi తిరిగి ఇచ్చింది అనే నివేదిక నేరుగా రూటింగ్ లేదా మినహాయింపు జాబితా వైపు సూచిస్తుంది, అది ఎవరైనా పని చేయగల సవరణ.

సంబంధిత వ్యాసాలు