Android VpnService కొంత ట్రాఫిక్ మాత్రమే పట్టుకుంటుంది, అంతా ఎందుకు కాదు
మార్గాలు, DNS నమోదులు మరియు ప్రతి యాప్ పరిధి ఏ ప్యాకెట్లు tun పరికరానికి చేరుతాయో, స్థానిక పరికరాలు ఎందుకు మాయమవుతాయో మరియు నిర్మాత ఏమి నిరాకరిస్తాడో నిర్ణయిస్తాయి.
VpnService లో ఏదీ తనంతట తాను ట్రాఫిక్ను పట్టుకోదు. ఇది సిస్టమ్ను tun ఇంటర్ఫేస్ అడుగుతుంది, ఆ ఇంటర్ఫేస్కు చిరునామాలు మరియు మార్గాల సమితిని ఇస్తుంది, ఆ క్షణం నుండి కెర్నల్ ఆ మార్గాలతో సరిపోలే ప్రతి ప్యాకెట్ను యాప్ చదవగల ఫైల్ డిస్క్రిప్టర్లోకి కాపీ చేస్తుంది. యాప్ కోడ్ మార్గాలు ఎంచుకోని ప్యాకెట్లను ఎప్పుడూ చూడదు, కాబట్టి టన్నెల్ పరిధి ప్రోగ్రామింగ్ ప్రశ్న కాకముందే రూటింగ్ పట్టిక ప్రశ్న. అందుకే అదే సేవా అమలు ఒక ఫోన్లో ప్రతి ప్రవాహాన్ని మింగగలదు మరొకదానిలో కొంత భాగాన్ని మాత్రమే, అందుకే మార్గాన్ని జోడించడం కొన్నిసార్లు విరిగినట్లు కనిపించిన టన్నెల్ను సరిచేస్తుంది. మీరు పొందేది మీరు ప్రకటించినదే, నిర్మాత నిశ్శబ్దంగా నిరాకరించినదంతా తీసివేసి.
ఏ ప్యాకెట్లు వస్తాయో మార్గాలు నిర్ణయిస్తాయి
Builder.addRoute(prefix, prefixLength) VPN నెట్వర్క్ రూటింగ్ పట్టికలో ప్రిఫిక్స్ను ఇన్స్టాల్ చేస్తుంది. సిస్టమ్ ఆ నెట్వర్క్ను పరిధిలోని యాప్లకు డిఫాల్ట్గా పరిగణిస్తుంది, కాబట్టి దాని నమోదులు భౌతిక నెట్వర్క్ డిఫాల్ట్ మార్గానికి ముందే చూడబడతాయి, సరిపోలే ప్రిఫిక్స్ ఒక ప్రవాహాన్ని మళ్లించడానికి సరిపోతుంది. అందుకే 0.0.0.0/0 కోసం మార్గం IPv4 మొత్తాన్ని తీసుకుంటుంది, ప్రింటర్, cast లక్ష్యం మరియు రౌటర్ నిర్వాహక పేజీతో సహా.
భౌతిక డిఫాల్ట్ నమోదును తొలగించకుండా ఆ కవరేజీ కావాలనుకునే క్లయింట్లు బదులుగా 0.0.0.0/1 మరియు 128.0.0.0/1 జోడిని ఉపయోగిస్తారు. రెండు మరింత నిర్దిష్ట మార్గాలు డిఫాల్ట్ మార్గాన్ని ఓడిస్తాయి, కలిసి అవి మొత్తం చిరునామా స్థలాన్ని కవర్ చేస్తాయి, ఫోన్ స్వంత డిఫాల్ట్ నమోదు ఇంకా భౌతిక నెట్వర్క్కు కట్టుబడి ఉన్న సాకెట్ల కోసం పట్టికలో ఉంటుంది.
చిరునామాలు మరియు DNS నమోదులు అదే నిర్మాత నుండి వచ్చి మరొక ప్రశ్నకు సమాధానమిస్తాయి. addAddress ఇంటర్ఫేస్కు ప్రిఫిక్స్ పొడవుతో చిరునామా ఇస్తుంది, addDnsServer పరిధిలోని యాప్లు ఇంటర్ఫేస్ ద్వారా అడిగే పరిష్కర్తను ఇన్స్టాల్ చేస్తుంది. రెండు కుటుంబాలు ఒకే ఇంటర్ఫేస్పై ఉండవచ్చు, కాబట్టి IPv6 చిరునామా పక్కన IPv4 మాత్రమే మార్గాల సమితి సరిగ్గా చదవబడుతూ ఇంకా లీక్ అయ్యే కాన్ఫిగరేషన్. ఇంటర్ఫేస్కు చిరునామా లేని కుటుంబాన్ని మార్గపరచినట్లయితే, కెర్నల్కు ఆ ప్యాకెట్లకు మూల చిరునామా ఉండదు, అవి ఎప్పుడూ డిస్క్రిప్టర్ వద్ద కనిపించవు.
establish() ఏమి తిరిగి ఇస్తుంది
establish() ParcelFileDescriptor తిరిగి ఇస్తుంది, లేదా యాప్కు అధికారం లేనప్పుడు null. null నెట్వర్క్ లోపం కాదు, సమ్మతి స్థితి: VpnService.prepare() ఇప్పటికే null తిరిగి ఇచ్చి ఉండాలి, లేదా వినియోగదారు కాల్కు ముందే సిస్టమ్ సంభాషణను ఆమోదించి ఉండాలి. సేవ నడుస్తున్నప్పుడు సమ్మతి ఉపసంహరించబడవచ్చు, ఇంటర్ఫేస్ మీ చదవడం లూప్కు ఎలాంటి కాల్బ్యాక్ లేకుండా మీ కాళ్ల కింద మూసుకుపోతుంది.
మీరు వేరే చెప్పకపోతే డిస్క్రిప్టర్ బ్లాక్ చేయదు, కాబట్టి చదవడం థ్రెడ్ను ఆపకుండా డేటా లేకుండా వెంటనే తిరిగి వస్తుంది. బ్లాకింగ్ సాకెట్ కోసం రాసిన లూప్ ఒక కోర్ను కాల్చేస్తుంది, ఖాళీ చదవడాన్ని ప్రాణాంతకంగా భావించే లూప్ నిష్క్రియ సెకనులో టన్నెల్ను చింపివేస్తుంది. Builder.setBlocking(true) ఆ ప్రవర్తనను మారుస్తుంది, ధర చదవడం లోపల వేచి ఉండే థ్రెడ్.
మార్గం మరియు చిరునామా ఆర్గ్యుమెంట్లు LinkAddress విలువలుగా ధృవీకరించబడతాయి, 224.0.0.0/4 వంటి మల్టీకాస్ట్ గమ్యాలు నేరుగా తిరస్కరించబడతాయి. పాయింట్-టు-పాయింట్ tun ఇంటర్ఫేస్కు బ్రాడ్కాస్ట్ డొమైన్ కూడా ఉండదు, కాబట్టి దాని ద్వారా మల్టీకాస్ట్ అన్వేషణకు మరో మార్గం కాదు, వేరే రూపకల్పన కావాలి. తనిఖీ చేయవలసిన జాబితా VpnService.Builder అని, కాల్ విస్మరించబడిందని నిర్ణయించే ముందు.
యాప్ వారీ పరిధి సమితిని తగ్గిస్తుంది, టన్నెల్ను కాదు
API 21 నుండి నిర్మాత addAllowedApplication మరియు addDisallowedApplication అంగీకరిస్తుంది, రెండు జాబితాలు ఒకే నిర్మాతలో పరస్పరం మినహాయించుకుంటాయి. అనుమతి జాబితా ఆ ప్యాకెట్లకు టన్నెల్ ఉండేలా చేస్తుంది, మిగతావన్నీ భౌతిక నెట్వర్క్ను ఉంచుతాయి; నిషేధ జాబితా పేరు పెట్టిన ప్యాకెట్లు తప్ప అన్నింటినీ పడుతుంది, దాన్ని క్లయింట్ విభజిత టన్నెలింగ్గా అందిస్తుంది. API 21 కు ముందు వేదిక యంత్రాంగం అసలే లేదు, యాప్ వారీ ప్రవర్తన తమ ఫార్వర్డర్లో UID ప్రకారం ఫిల్టర్ చేసే తృతీయ పక్ష క్లయింట్ల నుండి వచ్చింది. డీబగ్ చేసేటప్పుడు ఈ భేదం ముఖ్యం, ఎందుకంటే ఒక ప్యాకెట్ అనుమతి జాబితాతో ఉన్న యాప్ వారీ టన్నెల్ దాదాపు ట్రాఫిక్నే ఉత్పత్తి చేయదు, అది సరైన ప్రవర్తన, విరిగిన మార్గం కాదు.
పరిధి ఏదైనా, మీ యాప్ VPN సర్వర్కు తెరిచే సాకెట్ అది నిర్మిస్తున్న టన్నెల్ గుండా ప్రయాణించకూడదు. VpnService.protect(socket) ఆ సాకెట్ను అంతర్లీన నెట్వర్క్కు కట్టివేస్తుంది, దాని ప్యాకెట్లు tun పరికరాన్ని దాటవేస్తాయి. కాల్ను దాటవేస్తే, చేతులు కలపడం దాన్ని ఎత్తాల్సిన ఇంటర్ఫేస్ మింగేస్తుంది.
VpnService.setUnderlyingNetworks ఏ భౌతిక నెట్వర్క్ టన్నెల్ను మోస్తుందో సిస్టమ్కు చెప్పి వృత్తాన్ని మూస్తుంది. ఆ విలువ VPN ఇతర యాప్లకు కనెక్టివిటీని ఎలా నివేదిస్తుందో నిర్ణయిస్తుంది, null లేదా పాత విలువ ఫోన్ మిగిలిన భాగం ఆఫ్లైన్గా భావించే కనెక్ట్ అయిన టన్నెల్కు సాధారణ కారణం. అంతర్లీన నెట్వర్క్ మారినప్పుడు దాన్ని నవీకరించండి, ప్రారంభంలో మాత్రమే కాదు.
చెక్సమ్లు మరియు MTU: సరైన మార్గం కూడా విఫలమయ్యే చోటు
ప్యాకెట్లు వచ్చిన తర్వాత, ప్యాకెట్ స్థాయిలో రెండు వివరాలు ఏదైనా ఒక చివర నుండి మరొక చివర వరకు పనిచేస్తుందా అని నిర్ణయిస్తాయి. మొదటిది మూల చిరునామా: అనేక ఇంటర్ఫేస్ చిరునామాలు ఉంటే కెర్నల్ మొదటిదాన్ని మోసే ప్యాకెట్లను పంపవచ్చు, కాబట్టి శీర్షికలను తిరిగి రాసే ఫార్వర్డర్ చిరునామాను మరియు దాన్ని కవర్ చేసే చెక్సమ్ను సరిచేయాలి.
రెండవది చెక్సమ్ పరిధి. యాప్ తానే TCP లేదా UDP ప్యాకెట్లను నిర్మించినప్పుడు, చెక్సమ్ మూల చిరునామా, గమ్య చిరునామా, ప్రోటోకాల్ సంఖ్య మరియు రవాణా పొడవు ఉన్న స్యూడో-శీర్షికను కవర్ చేస్తుంది, వాటిలో ఏదైనా వదిలేస్తే వచ్చి పారేయబడే ప్యాకెట్లు వస్తాయి. ఆ వైఫల్యం ఎప్పుడూ రాని జవాబు తర్వాత సమయం ముగిసినట్లు కనిపిస్తుంది, అది చాలామందిని మళ్లీ మార్గాల వైపు పంపుతుంది. setMtu ఇంటర్ఫేస్ MTUని నిర్ణయిస్తుంది, ప్రతి చదవడం సరిగ్గా ఒక పూర్తి IP ప్యాకెట్ను తిరిగి ఇస్తుంది, కాబట్టి బైట్ ప్రవాహం కోసం రాసిన బఫర్ ప్యాకెట్ను కాదు, మీ పార్సింగ్ను ముక్కలు చేస్తుంది.
పొరలను వేరు చేసే ధృవీకరణ పర్యాయం
పరిధి ఎక్కడ తప్పైందో కనుగొనడానికి పొరలను వరుసగా పరీక్షించండి. VPN నెట్వర్క్ నిజంగా ఏ మార్గాలను కలిగి ఉందో పరికరాన్ని అడగండి, తర్వాత తెలిసిన చిరునామాకు ప్రవాహం డిస్క్రిప్టర్పై చదవడంగా కనిపిస్తుందా చూడండి, తర్వాత మీ ఫార్వర్డర్ పంపే ప్యాకెట్ చక్కగా రూపొందిందా చూడండి. మార్గ సమస్య డిస్క్రిప్టర్పై ఏమీ చూపదు, చెక్సమ్ సమస్య వచ్చి మాయమయ్యే ప్యాకెట్ను చూపుతుంది.
డిస్క్రిప్టర్ను ఏదీ చేరకపోతే, అనుమానితుడు చదివేవాడు కాదు, మార్గాల సమితి: ప్రిఫిక్స్లను ధృవీకరించండి, అదే కుటుంబంలో చిరునామా ఉందని ధృవీకరించండి, యాప్ మీరు నిర్ణయించిన పరిధిలో ఉందని ధృవీకరించండి. ప్యాకెట్లు డిస్క్రిప్టర్ను చేరినా ఏదీ తిరిగి రాకపోతే, మళ్లీ మార్గాన్ని తాకే ముందు protect() మరియు అంతర్లీన నెట్వర్క్ విలువను తనిఖీ చేయండి. దూరపు వైపు వికృత ప్యాకెట్లను నివేదిస్తే, చెక్సమ్ మరియు MTU చూడవలసిన స్థలాలు. ప్రతి పొరకు ఒక పరీక్ష అర్ధరోజు ఊహను ఆదా చేస్తుంది.