Εφαρμογή Android επιλύει ονόματα εκτός VPN: λίστα ελέγχου σύνδεσης
Το Android μπορεί να επιλύει ονόματα μέσω του προεπιλεγμένου δικτύου όσο είναι ενεργό ένα VPN. Δέστε τη διεργασία στο δίκτυο VPN και ελέγξτε ποιον resolver χρησιμοποίησε στην πραγματικότητα η εφαρμογή.
Μια εφαρμογή Android αποτυγχάνει να επιλύσει ένα εσωτερικό όνομα, ενώ το πρόγραμμα περιήγησης του πελάτη VPN το φτάνει, και η ίδια έκδοση λειτουργεί σε άλλο τηλέφωνο. Η μεταβλητή δεν είναι το URL. Η μεταβλητή είναι ποιο δίκτυο επιτρέπεται να χρησιμοποιεί η διεργασία της εφαρμογής για επίλυση, και το Android δεν εγγυάται ότι το ενεργό VPN είναι αυτό που χρησιμοποιούν οι υποδοχές σας. Εκτελέστε αυτούς τους ελέγχους με τη σειρά και σταματήστε όταν το στιγμιότυπο του resolver δεν συμφωνεί με την υπόθεσή σας.
Βήμα 1: Αποδείξτε σε ποιο δίκτυο βρίσκεται η εφαρμογή
Διαβάστε την οπτική της ίδιας της εφαρμογής και όχι τη γραμμή κατάστασης. Από ConnectivityManager πάρτε το ενεργό δίκτυο, τις LinkProperties , τη λίστα διακομιστών DNS και τη ρύθμιση ιδιωτικού DNS. Αν η λίστα περιέχει τον resolver του VPN, η εφαρμογή έχει διαδρομή προς αυτόν· αν περιέχει τον resolver του Wi-Fi, η σήραγγα δεν είναι το προεπιλεγμένο δίκτυο για αυτή τη διεργασία.
Ένα εικονίδιο VPN λέει μόνο ότι υπάρχει σήραγγα. Δεν λέει ότι η διεργασία της εφαρμογής δέθηκε σε αυτήν, και το Android δεν δρομολογεί πάντα την επίλυση ονομάτων μέσω του δικτύου που φαίνεται ενεργό. Τοπικές εφαρμογές VPN που προωθούν σε άλλη συσκευή, δίκτυα Wi-Fi χωρίς internet και εκδόσεις κατασκευαστών μπορούν να αφήσουν μια εφαρμογή να ρωτά τον προεπιλεγμένο resolver αντί για τους διακομιστές της σήραγγας.
Βήμα 2: Ζητήστε τη μεταφορά VPN και δέστε τη διεργασία
Όταν η εφαρμογή πρέπει να χρησιμοποιήσει τον resolver της σήραγγας, ζητήστε ένα δίκτυο με μεταφορά VPN και δέστε τη διεργασία στο callback, ώστε ο κώδικας να μην μαντεύει πότε εμφανίζεται το δίκτυο:
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)
}
})Η κλήση αλλάζει το προεπιλεγμένο δίκτυο για όλη τη διεργασία, οπότε κάθε υποδοχή που δημιουργείται μετά το χρησιμοποιεί. Οι υποδοχές που υπάρχουν ήδη κρατούν το δίκτυο στο οποίο δημιουργήθηκαν, γι’ αυτό μια δεξαμενή συνδέσεων που άνοιξε πριν από τη δέσμευση μπορεί να συνεχίσει να επιλύει από την παλιά διαδρομή. Η τιμή επιστροφής είναι boolean, και ένα αποτέλεσμα false σημαίνει ότι η δέσμευση δεν έγινε· δοκιμάστε ξανά μετά από σύντομη καθυστέρηση και καταγράψτε και τις δύο προσπάθειες.
Βήμα 3: Περιορίστε τη δέσμευση σε ό,τι τη χρειάζεται
Η δέσμευση σε όλη τη διεργασία είναι χονδρική. Η τηλεμετρία, οι έλεγχοι ενημερώσεων και τα SDK τρίτων μετακινούνται επίσης στη σήραγγα, και αν η σήραγγα δεν έχει internet αρχίζουν να αποτυγχάνουν. Για ένα μόνο αίτημα, χρησιμοποιήστε το εργοστάσιο υποδοχών του δικτύου και κρατήστε την προεπιλογή της συσκευής για όλα τα άλλα. Επιλέξτε συνειδητά ένα μοντέλο: στενή δέσμευση ανά σύνδεση ή δέσμευση διεργασίας με ρητή αποδέσμευση όταν το VPN εξαφανιστεί.
Δύο λειτουργίες του resolver μπορούν να νικήσουν τη δέσμευση χωρίς κανένα σφάλμα. Το ιδιωτικό DNS σε αυστηρή λειτουργία στέλνει τα ερωτήματα σε επώνυμο διακομιστή DoT αντί για τον resolver του δικτύου, και μια εφαρμογή που φέρνει δικό της πελάτη DNS-over-HTTPS παρακάμπτει εντελώς τον resolver του συστήματος. Ελέγξτε και τα δύο πριν συμπεράνετε ότι η δέσμευση απέτυχε. Ένα ερώτημα που δεν φτάνει ποτέ στον διακομιστή DNS του VPN δεν θα εμφανιστεί σε κανένα αρχείο καταγραφής από την πλευρά της σήραγγας.
Βήμα 4: Μην εμπιστεύεστε έναν περιορισμό CONNECTED
Η σημαία NetworkType.CONNECTED του WorkManager σημαίνει ότι ένα δίκτυο είναι συνδεδεμένο, και η μεταφορά VPN τον ικανοποιεί ακόμη και όταν ο υποκείμενος σύνδεσμος Wi-Fi ή κινητής έχει χαθεί. Η εργασία εκτελείται, κάθε αίτημα αποτυγχάνει, και η πολιτική επανάληψης τη μετατρέπει σε καταιγίδα που μοιάζει με σφάλμα προγραμματισμού. Η σήραγγα είναι δίκτυο· ο περιορισμός δεν ήταν ποτέ έλεγχος internet.
Ελέγξτε την ικανότητα που χρειάζεται πραγματικά η εργασία, όπως επικυρωμένη πρόσβαση στο internet, και κρατήστε μια περιορισμένη πολιτική επανάληψης με υποχώρηση. Αν η εργασία χρειάζεται εσωτερικό όνομα, επιλύστε το όνομα στο επιλεγμένο δίκτυο πριν κάνετε την εργασία, και αποτύχετε γρήγορα με σαφές σφάλμα αντί να επαναλαμβάνετε ένα αίτημα που δεν μπορεί να πετύχει.
Βήμα 5: Καταγράψτε τα στοιχεία και δοκιμάστε ξανά το εύρος
Καταγράψτε τους τύπους μεταφοράς του επιλεγμένου δικτύου, τους διακομιστές DNS από LinkProperties , αν η δέσμευση επέστρεψε true, και την ακριβή αποτυχία του πρώτου αιτήματος. Στη συνέχεια εκτελέστε ένα εσωτερικό και ένα δημόσιο όνομα κάτω από την ίδια δέσμευση. Αυτό το ζεύγος δείχνει αν η εφαρμογή χρησιμοποίησε τον resolver της σήραγγας ή έπεσε σιωπηλά στην προεπιλογή της συσκευής, και αυτή είναι η διαφορά που βιώνει ο χρήστης.
Επαναλάβετε στην παλαιότερη έκδοση Android που υποστηρίζετε και σε μία τρέχουσα έκδοση. Η συμπεριφορά του resolver που κάνει την προεπιλεγμένη διαδρομή να φαίνεται σωστή είναι ακριβώς εκεί όπου διαφέρουν συσκευές και εκδόσεις, και μια έκδοση που περνά μόνο στη νεότερη δοκιμαστική συσκευή δεν έχει επαληθευτεί για το εύρος που διανέμετε. adb shell dumpsys connectivityείναι ένας γρήγορος τρόπος να επιβεβαιώσετε ποια δίκτυα και δυνατότητες αναφέρει η συσκευή όσο αναπαράγετε την αποτυχία.