Android 10 आणि नंतर, /proc/net/tcp उघडणाऱ्या ॲपला socket तक्त्याऐवजी प्रवेश नकार मिळतो. VPN इंटरफेसला त्याचे काही नाही: पॅकेट येतच राहतात, कारण टनेल हा राउटिंगचा निर्णय आहे, फाइल परवानगी नाही. बदलले ते अधिक अरुंद प्रश्नाचे उत्तर: “कोणते ॲप या कनेक्शनचे मालक आहे?” पर्याय ConnectivityManager.getConnectionOwnerUid आहे, प्रत्येक कनेक्शनसाठी समर्थित क्वेरी, आणि जुन्या सवयी व नव्या API मधील निवड तुमच्याकडे प्रत्यक्षात तीन कामांपैकी कोणते आहे यावर अवलंबून आहे: पॅकेट घेणे, प्रवाहाचे एट्रिब्यूशन, किंवा वापराची बेरीज.

मालक प्रश्नाची दोन उत्तरे

API 29 पूर्वी, विशेषाधिकार असलेली किंवा root प्रक्रिया kernel च्या socket तक्त्या वाचू शकत होती, चौकडी जुळवू शकत होती आणि मालक UID जाणू शकत होती. त्यामुळे एका फाइलमध्ये संपूर्ण उपकरणाची यादी मिळत होती. API 29 पासून फाइलसिस्टम दृश्य मर्यादित आहे, आणि समर्थित मार्ग म्हणजे प्रोटोकॉल, स्थानिक पत्ता व दूरच्या पत्त्यासह प्रत्येक कनेक्शनची क्वेरी.

QuestionLegacy socket tablesgetConnectionOwnerUid
Who owns this flow?Scan and match the tupleAsk once per tuple
Device-wide inventory?Yes, when readableNo, one flow at a time
Historical usage?NoNo; that is NetworkStatsManager
Works without root?No on modern releasesYes, for authorized callers

तुलना “जुने विरुद्ध नवे” नाही. ही तीन वेगळी कामे आहेत जी पूर्वी एका वाचनीय फाइलने पूर्ण होत आणि आता तीन वेगळ्या करारांसह तीन वेगळे इंटरफेस पूर्ण करतात.

स्थानिक पत्ताच ॲपचे टोक

पद्धतीची स्वाक्षरी प्रोटोकॉल, स्थानिक socket पत्ता आणि दूरचा socket पत्ता घेते. “स्थानिक” म्हणजे कनेक्शनमधील ॲपची बाजू, तपासणीच्या क्षणी पॅकेटचा स्रोत असलेले टोक नाही. दूरच्या सर्व्हरवरून ॲपकडे परत येणाऱ्या पॅकेटचा स्रोत आणि गंतव्यस्थान या व्याख्येच्या तुलनेत उलटे असते.

ConnectivityManager cm = getSystemService(ConnectivityManager.class);
int uid = cm.getConnectionOwnerUid(
    OsConstants.IPPROTO_TCP, appLocalAddress, appRemoteAddress);

ही दिशा चूक हेच कार्यरत क्वेरी चुकीचे उत्तर देण्याचे किंवा काहीच न देण्याचे सर्वात सामान्य कारण आहे. कॉलपूर्वी दोन्ही टोके नोंदवा आणि ॲपने प्रत्यक्षात उघडलेल्या कनेक्शनशी जोडी तपासा. पत्ता कुटुंबही महत्त्वाचे आहे: IPv4 ने मॅप केलेला पत्ता आणि स्थानिक IPv6 पत्ता वेगळे tuple आहेत, तसेच त्याच पोर्टवरील TCP आणि UDP प्रवाहही.

अधिकृती आणि अज्ञात निकाल कराराचा भाग

क्वेरी अधिकृत कॉलरपुरती मर्यादित आहे, त्यात संबंधित वापरकर्त्याचे सक्रिय VPN ॲप समाविष्ट आहे. असंबंधित देखरेख ॲप दुसऱ्या प्रोफाइलची कनेक्शन्स मोजू शकते असे गृहीत धरू शकत नाही, आणि अनधिकृत कॉल मैत्रीपूर्ण त्रुटीऐवजी सुरक्षा अपवाद फेकू शकतो. दोन्ही निकाल स्पष्टपणे हाताळा.

अनुपस्थित मालक पॅकेज नाव नाही. प्रवाह पॅकेट आणि क्वेरी दरम्यान बंद झाला असू शकतो, tuple अपूर्ण असू शकते, किंवा कॉलरला जाणून घेण्याची परवानगीच नसू शकते. पहिले यशस्वी उत्तर कॅश करून नंतर पुनर्वापर केल्यास नवीन कनेक्शन जुन्या ॲपला जोडले जाते, जे अज्ञात असे नोंदवण्यापेक्षा वाईट आहे.

एट्रिब्यूशन अयशस्वी झाल्यावरही रहदारीला निर्णय हवा असतो: धोरण जिथे मागते तिथे ती अडवा, फक्त तुम्हाला समजणारी व्याप्ती अनुमत करा, किंवा अंतर दाखवा. तो पर्याय डिझाइनचा भाग आहे, टिप्पणीचा नाही.

लेखा हा वेगळा प्रश्न

NetworkStatsManager स्वतःच्या प्रवेश नियमांनुसार वापर नोंदवते. एखाद्या UID ने कालावधीत किती हस्तांतरित केले हे सांगू शकते; कोणत्याही जिवंत पॅकेटचा मालक सांगू शकत नाही. नेटवर्क क्षमता नेटवर्कचे गुणधर्म वर्णन करतात, socket ची यादी नाही. तीनही मिसळल्यास सुसंगत दिसणारे पण नसलेले डॅशबोर्ड तयार होतात.

कोणती ॲप्स टनेल वापरतात हे ठरवण्याच्या सोप्या बाबतीत, Android च्या समर्थित अनुमत आणि प्रतिबंधित ॲप याद्या कोणत्याही स्क्रॅपिंगशिवाय धोरण व्यक्त करतात. प्रत्यक्षात गरज असलेल्या बाबींसाठी प्रवाहानुसार एट्रिब्यूशन राखून ठेवा, आणि दिशा, परवानग्या व अज्ञात स्थिती एकत्र हाताळणाऱ्या देखभालक्षम अंमलबजावणीसाठी बजेट ठेवा.

कामानुसार साधन निवडा, नंतर कडे तपासा

आवश्यकता टनेल निवड असेल तर प्लॅटफॉर्म यादी वापरा. थेट एट्रिब्यूशन असेल तर मालक क्वेरी वापरा आणि प्रत्येक अनुत्तरित tuple अज्ञात माना. ऐतिहासिक बेरीज असतील तर stats API वापरा. नंतर साध्या अंमलबजावणी तोडणारे तीन कडे तपासा: विरुद्ध दिशेचे पॅकेट, क्वेरीपूर्वी बंद होणारा प्रवाह, आणि सक्रिय VPN नसलेला कॉलर.

यापैकी काहीही SELinux बंद करणे, फोन root करणे किंवा kernel तक्त्या जागतिकरीत्या वाचनीय करणे मागत नाही. मर्यादाच मुद्दा आहे: प्लॅटफॉर्मने एट्रिब्यूशन करारामागे हलवले जेणेकरून उत्तर वैधपणे गरज असलेल्या घटकालाच मिळेल, इतर कोणालाही नाही.

संबंधित लेख