तुम्ही एक डोमेन परवानगी यादीत टाकले, क्वेरी तुमच्या अ‍ॅपपर्यंत पोहोचते, जुळणीकर्ता परवानगी दिली असे परत करतो, आणि तरीही पान कधीही लोड होत नाही. त्या टप्प्यावर बहुतेक लोक जुळणीकर्ता पुन्हा लिहायला आणि वाइल्डकार्ड तुलना जोडायला लागतात. माझ्या अनुभवात जुळणीकर्ता सहसा बरोबर असतो, आणि बिघाड एका स्तराखाली असतो: तुम्ही तयार केलेल्या DNS उत्तरात, तुम्ही बसवलेल्या मार्गात, किंवा क्वेरी पुढे पाठवण्यासाठी वापरलेल्या सॉकेटमध्ये. यादी सोपा भाग आहे; पॅकेटचा मार्ग म्हणजे परवानगी याद्या तुटतात ती जागा.

जुळणीकर्ताच दोषी असतो असे क्वचितच

प्रथम वेगळे करायचे ते म्हणजे अडवलेले आणि तुटलेले. अडवलेले नाव वेगाने आणि दिसण्याजोगे अयशस्वी व्हायला हवे, कारण ब्राउझरला नाव अस्तित्वात नाही असे उत्तर मिळते आणि तो थांबतो. तुटलेले नाव अडकते, IPv6 वर पुन्हा प्रयत्न करते, दुसऱ्या वाहतुकीवर जाते, आणि तुम्हाला फिरणारे निर्देशक सोडते. तुम्हाला फिरणारे निर्देशक दिसत असेल, तर तुमची परवानगी यादी क्लायंट काहीही करू शकत नाही अशा गोष्टीचे उत्तर देत असावी.

रिकामा A रेकॉर्ड ही नेहमीची चूक आहे. शून्य उत्तरांसह NOERROR परत करणे वैध उत्तरासारखे दिसते, म्हणून stub रिझॉल्व्हर ते स्वीकारतो, ब्राउझर पुन्हा प्रयत्न करतो, AAAA वापरून पाहतो, दुसरा रिझॉल्व्हर वापरतो, आणि खूप उशिरा हार मानतो. प्रश्न विभाग पुनरावृत्त करून आणि व्यवहार ID ची प्रत करून दिलेला उत्तर कोड 3, म्हणजे NXDOMAIN, संभाषण लगेच संपवतो. तुम्ही जाणूनबुजून नाकारता त्या प्रत्येक नावासाठी तो वापरा.

IPv6 लाही डीफॉल्टऐवजी तोच निर्णय मिळायला हवा. तुम्ही A साठी NXDOMAIN उत्तर दिले आणि AAAA जाऊ दिले, तर क्लायंट IPv6 वरून अडवलेल्या नावापर्यंत पोहोचू शकतो आणि गाळणी गळते. काही अंमलबजावणी अडवलेल्या AAAA क्वेरींना loopback पत्त्याने उत्तर देतात जेणेकरून पर्यायाकडे न जाता कनेक्शन लगेच अयशस्वी होईल. एक धोरण निवडा, ते दोन्ही रेकॉर्ड प्रकारांवर लागू करा, आणि दोन्ही नोंदवा.

सर्व काही पकडणारा मार्ग सर्वांचा मालक असतो

फक्त DNS वाली रचना कधीही addRoute("0.0.0.0", 0) जोडत नाही, म्हणून TUN इंटरफेसमध्ये फक्त क्वेरीज येतात आणि बाकी सर्व खालचे नेटवर्क वापरत राहते. हाच सुरक्षित आकार, आणि काही परवानगी याद्या Wi-Fi वर चालतात पण मोबाइल नेटवर्कवर अयशस्वी होतात याचेही हेच कारण.

डीफॉल्ट मार्ग अस्तित्वात येण्याच्या क्षणापासून प्रत्येक प्रवाह तुमचा आहे. इंटरफेसवर येऊन पुढे न पाठवलेला किंवा उत्तर न मिळालेला TCP पॅकेट क्लायंटची वेळ संपेपर्यंत रांगेत बसतो, आणि नोंदवण्यासाठी त्रुटी नसते कारण काहीच चुकले नाही. कोणीतरी दुपारभर तुटलेल्या परवानगी यादीवर घालवताना मी पाहिले, जी प्रत्यक्षात पोर्ट 443 साठी गहाळ फॉर्वर्डर होती. तुम्ही टाकून देण्याचा निर्णय घेता त्या प्रत्येक पॅकेटचा प्रोटोकॉल आणि गंतव्य नोंदवा.

रिझॉल्व्हर सॉकेटने बोगद्याबाहेर जायला हवे

पुढे पाठवणे ही पुढील सापळ्याची जागा. कॅरियर रिझॉल्व्हर बहुधा अशा खाजगी पत्त्यावर असतात जिथे बोगदा पोहोचत नाही, म्हणून तुम्ही पुढे पाठवलेली क्वेरी कुठेही जात नाही आणि अ‍ॅप वाचन कालबाह्यता नोंदवते. मंजूर क्वेरीज तुम्हाला पोहोचण्यायोग्य माहीत असलेल्या रिझॉल्व्हरकडे पाठवा, आणि ते सॉकेट आधी VpnService.protect() ला द्या. असुरक्षित सॉकेट क्वेरी तुमच्याच बोगद्यात परत पाठवते, जिथे ती पुन्हा अ‍ॅपपर्यंत पोहोचते आणि कालबाह्यता सक्रिय होईपर्यंत फिरत राहते.

बिघाड नेटवर्क खंडासारखाच दिसतो, आणि म्हणूनच बग अहवालांमध्ये तो इतका काळ टिकतो. पाठवलेल्या क्वेरीज आणि मिळालेल्या उत्तरांसाठी मोजणी ठेवा: पहिला आकडा वाढत असेल आणि दुसरा शून्यावर राहिला तर तुम्ही यादीकडे नाही, सॉकेटकडे पाहत आहात.

आकार आणि चेकसम संदेशाशिवाय अयशस्वी होतात

शांत टाकाऊपण आकारामुळेही येते. मोठ्या उत्तरसंचासह DNS उत्तर, किंवा भरगच्च पर्यायांसह TCP हस्तांदोलन, तुम्ही कधीही स्पष्टपणे सेट न केलेल्या मार्ग MTU पेक्षा जास्त होऊ शकते; तुकडा वरच्या बाजूला नाहीसा होतो आणि क्लायंट एकतर लहान आकारात पुन्हा प्रयत्न करतो किंवा प्रयत्न सोडतो. इंटरफेस MTU 1280 वर सेट करणे ही पुराणमतवादी निवड आहे जी बहुतेक मोबाइल मार्गांवर टिकते, आणि कोणीही मोजले नाही असे डीफॉल्ट वारसा घेण्यापेक्षा स्पष्ट असणे बरे.

तुम्ही स्वतः पॅकेट बनवत असाल, तर चेकसम हा दुसरा शांत खुनी आहे. UDP लांबी किंवा प्रोटोकॉल फील्ड वगळणाऱ्या स्यूडो-शीर्षलेखावर मोजलेला UDP चेकसम तुमच्या बाजूला व्यवस्थित दिसणारा आणि स्वीकारणाऱ्याने कोणताही ठाव न देता टाकून दिलेला पॅकेट तयार करतो. तुमची स्यूडो-शीर्षलेख वैशिष्ट्यांशी फील्ड-दर-फील्ड तुलना करा, आणि डीबग करताना एका ज्ञात प्रवाहासाठी मोजलेला चेकसम छापा.

VpnService तुमच्यासाठी काय करणार नाही

यांच्याभोवती रचना करण्यापूर्वी दोन मर्यादा जाणून घेण्यासारख्या आहेत. कोणताही सामान्य अ‍ॅप Wi-Fi बाहेर प्रणाली-व्यापी प्रॉक्सी किंवा PAC फाइल बसवू शकत नाही, आणि तो भाग बदललेला नाही. प्रति-अ‍ॅप मार्ग बदलला आहे: API 29 आधी VpnService.Builder प्रॉक्सी अजिबात वाहून नेऊ शकत नव्हता, आणि API 29 पासून setHttpProxy(ProxyInfo.buildPacProxy(uri)) प्लॅटफॉर्मला VPN नेटवर्कसाठी मूल्यांकनासाठी PAC स्क्रिप्ट देतो. जुन्या API लक्ष्य करताना किंवा PAC प्रतिमान नियम व्यक्त करू शकत नाही तेव्हा नियम तुमच्या स्वतःच्या कोडमध्ये मूल्यांकन करा. UDP हेही मोफत नाही: ब्राउझर SOCKS प्रॉक्सीमधून फक्त TCP पाठवतात, आणि बहुतेक SOCKS5 क्लायंट UDP ASSOCIATE कधीही अंमलात आणत नाहीत, म्हणून प्रॉक्सी-आधारित रचना TCP निरोगी दिसत असताना UDP टाकून देते किंवा गळवते.

ही दुसरी मर्यादाच UDP-आधारित प्रोटोकॉल सामान्य नेटवर्कवर काम करून तुमचे VPN जोडले जाण्याच्या क्षणी अयशस्वी होण्याचे कारण आहे. बोगद्याने UDP वाहावे अशी अपेक्षा असेल, तर फॉर्वर्डरने त्यासाठी पुढे पाठवण्याचा मार्ग अंमलात आणायला हवा, फक्त वेगळ्या सॉकेट प्रकाराचा TCP मार्ग नाही.

या क्रमाने तपासा

यादी क्रमाने करा आणि अयशस्वी होणाऱ्या पहिल्या टप्प्यावर थांबा, कारण आधीचा टिकला नाही तर पुढील प्रत्येक तपासणी गोंगाट आहे.

  1. बसवलेले मार्ग सूचीबद्ध करा आणि DNS नसलेले पॅकेट TUN इंटरफेसमध्ये अजिबात येतात का ते तपासा.
  2. एका अडवलेल्या आणि एका मंजूर नावासाठी क्वेरी नाव, निर्णय आणि उत्तर कोड नोंदवा.
  3. रिझॉल्व्हर सॉकेट संरक्षित आहे आणि निवडलेला रिझॉल्व्हर बोगद्याच्या आतून उत्तर देतो याची खात्री करा.
  4. इंटरफेस MTU आणि हाताने बनवलेल्या एका उत्तराचा चेकसम तपासा.
  5. तेच पान Wi-Fi आणि मोबाइल नेटवर्कवर पुन्हा करा, कारण कॅरियर रिझॉल्व्हर आणि मार्ग MTU वेगळे असतात.

पाचही टिकले आणि पान तरीही अडकले, तर पुढील संशयित फॉर्वर्डर स्वतः आहे: पकडलेल्या विनंतीची पकडलेल्या उत्तराशी तुलना करा आणि गहाळ बाइट संख्या किंवा अर्धवट बंद सॉकेट शोधा. VpnService.Builder संदर्भ मार्ग, DNS आणि MTU करार व्यापतो, आणि protect() हा builder पर्याय नाही तर स्वतंत्र VpnService कॉल आहे; जोडलेला इंटरफेस म्हणजे फक्त पहिला करार पूर्ण झाला.

संबंधित लेख