Android অ্যাপ VPN-এর বাইরে নাম সমাধান করে: বাইন্ডিং চেকলিস্ট
VPN চালু থাকলেও Android ডিফল্ট নেটওয়ার্ক দিয়ে নাম সমাধান করতে পারে। প্রসেসটিকে VPN নেটওয়ার্কে বাইন্ড করুন এবং অ্যাপটি আসলে কোন রিজলভার ব্যবহার করেছে তা যাচাই করুন।
একটি Android অ্যাপ অভ্যন্তরীণ নাম সমাধান করতে ব্যর্থ হয়, অথচ VPN ক্লায়েন্টের নিজের ব্রাউজার সেখানে পৌঁছায়, এবং একই বিল্ড অন্য ফোনে কাজ করে। চলকটি URL নয়। চলকটি হলো অ্যাপ প্রসেসকে সমাধানের জন্য কোন নেটওয়ার্ক ব্যবহারের অনুমতি দেওয়া হয়েছে, এবং Android নিশ্চয়তা দেয় না যে সক্রিয় VPN-ই আপনার সকেটের ব্যবহার করা নেটওয়ার্ক। এই যাচাইগুলো ক্রমানুসারে করুন এবং রিজলভার স্ন্যাপশট আপনার অনুমানের সঙ্গে না মিললে থামুন।
ধাপ 1: প্রমাণ করুন অ্যাপটি কোন নেটওয়ার্কে আছে
স্ট্যাটাস বার নয়, অ্যাপের নিজের দৃষ্টিভঙ্গি পড়ুন। ConnectivityManager থেকে সক্রিয় নেটওয়ার্ক, তার LinkProperties , DNS সার্ভারের তালিকা এবং প্রাইভেট DNS সেটিং নিন। তালিকায় VPN-এর রিজলভার থাকলে অ্যাপের সেখানে যাওয়ার পথ আছে; Wi-Fi-এর রিজলভার থাকলে টানেলটি ওই প্রসেসের ডিফল্ট নেটওয়ার্ক নয়।
VPN আইকন শুধু বলে একটি টানেল আছে। এটি বলে না অ্যাপের প্রসেস তার সঙ্গে বাইন্ড হয়েছে, এবং Android নাম সমাধান সবসময় সক্রিয় দেখতে নেটওয়ার্কের মধ্য দিয়ে পাঠায় না। অন্য ডিভাইসে ফরওয়ার্ড করা লোকাল VPN অ্যাপ, ইন্টারনেটহীন Wi-Fi নেটওয়ার্ক এবং প্রস্তুতকারকের বিল্ড অ্যাপকে টানেলের সার্ভারের বদলে ডিফল্ট রিজলভার জিজ্ঞাসা করতে রাখতে পারে।
ধাপ 2: VPN ট্রান্সপোর্ট চান এবং প্রসেস বাইন্ড করুন
অ্যাপকে টানেলের রিজলভার ব্যবহার করতে হলে VPN ট্রান্সপোর্টসহ একটি নেটওয়ার্ক চান এবং কলব্যাকে প্রসেসটি বাইন্ড করুন, যাতে কোড অনুমান না করে নেটওয়ার্ক কখন আসবে:
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.build()
connectivityManager.requestNetwork(request, object : NetworkCallback() {
override fun onAvailable(network: Network) {
val bound = connectivityManager.bindProcessToNetwork(network)
Log.i(TAG, "bound to VPN network: " + bound)
}
})কলটি প্রসেস-ব্যাপী ডিফল্ট নেটওয়ার্ক বদলায়, তাই এর পরে তৈরি প্রতিটি সকেট সেটিই ব্যবহার করে। আগে থেকে থাকা সকেট যে নেটওয়ার্কে তৈরি হয়েছিল তা ধরে রাখে, তাই বাইন্ডের আগে খোলা একটি সংযোগ-পুল পুরোনো পথে সমাধান চালিয়ে যেতে পারে। ফেরত মান একটি বুলিয়ান, এবং false ফলাফল মানে বাইন্ড হয়নি; সংক্ষিপ্ত বিরতির পরে আবার চেষ্টা করুন এবং দুটি প্রচেষ্টাই লগ করুন।
ধাপ 3: বাইন্ডিং শুধু যেখানে দরকার সেখানে সীমিত করুন
প্রসেস-ব্যাপী বাইন্ডিং স্থূল। টেলিমেট্রি, আপডেট যাচাই এবং তৃতীয় পক্ষের SDK-ও টানেলে চলে যায়, এবং টানেলে ইন্টারনেট না থাকলে তারা ব্যর্থ হতে শুরু করে। একক অনুরোধের জন্য নেটওয়ার্কের সকেট ফ্যাক্টরি ব্যবহার করুন এবং বাকি সবের জন্য ডিভাইসের ডিফল্ট রাখুন। সচেতনভাবে একটি মডেল বেছে নিন: প্রতি সংযোগে সংকীর্ণ বাইন্ড, অথবা VPN হারিয়ে গেলে স্পষ্ট আনবাইন্ডসহ প্রসেস বাইন্ড।
দুটি রিজলভার বৈশিষ্ট্য কোনো ত্রুটি ছাড়াই বাইন্ডিংকে হারিয়ে দিতে পারে। কঠোর মোডে প্রাইভেট DNS কুয়েরি নেটওয়ার্ক রিজলভারের বদলে নামযুক্ত DoT সার্ভারে পাঠায়, এবং নিজের DNS-over-HTTPS ক্লায়েন্ট বহনকারী অ্যাপ সিস্টেম রিজলভারকে সম্পূর্ণ এড়িয়ে যায়। বাইন্ডিং ব্যর্থ হয়েছে বলে সিদ্ধান্ত নেওয়ার আগে দুটিই যাচাই করুন। যে কুয়েরি কখনও VPN-এর DNS সার্ভারে পৌঁছায় না তা টানেলের কোনো লগে দেখা যাবে না।
ধাপ 4: CONNECTED সীমাবদ্ধতায় ভরসা করবেন না
WorkManager-এর NetworkType.CONNECTED মানে একটি নেটওয়ার্ক সংযুক্ত, এবং VPN ট্রান্সপোর্ট নিচের Wi-Fi বা সেলুলার লিঙ্ক না থাকলেও তা পূরণ করে। কাজটি চলে, প্রতিটি অনুরোধ ব্যর্থ হয়, এবং পুনরায় চেষ্টার নীতিটি এটিকে সময়সূচির বাগের মতো ঝড়ে পরিণত করে। টানেল একটি নেটওয়ার্ক; সীমাবদ্ধতাটি কখনও ইন্টারনেট যাচাই ছিল না।
কাজটির আসলে যে সামর্থ্য দরকার তা যাচাই করুন, যেমন বৈধ ইন্টারনেট অ্যাক্সেস, এবং ব্যাকঅফসহ সীমিত পুনরায় চেষ্টার নীতি রাখুন। কাজটির অভ্যন্তরীণ নাম দরকার হলে কাজ করার আগে নির্বাচিত নেটওয়ার্কে সেই নাম সমাধান করুন, এবং সফল হতে পারে না এমন অনুরোধ পুনরায় না করে স্পষ্ট ত্রুটিসহ দ্রুত ব্যর্থ হোন।
ধাপ 5: প্রমাণ লিপিবদ্ধ করুন এবং পরিসর আবার পরীক্ষা করুন
নির্বাচিত নেটওয়ার্কের ট্রান্সপোর্ট ধরন, LinkProperties থেকে DNS সার্ভার, বাইন্ড true ফিরিয়েছে কি না এবং প্রথম অনুরোধের সঠিক ব্যর্থতা লগ করুন। তারপর একই বাইন্ডিংয়ের অধীনে একটি অভ্যন্তরীণ ও একটি পাবলিক নাম চালান। এই জোড়া দেখায় অ্যাপ টানেল রিজলভার ব্যবহার করেছে কি না নীরবে ডিভাইস ডিফল্টে ফিরে গেছে, এবং সেটিই ব্যবহারকারীর অনুভব করা পার্থক্য।
আপনি যে সবচেয়ে পুরোনো Android সংস্করণ সমর্থন করেন এবং একটি চলতি সংস্করণে পুনরাবৃত্তি করুন। ডিফল্ট পথকে সঠিক দেখাতে যে রিজলভার আচরণ কাজ করে সেখানেই ডিভাইস ও সংস্করণ আলাদা হয়, এবং কেবল নতুন পরীক্ষার ডিভাইসে পাস করা বিল্ড আপনার সরবরাহ করা পরিসরের জন্য যাচাই হয়নি। adb shell dumpsys connectivityব্যর্থতা পুনরুৎপাদন করার সময় ডিভাইস কোন নেটওয়ার্ক ও সামর্থ্য জানায় তা নিশ্চিত করার দ্রুত উপায়।