diff --git a/ChangeLog.md b/ChangeLog.md index 35235cd1b..67deb2997 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1099,3 +1099,51 @@ **InviZible Pro beta 2.1.7** * Fixed Telegram messenger always connecting. + +**InviZible Pro beta 2.1.8** +* Added DNSCrypt ODoH servers support. +* Updated default Tor bridges. +* App shows IP and country for all types of bridges. +* Improved handling of IPv6-only networks. +* Performance improvements. +* Fixes and optimizations. + +**InviZible Pro beta 2.1.9** +* Updated Purple I2P with the latest patch to mitigate the ongoing DoS attack on the I2P network. + +**InviZible Pro beta 2.2.0** +* Updated Purple I2P with the latest patch to mitigate the ongoing DoS attack on the I2P network. +* Display the IPv6 network status for Purple I2P. +* Sort tabs depending on running modules. +* Fixed WebTunnel connection via IPv6. +* Fixes and optimizations. + +**InviZible Pro beta 2.2.1** +* Revised app settings. +* Updated translations. +* Fixes and optimizations. + +**InviZible Pro beta 2.2.2** +* Fascist Firewall automatically turns off when inappropriate bridges are selected. +* Fixed display of the app list on some phones. +* Updated Spanish and Chinese translations. +* Fixes and optimizations. + +**InviZible Pro beta 2.2.3** +* Updated Tor. +* Updated Tor lyrebird obfuscating proxy. +* Updated DNSCrypt. +* Fascist Firewall option is blocked if inappropriate bridges are selected. +* Updated Spanish and Turkish translations. +* Fixes and optimizations. + +**InviZible Pro beta 2.2.4** +* Downgraded Android material library which causes multiple crashes. + +**InviZible Pro beta 2.2.5** +* Updated Purple I2P to version 2.52.0. +* Updated DNSCrypt. +* Updated Tor Snowflake bridge. +* Updated Tor Lyrebird obfuscating proxy. +* Updated Chinese and Persian translations. +* Fixes and optimizations. diff --git a/Wiki/Screenshots/How to check/Screenshot_how_to_check_6.png b/Wiki/Screenshots/How to check/Screenshot_how_to_check_6.png index c812ff8e9..d2a097feb 100644 Binary files a/Wiki/Screenshots/How to check/Screenshot_how_to_check_6.png and b/Wiki/Screenshots/How to check/Screenshot_how_to_check_6.png differ diff --git a/Wiki/Screenshots/Options/Add DNSCrypt server/Screenshot_add_dnscrypt_server_13.png b/Wiki/Screenshots/Options/Add DNSCrypt server/Screenshot_add_dnscrypt_server_13.png new file mode 100644 index 000000000..a6a995759 Binary files /dev/null and b/Wiki/Screenshots/Options/Add DNSCrypt server/Screenshot_add_dnscrypt_server_13.png differ diff --git a/Wiki/Screenshots/Options/Multi user/Screenshot_multi_user_1.png b/Wiki/Screenshots/Options/Multi user/Screenshot_multi_user_1.png new file mode 100644 index 000000000..945d91a57 Binary files /dev/null and b/Wiki/Screenshots/Options/Multi user/Screenshot_multi_user_1.png differ diff --git a/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_1.png b/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_1.png new file mode 100644 index 000000000..a868a0b5b Binary files /dev/null and b/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_1.png differ diff --git a/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_2.png b/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_2.png new file mode 100644 index 000000000..556753353 Binary files /dev/null and b/Wiki/Screenshots/Options/Spoof SNI/Screenshot_spoof_sni_2.png differ diff --git a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_7.png b/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_7.png index 1d6b52811..a1eace472 100644 Binary files a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_7.png and b/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_7.png differ diff --git a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_8.png b/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_8.png index 01a47b4b2..939938428 100644 Binary files a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_8.png and b/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_8.png differ diff --git a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_9.png b/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_9.png deleted file mode 100644 index 01428fc40..000000000 Binary files a/Wiki/Screenshots/Options/Tor bridges/Using default bridges/Screenshot_using_default_bridges_9.png and /dev/null differ diff --git a/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_12.png b/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_12.png new file mode 100644 index 000000000..f84e30d78 Binary files /dev/null and b/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_12.png differ diff --git a/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_13.png b/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_13.png new file mode 100644 index 000000000..733573b54 Binary files /dev/null and b/Wiki/Screenshots/Quick guide/Screenshot_quick_guide_13.png differ diff --git a/build.gradle b/build.gradle index a9253b6c0..42aea9672 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { ext { kotlin_version = '1.9.23' - dagger_version = '2.51' + dagger_version = '2.51.1' multidex_version = "2.0.1" } @@ -13,7 +13,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.3.2' + classpath 'com.android.tools.build:gradle:8.4.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" diff --git a/fastlane/metadata/android/en-US/changelogs/100218.txt b/fastlane/metadata/android/en-US/changelogs/100218.txt new file mode 100644 index 000000000..cee306929 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100218.txt @@ -0,0 +1,7 @@ +**InviZible Pro beta 2.1.8** +* Added DNSCrypt ODoH servers support. +* Updated default Tor bridges. +* App shows IP and country for all types of bridges. +* Improved handling of IPv6-only networks. +* Performance improvements. +* Fixes and optimizations. diff --git a/fastlane/metadata/android/en-US/changelogs/100219.txt b/fastlane/metadata/android/en-US/changelogs/100219.txt new file mode 100644 index 000000000..091d15416 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100219.txt @@ -0,0 +1,2 @@ +**InviZible Pro beta 2.1.9** +* Updated Purple I2P with the latest patch to mitigate the ongoing DoS attack on the I2P network. diff --git a/fastlane/metadata/android/en-US/changelogs/100220.txt b/fastlane/metadata/android/en-US/changelogs/100220.txt new file mode 100644 index 000000000..59f6062d8 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100220.txt @@ -0,0 +1,6 @@ +**InviZible Pro beta 2.2.0** +* Updated Purple I2P with the latest patch to mitigate the ongoing DoS attack on the I2P network. +* Display the IPv6 network status for Purple I2P. +* Sort tabs depending on running modules. +* Fixed WebTunnel connection via IPv6. +* Fixes and optimizations. diff --git a/fastlane/metadata/android/en-US/changelogs/100221.txt b/fastlane/metadata/android/en-US/changelogs/100221.txt new file mode 100644 index 000000000..abd462865 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100221.txt @@ -0,0 +1,4 @@ +**InviZible Pro beta 2.2.1** +* Revised app settings. +* Updated translations. +* Fixes and optimizations. diff --git a/fastlane/metadata/android/en-US/changelogs/100222.txt b/fastlane/metadata/android/en-US/changelogs/100222.txt new file mode 100644 index 000000000..a7bbbb23e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100222.txt @@ -0,0 +1,5 @@ +**InviZible Pro beta 2.2.2** +* Fascist Firewall automatically turns off when inappropriate bridges are selected. +* Fixed display of the app list on some phones. +* Updated Spanish and Chinese translations. +* Fixes and optimizations. diff --git a/fastlane/metadata/android/en-US/changelogs/100223.txt b/fastlane/metadata/android/en-US/changelogs/100223.txt new file mode 100644 index 000000000..161fbf4f8 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100223.txt @@ -0,0 +1,7 @@ +**InviZible Pro beta 2.2.3** +* Updated Tor. +* Updated Tor lyrebird obfuscating proxy. +* Updated DNSCrypt. +* Fascist Firewall option is blocked if inappropriate bridges are selected. +* Updated Spanish and Turkish translations. +* Fixes and optimizations. diff --git a/fastlane/metadata/android/en-US/changelogs/100224.txt b/fastlane/metadata/android/en-US/changelogs/100224.txt new file mode 100644 index 000000000..3b0ee1187 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100224.txt @@ -0,0 +1,2 @@ +**InviZible Pro beta 2.2.4** +* Downgraded Android material library which causes multiple crashes. diff --git a/fastlane/metadata/android/en-US/changelogs/100225.txt b/fastlane/metadata/android/en-US/changelogs/100225.txt new file mode 100644 index 000000000..05fab2fb6 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/100225.txt @@ -0,0 +1,7 @@ +**InviZible Pro beta 2.2.5** +* Updated Purple I2P to version 2.52.0. +* Updated DNSCrypt. +* Updated Tor Snowflake bridge. +* Updated Tor Lyrebird obfuscating proxy. +* Updated Chinese and Persian translations. +* Fixes and optimizations. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 69f279b19..0f7edf093 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,5 +3,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip -distributionSha256Sum=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip +distributionSha256Sum=85719317abd2112f021d4f41f09ec370534ba288432065f4b477b6a3b652910d diff --git a/tordnscrypt/build.gradle b/tordnscrypt/build.gradle index 739be276a..1a53d36a9 100644 --- a/tordnscrypt/build.gradle +++ b/tordnscrypt/build.gradle @@ -15,7 +15,7 @@ android { fdroid{ applicationId "pan.alexander.tordnscrypt.stable" - versionName "6.6.0" + versionName "6.7.0" dimension = 'version' resValue 'string', 'package_name', applicationId } @@ -55,7 +55,7 @@ android { defaultConfig { minSdkVersion 19 targetSdkVersion 33 - versionCode 217 + versionCode 225 resConfigs "en", "ru", "pl", "de", "fa", "fi", "in", "fr", "ja", "zh", "es", "pt", "pt-rBR", "el", "tr", "it", "uk" @@ -136,6 +136,12 @@ android { jvmTarget = '17' } + kapt { + javacOptions { + option("-Adagger.fastInit=enabled") + } + } + } repositories { @@ -158,7 +164,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation 'eu.chainfire:libsuperuser:1.1.1' implementation 'com.jrummyapps:android-shell:1.0.1' - implementation 'androidx.core:core-ktx:1.12.0' + implementation 'androidx.core:core-ktx:1.13.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation project(':filepicker') diff --git a/tordnscrypt/libs/arm64-v8a/libdnscrypt-proxy.so b/tordnscrypt/libs/arm64-v8a/libdnscrypt-proxy.so index 5d5d8363b..f790bdb54 100755 Binary files a/tordnscrypt/libs/arm64-v8a/libdnscrypt-proxy.so and b/tordnscrypt/libs/arm64-v8a/libdnscrypt-proxy.so differ diff --git a/tordnscrypt/libs/arm64-v8a/libi2pd.so b/tordnscrypt/libs/arm64-v8a/libi2pd.so index f6df420a2..a08e5ba14 100644 Binary files a/tordnscrypt/libs/arm64-v8a/libi2pd.so and b/tordnscrypt/libs/arm64-v8a/libi2pd.so differ diff --git a/tordnscrypt/libs/arm64-v8a/libobfs4proxy.so b/tordnscrypt/libs/arm64-v8a/libobfs4proxy.so index 6991d648a..5bcd35698 100755 Binary files a/tordnscrypt/libs/arm64-v8a/libobfs4proxy.so and b/tordnscrypt/libs/arm64-v8a/libobfs4proxy.so differ diff --git a/tordnscrypt/libs/arm64-v8a/libsnowflake.so b/tordnscrypt/libs/arm64-v8a/libsnowflake.so index a382381d2..b9acc4289 100755 Binary files a/tordnscrypt/libs/arm64-v8a/libsnowflake.so and b/tordnscrypt/libs/arm64-v8a/libsnowflake.so differ diff --git a/tordnscrypt/libs/arm64-v8a/libtor.so b/tordnscrypt/libs/arm64-v8a/libtor.so index 4f65b3ffa..1e73a7e60 100644 Binary files a/tordnscrypt/libs/arm64-v8a/libtor.so and b/tordnscrypt/libs/arm64-v8a/libtor.so differ diff --git a/tordnscrypt/libs/arm64-v8a/libwebtunnel.so b/tordnscrypt/libs/arm64-v8a/libwebtunnel.so index 14808889c..ad2d8a827 100755 Binary files a/tordnscrypt/libs/arm64-v8a/libwebtunnel.so and b/tordnscrypt/libs/arm64-v8a/libwebtunnel.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libdnscrypt-proxy.so b/tordnscrypt/libs/armeabi-v7a/libdnscrypt-proxy.so index 2c8b3fd5e..4328348ee 100755 Binary files a/tordnscrypt/libs/armeabi-v7a/libdnscrypt-proxy.so and b/tordnscrypt/libs/armeabi-v7a/libdnscrypt-proxy.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libi2pd.so b/tordnscrypt/libs/armeabi-v7a/libi2pd.so index 6f84c9e0e..92bcccb38 100644 Binary files a/tordnscrypt/libs/armeabi-v7a/libi2pd.so and b/tordnscrypt/libs/armeabi-v7a/libi2pd.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libobfs4proxy.so b/tordnscrypt/libs/armeabi-v7a/libobfs4proxy.so index b0b90d3d7..f85a35b51 100755 Binary files a/tordnscrypt/libs/armeabi-v7a/libobfs4proxy.so and b/tordnscrypt/libs/armeabi-v7a/libobfs4proxy.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libsnowflake.so b/tordnscrypt/libs/armeabi-v7a/libsnowflake.so index 1c99983d4..39e035a68 100755 Binary files a/tordnscrypt/libs/armeabi-v7a/libsnowflake.so and b/tordnscrypt/libs/armeabi-v7a/libsnowflake.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libtor.so b/tordnscrypt/libs/armeabi-v7a/libtor.so index 5f5a20e03..b3872213f 100644 Binary files a/tordnscrypt/libs/armeabi-v7a/libtor.so and b/tordnscrypt/libs/armeabi-v7a/libtor.so differ diff --git a/tordnscrypt/libs/armeabi-v7a/libwebtunnel.so b/tordnscrypt/libs/armeabi-v7a/libwebtunnel.so index 1b236893d..b5239dc9f 100755 Binary files a/tordnscrypt/libs/armeabi-v7a/libwebtunnel.so and b/tordnscrypt/libs/armeabi-v7a/libwebtunnel.so differ diff --git a/tordnscrypt/libs/prebuild b/tordnscrypt/libs/prebuild index 2b30265c1..98bbab398 100755 --- a/tordnscrypt/libs/prebuild +++ b/tordnscrypt/libs/prebuild @@ -13,9 +13,9 @@ libevent_version=release-2.1.12-stable zstd_version=v1.4.9 xz_version=v5.2.4 tor_version=prod -i2pd_openssl_version=openssl-3.2.0 +i2pd_openssl_version=openssl-3.3.0 miniupnpc_version=c2818392e12f42901ab5abf145f43d69825a38c9 -i2pd_version=2.51.0 +i2pd_version=2.52.0 git clone --single-branch --branch $lyrebird_version https://gitlab.torproject.org/Gedsh/lyrebird diff --git a/tordnscrypt/owner.gradle b/tordnscrypt/owner.gradle index 2f2f34117..68571191a 100644 --- a/tordnscrypt/owner.gradle +++ b/tordnscrypt/owner.gradle @@ -34,7 +34,7 @@ android { productFlavors { lite { applicationId "pan.alexander.tordnscrypt.stable" - versionName "6.6.0" + versionName "6.7.0" dimension = 'version' signingConfig signingConfigs.stablesign resValue 'string', 'package_name', applicationId @@ -42,7 +42,7 @@ android { pro { applicationId "pan.alexander.tordnscrypt.stable" - versionName "6.6.0" + versionName "6.7.0" dimension = 'version' signingConfig signingConfigs.stablesign resValue 'string', 'package_name', applicationId @@ -50,7 +50,7 @@ android { beta { applicationId "pan.alexander.tordnscrypt" - versionName "2.1.7" + versionName "2.2.5" dimension = 'version' signingConfig signingConfigs.betasign resValue 'string', 'package_name', applicationId @@ -59,7 +59,7 @@ android { google_play { minSdkVersion 22 applicationId "pan.alexander.tordnscrypt.gp" - versionName "6.6.0" + versionName "6.7.0" dimension = 'version' signingConfig signingConfigs.stablesign resValue 'string', 'package_name', applicationId @@ -91,7 +91,7 @@ android { defaultConfig { minSdkVersion 19 targetSdkVersion 33 - versionCode 217 + versionCode 225 resConfigs "en", "ru", "pl", "de", "fa", "fi", "in", "fr", "ja", "zh", "es", "pt", "pt-rBR", "el", "tr", "it", "uk" @@ -178,6 +178,12 @@ android { jvmTarget = '17' } + kapt { + javacOptions { + option("-Adagger.fastInit=enabled") + } + } + } @@ -203,7 +209,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation 'eu.chainfire:libsuperuser:1.1.1' implementation 'com.jrummyapps:android-shell:1.0.1' - implementation 'androidx.core:core-ktx:1.12.0' + implementation 'androidx.core:core-ktx:1.13.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0' implementation project(':filepicker') diff --git a/tordnscrypt/proguard-rules.pro b/tordnscrypt/proguard-rules.pro index d8595b07d..7c5dbb457 100644 --- a/tordnscrypt/proguard-rules.pro +++ b/tordnscrypt/proguard-rules.pro @@ -30,3 +30,5 @@ -keepattributes *Annotation*,SourceFile,LineNumberTable,Signature -keep class kotlin.coroutines.Continuation + +-keepclassmembers,allowoptimization,allowobfuscation public class pan.alexander.tordnscrypt.dialogs.ExtendedDialogFragment {*;} diff --git a/tordnscrypt/src/main/assets/dnscrypt.mp3 b/tordnscrypt/src/main/assets/dnscrypt.mp3 index 59342e894..d6e043ffe 100644 Binary files a/tordnscrypt/src/main/assets/dnscrypt.mp3 and b/tordnscrypt/src/main/assets/dnscrypt.mp3 differ diff --git a/tordnscrypt/src/main/assets/itpd.mp3 b/tordnscrypt/src/main/assets/itpd.mp3 index 9f020e8d8..b197fdcb2 100644 Binary files a/tordnscrypt/src/main/assets/itpd.mp3 and b/tordnscrypt/src/main/assets/itpd.mp3 differ diff --git a/tordnscrypt/src/main/assets/tor.mp3 b/tordnscrypt/src/main/assets/tor.mp3 index 89ff3ccf1..2370e2d60 100644 Binary files a/tordnscrypt/src/main/assets/tor.mp3 and b/tordnscrypt/src/main/assets/tor.mp3 differ diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/App.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/App.kt index 96663aa21..a23d6ab63 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/App.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/App.kt @@ -19,7 +19,6 @@ package pan.alexander.tordnscrypt -import android.annotation.TargetApi import android.app.* import android.content.Context import android.content.res.Configuration @@ -34,8 +33,6 @@ import pan.alexander.tordnscrypt.di.* import pan.alexander.tordnscrypt.language.Language import pan.alexander.tordnscrypt.utils.multidex.MultidexActivator -const val ANDROID_CHANNEL_ID = "InviZible" -const val FIREWALL_CHANNEL_ID = "Firewall" const val AUX_CHANNEL_ID = "Auxiliary" class App : Application() { @@ -81,8 +78,6 @@ class App : Application() { Language.setFromPreference(this, "pref_fast_language") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel() - createFirewallChannel() createAuxChannel() } @@ -95,40 +90,6 @@ class App : Application() { initAppLifecycleListener() } - @TargetApi(Build.VERSION_CODES.O) - private fun createNotificationChannel() { - val notificationManager = getSystemService(this, NotificationManager::class.java) - val channel = NotificationChannel( - ANDROID_CHANNEL_ID, - getString(R.string.notification_channel_services), - NotificationManager.IMPORTANCE_MIN - ) - channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT) - channel.description = "" - channel.enableLights(false) - channel.enableVibration(false) - channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE - channel.setShowBadge(false) - notificationManager?.createNotificationChannel(channel) - } - - @RequiresApi(Build.VERSION_CODES.O) - private fun createFirewallChannel() { - val notificationManager = getSystemService(this, NotificationManager::class.java) - val channel = NotificationChannel( - FIREWALL_CHANNEL_ID, - getString(R.string.notification_channel_firewall), - NotificationManager.IMPORTANCE_HIGH - ) - channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT) - channel.description = "" - channel.enableLights(true) - channel.enableVibration(true) - channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE - channel.setShowBadge(true) - notificationManager?.createNotificationChannel(channel) - } - @RequiresApi(Build.VERSION_CODES.O) private fun createAuxChannel() { val notificationManager = getSystemService(this, NotificationManager::class.java) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java index 3a23a5c21..f06282c78 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/MainActivity.java @@ -46,6 +46,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.appcompat.widget.Toolbar; +import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; import android.text.InputType; @@ -103,6 +104,7 @@ import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper; import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; +import static pan.alexander.tordnscrypt.main_fragment.ViewPagerAdapter.MAIN_SCREEN_FRAGMENT_QUANTITY; import static pan.alexander.tordnscrypt.utils.Utils.isInterfaceLocked; import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; import static pan.alexander.tordnscrypt.utils.logger.Logger.logi; @@ -157,7 +159,7 @@ public class MainActivity extends LangAppCompatActivity private TorRunFragment torRunFragment; private ITPDRunFragment iTPDRunFragment; private MainFragment mainFragment; - private ModulesStatus modulesStatus; + private final ModulesStatus modulesStatus = ModulesStatus.getInstance(); private ViewPager viewPager; private static int viewPagerPosition = 0; private MenuItem newIdentityMenuItem; @@ -195,25 +197,20 @@ protected void onCreate(Bundle savedInstanceState) { navigationView.setBackgroundColor(getResources().getColor(R.color.colorBackground)); navigationView.setNavigationItemSelectedListener(this); - modulesStatus = ModulesStatus.getInstance(); + initViewPager(savedInstanceState == null); + } + private void initViewPager(boolean initialiseFragments) { viewPager = findViewById(R.id.viewPager); if (viewPager != null) { - viewPager.setOffscreenPageLimit(4); - - ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(), ViewPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - - MainFragment mainFragment = new MainFragment(); + viewPager.setOffscreenPageLimit(MAIN_SCREEN_FRAGMENT_QUANTITY); - DNSCryptRunFragment dnsCryptRunFragment = new DNSCryptRunFragment(); + ViewPagerAdapter adapter = new ViewPagerAdapter( + getSupportFragmentManager(), + ViewPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT + ); - TorRunFragment torRunFragment = new TorRunFragment(); - ITPDRunFragment itpdRunFragment = new ITPDRunFragment(); - - adapter.addFragment(new ViewPagerAdapter.ViewPagerFragment("Main", mainFragment)); - adapter.addFragment(new ViewPagerAdapter.ViewPagerFragment("DNS", dnsCryptRunFragment)); - adapter.addFragment(new ViewPagerAdapter.ViewPagerFragment("Tor", torRunFragment)); - adapter.addFragment(new ViewPagerAdapter.ViewPagerFragment("I2P", itpdRunFragment)); + adapter.addFragments(initialiseFragments); viewPager.setAdapter(adapter); @@ -222,17 +219,27 @@ protected void onCreate(Bundle savedInstanceState) { viewPager.setCurrentItem(viewPagerPosition); } - } @Override protected void onStart() { super.onStart(); + refreshViewPager(); + NavigationView navigationView = findViewById(R.id.nav_view); changeDrawerWithVersionAndDestination(navigationView); } + private void refreshViewPager() { + if (viewPager != null) { + PagerAdapter adapter = viewPager.getAdapter(); + if (adapter != null) { + viewPager.post(adapter::notifyDataSetChanged); + } + } + } + @Override public void onResume() { super.onResume(); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java index ed199cac4..48480d5a9 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/TopFragment.java @@ -47,13 +47,14 @@ import androidx.preference.PreferenceManager; import java.util.List; +import java.util.concurrent.CancellationException; import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import dagger.Lazy; +import kotlinx.coroutines.Job; import pan.alexander.tordnscrypt.dialogs.AgreementDialog; import pan.alexander.tordnscrypt.dialogs.AskAccelerateDevelop; import pan.alexander.tordnscrypt.dialogs.AskRestoreDefaultsDialog; @@ -74,9 +75,9 @@ import pan.alexander.tordnscrypt.update.UpdateCheck; import pan.alexander.tordnscrypt.update.UpdateService; import pan.alexander.tordnscrypt.utils.enums.ModuleName; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.dialogs.Registration; import pan.alexander.tordnscrypt.utils.Utils; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import pan.alexander.tordnscrypt.utils.enums.ModuleState; import pan.alexander.tordnscrypt.utils.enums.OperationMode; @@ -136,7 +137,7 @@ public class TopFragment extends Fragment @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy modulesVersions; @Inject @@ -156,7 +157,7 @@ public class TopFragment extends Fragment private boolean runModulesWithRoot = false; public CheckUpdatesDialog checkUpdatesDialog; - volatile Future updateCheckTask; + volatile Job updateCheckTask; private ScheduledFuture scheduledFuture; private BroadcastReceiver br; @@ -367,12 +368,12 @@ private void observeRootState() { @WorkerThread private void performInitTasksBackgroundWork() { - cachedExecutor.submit(() -> { + executor.submit("TopFragment performInitTasksBackgroundWork", () -> { Activity activity = getActivity(); if (activity == null || activity.isFinishing()) { - return; + return null; } Context context = activity.getApplicationContext(); @@ -392,7 +393,7 @@ private void performInitTasksBackgroundWork() { if (handler != null) { handler.post(this::performInitTasksMainThreadWork); } - + return null; }); } @@ -636,7 +637,7 @@ private void setSUInfo(List fSuResult, String fSuVersion) { try { final PreferenceRepository preferences = preferenceRepository.get(); - if (fSuResult != null && fSuResult.size() != 0 + if (fSuResult != null && !fSuResult.isEmpty() && fSuResult.toString().toLowerCase().contains("uid=0") && fSuResult.toString().toLowerCase().contains("gid=0")) { @@ -644,7 +645,7 @@ private void setSUInfo(List fSuResult, String fSuVersion) { preferences.setBoolPreference(ROOT_IS_AVAILABLE, true); - if (fSuVersion != null && fSuVersion.length() != 0) { + if (fSuVersion != null && !fSuVersion.isEmpty()) { verSU = "Root is available." + (char) 10 + "Super User Version: " + fSuVersion + (char) 10 + fSuResult.get(0); @@ -668,7 +669,7 @@ private void setBBinfo(List fBbResult) { try { final PreferenceRepository preferences = preferenceRepository.get(); - if (fBbResult != null && fBbResult.size() != 0) { + if (fBbResult != null && !fBbResult.isEmpty()) { verBB = fBbResult.get(0); } else { preferences.setBoolPreference("bbOK", false); @@ -849,12 +850,10 @@ private void dismissCheckUpdatesDialog() { } private void cancelCheckUpdatesTask() { - if (updateCheckTask != null) { - if (!updateCheckTask.isDone()) { - updateCheckTask.cancel(true); - } - updateCheckTask = null; + if (updateCheckTask != null && !updateCheckTask.isCompleted()) { + updateCheckTask.cancel(new CancellationException()); } + updateCheckTask = null; } public void showUpdateResultMessage(Activity activity) { @@ -938,7 +937,7 @@ private boolean isBroadcastMatch(Intent intent) { String action = intent.getAction(); - if ((action == null) || (action.equals(""))) { + if (action == null || action.isEmpty()) { return false; } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/arp/ArpScannerHelper.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/arp/ArpScannerHelper.kt index 815a31f03..af59cbe67 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/arp/ArpScannerHelper.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/arp/ArpScannerHelper.kt @@ -26,7 +26,7 @@ import pan.alexander.tordnscrypt.di.arp.ArpScope import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository import pan.alexander.tordnscrypt.modules.ModulesStatus import pan.alexander.tordnscrypt.utils.enums.OperationMode -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.logger.Logger.logi import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.* import java.util.concurrent.locks.ReentrantLock @@ -40,7 +40,7 @@ class ArpScannerHelper @Inject constructor( @Named(SharedPreferencesModule.DEFAULT_PREFERENCES_NAME) private val defaultSharedPreferences: SharedPreferences, private val appPreferenceRepository: PreferenceRepository, - private val cachedExecutor: CachedExecutor, + private val executor: CoroutineExecutor, private val defaultGatewayManager: dagger.Lazy, private val arpTableManager: dagger.Lazy, private val arpScannerLoop: dagger.Lazy, @@ -77,7 +77,7 @@ class ArpScannerHelper @Inject constructor( } fun resetArpScannerState() { - cachedExecutor.submit { + executor.submit("ArpScannerHelper resetArpScannerState") { arpScannerReentrantLock.withLock { ArpScanner.arpAttackDetected = false ArpScanner.dhcpGatewayAttackDetected = false diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupFragment.java index b9db48e58..0e9665027 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupFragment.java @@ -58,9 +58,9 @@ import pan.alexander.tordnscrypt.dialogs.progressDialogs.PleaseWaitProgressDialog; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.Utils; import pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.ExternalStoragePermissions; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.utils.filemanager.OnBinaryFileOperationsCompleteListener; @@ -93,7 +93,7 @@ public class BackupFragment extends Fragment implements View.OnClickListener, @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; final static Set TAGS_TO_CONVERT = new HashSet<>(Arrays.asList( APPS_ALLOW_LAN_PREF, @@ -326,7 +326,7 @@ void closePleaseWaitDialog() { return; } - cachedExecutor.submit(() -> { + executor.submit("BackupFragment closePleaseWaitDialog", () -> { try { while (progress != null) { if (progress.isStateSaved()) { @@ -344,6 +344,7 @@ void closePleaseWaitDialog() { } loge("BackupFragment close progress fault", ex); } + return null; }); } @@ -431,7 +432,7 @@ private void showAreYouSureDialog(Activity activity, int title, Runnable action) } private void hideSelectionEditTextIfRequired(Activity activity) { - cachedExecutor.submit(() -> { + executor.submit("BackupFragment hideSelectionEditTextIfRequired", () -> { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { logsDirAccessible = Utils.INSTANCE.isLogsDirAccessible(); @@ -445,6 +446,7 @@ private void hideSelectionEditTextIfRequired(Activity activity) { } }); } + return null; }); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupHelper.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupHelper.java index 3e1d34173..ce828a10b 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupHelper.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/BackupHelper.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.concurrent.CancellationException; import java.util.concurrent.ConcurrentSkipListSet; import dagger.Lazy; @@ -49,8 +50,8 @@ import pan.alexander.tordnscrypt.di.SharedPreferencesModule; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.settings.tor_apps.ApplicationData; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.apps.InstalledApplicationsManager; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.zipUtil.ZipFileManager; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; @@ -65,7 +66,7 @@ public class BackupHelper { @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; private Activity activity; private String pathBackup; @@ -82,7 +83,7 @@ public class BackupHelper { void saveAll(boolean logsDirAccessible) { - cachedExecutor.submit(() -> { + executor.submit("BackupHelper saveAll", () -> { try { convertSharedPreferencesUIDsToPackageNames(); @@ -103,6 +104,10 @@ void saveAll(boolean logsDirAccessible) { throw new IllegalStateException("Backup file not exist " + backup.getAbsolutePath()); } + if (isTreadInterrupted()) { + throw new CancellationException(); + } + if (logsDirAccessible) { saveFile(); } else { @@ -118,6 +123,7 @@ void saveAll(boolean logsDirAccessible) { FileManager.deleteFile(activity, cacheDir, "/InvizibleBackup.zip", "ignored"); } + return null; }); } @@ -159,8 +165,7 @@ void saveFileWithSAF() { } void copyData(OutputStream outputStream) { - - cachedExecutor.submit(() -> { + executor.submit("BackupHelper copyData", () -> { try (outputStream; FileInputStream fileInputStream = new FileInputStream(cacheDir + "/InvizibleBackup.zip")) { byte[] buffer = new byte[8 * 1024]; @@ -175,7 +180,7 @@ void copyData(OutputStream outputStream) { FileManager.deleteFile(activity, cacheDir, "/InvizibleBackup.zip", "ignored"); } - + return null; }); } @@ -243,6 +248,10 @@ private void clearSharedPreferencesBackupData() { } } + private boolean isTreadInterrupted() { + return Thread.currentThread().isInterrupted(); + } + void setPathBackup(String pathBackup) { this.pathBackup = pathBackup; } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/ResetHelper.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/ResetHelper.kt index e42f932fb..7ec9b9bda 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/ResetHelper.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/ResetHelper.kt @@ -41,7 +41,7 @@ class ResetHelper( private val backupFragmentWeakReference: WeakReference = WeakReference(backupFragment) fun resetSettings() { - cachedExecutor.submit { + executor.submit("ResetHelper resetSettings") { try { val activity = activityWeakReference.get() ?: return@submit diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/RestoreHelper.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/RestoreHelper.java index e31b0573b..a5c0bd07d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/RestoreHelper.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/backup/RestoreHelper.java @@ -98,7 +98,7 @@ class RestoreHelper extends Installer { void restoreAll(InputStream inputStream, boolean logsDirAccessible) { - cachedExecutor.submit(() -> { + executor.submit("RestoreHelper restoreAll", () -> { try { if (!logsDirAccessible) { @@ -174,6 +174,7 @@ void restoreAll(InputStream inputStream, boolean logsDirAccessible) { } } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/bridges/DefaultVanillaBridgeRepositoryImpl.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/bridges/DefaultVanillaBridgeRepositoryImpl.kt index 6e9f1c798..d4d71b789 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/bridges/DefaultVanillaBridgeRepositoryImpl.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/bridges/DefaultVanillaBridgeRepositoryImpl.kt @@ -37,6 +37,8 @@ import javax.inject.Named import javax.inject.Provider import kotlin.Exception +private const val CONNECT_TIMEOUT_SEC = 1 + class DefaultVanillaBridgeRepositoryImpl @Inject constructor( private val socketInternetChecker: Provider, private val bridgeDataSource: DefaultVanillaBridgeDataSource, @@ -204,4 +206,50 @@ class DefaultVanillaBridgeRepositoryImpl @Inject constructor( return null } + override fun isAddressReachable(ip: String, port: Int): Boolean = try { + tryCheckAddress(ip, port, CONNECT_TIMEOUT_SEC, CONNECT_TIMEOUT_SEC) + } catch (ignored: Exception) { + false + } + + @Suppress("SameParameterValue") + private fun tryCheckAddress( + ip: String, + port: Int, + connectTimeout: Int, + reachableTimeout: Int + ): Boolean = if (isTorOutboundProxyEnabled()) { + val proxyAddress = getTorOutboundProxyAddress()?.split(":") ?: emptyList() + if (proxyAddress.size == 2 + && proxyAddress[0].trim().matches(Regex(IPv4_REGEX)) + && proxyAddress[1].trim().matches(Regex(NUMBER_REGEX)) + ) { + socketInternetChecker.get().checkConnectionAvailability( + ip = ip, + port = port, + proxyAddress = proxyAddress[0].trim(), + proxyPort = proxyAddress[1].trim().toInt(), + connectTimeout = connectTimeout, + reachableTimeout = reachableTimeout + ) + } else { + socketInternetChecker.get().checkConnectionAvailability( + ip = ip, + port = port, + proxyAddress = "", + proxyPort = 0, + connectTimeout = connectTimeout, + reachableTimeout = reachableTimeout + ) + } + } else { + socketInternetChecker.get().checkConnectionAvailability( + ip = ip, + port = port, + proxyAddress = "", + proxyPort = 0, + connectTimeout = connectTimeout, + reachableTimeout = reachableTimeout + ) + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/ModulesLogRepositoryImpl.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/ModulesLogRepositoryImpl.kt index be2445c98..e3f78fe24 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/ModulesLogRepositoryImpl.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/ModulesLogRepositoryImpl.kt @@ -22,8 +22,11 @@ package pan.alexander.tordnscrypt.data.log_reader import android.content.Context import pan.alexander.tordnscrypt.domain.log_reader.ModulesLogRepository import pan.alexander.tordnscrypt.settings.PathVars +import pan.alexander.tordnscrypt.utils.logger.Logger.loge import javax.inject.Inject +private val asciiVisibleSymbols = 32..126 + class ModulesLogRepositoryImpl @Inject constructor( val applicationContext: Context, pathVars: PathVars @@ -35,12 +38,36 @@ class ModulesLogRepositoryImpl @Inject constructor( private var itpdLogFileReader: OwnFileReader? = null private var itpdHtmlFileReader: HtmlReader? = null + private val dnsCryptLog: MutableList = arrayListOf() + private val torLog: MutableList = arrayListOf() + private val itpdLog: MutableList = arrayListOf() + + @Volatile + private var dnsCryptLogLength = 0L + + @Volatile + private var torLogLength = 0L + + @Volatile + private var itpdLogLength = 0L + override fun getDNSCryptLog(): List { dnsCryptLogFileReader = dnsCryptLogFileReader ?: OwnFileReader( applicationContext, "$appDataDir/logs/DnsCrypt.log" ) - return dnsCryptLogFileReader?.readLastLines() ?: emptyList() + + return dnsCryptLogFileReader?.let { reader -> + val length = reader.fileLength + if (length < 0 || length > 0 && length != dnsCryptLogLength) { + dnsCryptLogLength = length + dnsCryptLog.clear() + dnsCryptLog.addAll( + reader.readLastLines().map { it.removeNonVisibleSymbols() } + ) + } + dnsCryptLog + } ?: emptyList() } override fun getTorLog(): List { @@ -48,7 +75,16 @@ class ModulesLogRepositoryImpl @Inject constructor( applicationContext, "$appDataDir/logs/Tor.log" ) - return torLogFileReader?.readLastLines() ?: emptyList() + + return torLogFileReader?.let { reader -> + val length = reader.fileLength + if (length < 0 || length > 0 && length != torLogLength) { + torLogLength = length + torLog.clear() + torLog.addAll(reader.readLastLines()) + } + torLog + } ?: emptyList() } override fun getITPDLog(): List { @@ -56,11 +92,41 @@ class ModulesLogRepositoryImpl @Inject constructor( applicationContext, "$appDataDir/logs/i2pd.log" ) - return itpdLogFileReader?.readLastLines() ?: emptyList() + + return itpdLogFileReader?.let { reader -> + val length = reader.fileLength + if (length < 0 || length > 0 && length != itpdLogLength) { + itpdLogLength = length + itpdLog.clear() + itpdLog.addAll(reader.readLastLines()) + } + itpdLog + } ?: emptyList() } override fun getITPDHtmlData(): List { itpdHtmlFileReader = itpdHtmlFileReader ?: HtmlReader(7070) return itpdHtmlFileReader?.readLines() ?: emptyList() } + + private fun String.removeNonVisibleSymbols(): String { + var result: StringBuilder? = null + for (ch in toCharArray()) { + if (ch.code !in asciiVisibleSymbols) { + result = StringBuilder() + loge("DNSCrypt log contains non-visible symbols: ${ch.code} Line: $this") + break + } + } + if (result != null) { + for (ch in toCharArray()) { + if (ch.code in asciiVisibleSymbols) { + result.append(ch) + } + } + } + return result?.let { + result.toString() + } ?: this + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/OwnFileReader.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/OwnFileReader.java index 5ab29e880..aaccc56fe 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/OwnFileReader.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/data/log_reader/OwnFileReader.java @@ -137,4 +137,24 @@ private void shortenTooLongFile(List lines) { } } + long getFileLength() { + try { + reentrantLock.lockInterruptibly(); + + File file = new File(filePath); + if (!file.isFile() || !file.canRead()) { + return -1; + } + + return file.length(); + } catch (Exception e) { + loge("OwnFileReader getFileSize", e); + } finally { + if (reentrantLock.isLocked() && reentrantLock.isHeldByCurrentThread()) { + reentrantLock.unlock(); + } + } + return -1; + } + } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/AppComponent.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/AppComponent.kt index 9ad60a981..a67e7b7ee 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/AppComponent.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/AppComponent.kt @@ -61,6 +61,7 @@ import pan.alexander.tordnscrypt.update.UpdateCheck import pan.alexander.tordnscrypt.update.UpdateService import pan.alexander.tordnscrypt.utils.apps.InstalledApplicationsManager import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.filemanager.FileManager import pan.alexander.tordnscrypt.utils.integrity.Verifier import pan.alexander.tordnscrypt.utils.root.RootExecService @@ -84,6 +85,7 @@ interface AppComponent { fun getPathVars(): dagger.Lazy fun getPreferenceRepository(): dagger.Lazy fun getCachedExecutor(): CachedExecutor + fun getCoroutineExecutor(): CoroutineExecutor @Component.Builder interface Builder { @@ -125,6 +127,7 @@ interface AppComponent { fun inject(dialogFragment: RequestIgnoreBatteryOptimizationDialog) fun inject(dialogFragment: RequestIgnoreDataRestrictionDialog) fun inject(dialogFragment: SendCrashReport) + fun inject(dialogFragment: AddDNSCryptServerDialogFragment) fun inject(usageStatistic: UsageStatistic) fun inject(modulesKiller: ModulesKiller) fun inject(contextUIDUpdater: ContextUIDUpdater) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/CoroutinesModule.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/CoroutinesModule.kt index f25437874..c821a6fcc 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/CoroutinesModule.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/CoroutinesModule.kt @@ -24,6 +24,7 @@ import dagger.Provides import kotlinx.coroutines.* import pan.alexander.tordnscrypt.utils.logger.Logger.loge import javax.inject.Named +import javax.inject.Singleton @Module class CoroutinesModule { @@ -44,6 +45,15 @@ class CoroutinesModule { return CoroutineScope(SupervisorJob() + dispatcherIo) } + @Provides + @Singleton + @Named(SUPERVISOR_JOB_IO_DISPATCHER_SCOPE_SINGLETON) + fun provideSupervisorIoDispatcherCoroutineScopeSingleton( + @Named(DISPATCHER_IO) dispatcherIo: CoroutineDispatcher + ): CoroutineScope { + return CoroutineScope(SupervisorJob() + dispatcherIo) + } + @Provides fun provideDispatcherMain(): MainCoroutineDispatcher = Dispatchers.Main.immediate @@ -58,13 +68,14 @@ class CoroutinesModule { @Provides fun provideCoroutineExceptionHandler(): CoroutineExceptionHandler { return CoroutineExceptionHandler { coroutine, throwable -> - loge("Coroutine ${coroutine[CoroutineName]}", throwable) + loge("Coroutine ${coroutine[CoroutineName]} unhandled exception", throwable) } } companion object { const val SUPERVISOR_JOB_MAIN_DISPATCHER_SCOPE = "SUPERVISOR_JOB_MAIN_DISPATCHER_SCOPE" const val SUPERVISOR_JOB_IO_DISPATCHER_SCOPE = "SUPERVISOR_JOB_IO_DISPATCHER_SCOPE" + const val SUPERVISOR_JOB_IO_DISPATCHER_SCOPE_SINGLETON = "SUPERVISOR_JOB_IO_DISPATCHER_SCOPE_SINGLETON" const val DISPATCHER_IO = "DISPATCHER_IO" const val DISPATCHER_COMPUTATION = "DISPATCHER_COMPUTATION" } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/ViewModelModule.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/ViewModelModule.kt index 5e248d6d0..16c51faba 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/ViewModelModule.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/di/ViewModelModule.kt @@ -27,6 +27,7 @@ import dagger.multibindings.IntoMap import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ObsoleteCoroutinesApi import pan.alexander.tordnscrypt.TopFragmentViewModel +import pan.alexander.tordnscrypt.settings.dnscrypt_relays.DnsRelayViewModel import pan.alexander.tordnscrypt.settings.dnscrypt_servers.DnsServerViewModel import pan.alexander.tordnscrypt.settings.firewall.FirewallViewModel import pan.alexander.tordnscrypt.settings.tor_bridges.PreferencesTorBridgesViewModel @@ -76,4 +77,11 @@ abstract class ViewModelModule { abstract fun provideDnsServerViewModel( dnsServerViewModel: DnsServerViewModel ): ViewModel + + @Binds + @IntoMap + @ViewModelKey(DnsRelayViewModel::class) + abstract fun provideDnsRelayViewModel( + dnsRelayViewModel: DnsRelayViewModel + ): ViewModel } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AddDNSCryptServerDialogFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AddDNSCryptServerDialogFragment.java index 733173924..048e9d85e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AddDNSCryptServerDialogFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AddDNSCryptServerDialogFragment.java @@ -21,20 +21,34 @@ import android.app.Dialog; import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; import android.util.Base64; import android.widget.EditText; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; +import dagger.Lazy; +import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; +import pan.alexander.tordnscrypt.settings.dnscrypt_servers.DnsServerFeatures; import pan.alexander.tordnscrypt.settings.dnscrypt_servers.DnsServerItem; +import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; import static pan.alexander.tordnscrypt.utils.logger.Logger.logi; import static pan.alexander.tordnscrypt.utils.logger.Logger.logw; +import javax.inject.Inject; +import javax.inject.Named; + public class AddDNSCryptServerDialogFragment extends ExtendedDialogFragment { + @Inject + @Named(DEFAULT_PREFERENCES_NAME) + public Lazy defaultPreferences; + private EditText etOwnServerName; private EditText etOwnServerDescription; private EditText etOwnServerSDNS; @@ -53,6 +67,12 @@ public void setOnServerAddListener(OnServerAddedListener onServerAddedListener) this.onServerAddedListener = onServerAddedListener; } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + App.getInstance().getDaggerComponent().inject(this); + super.onCreate(savedInstanceState); + } + @Override public AlertDialog.Builder assignBuilder() { if (getActivity() == null) { @@ -118,7 +138,8 @@ private boolean saveOwnDNSCryptServer(Context context) { } try { - DnsServerItem item = new DnsServerItem(context, etOwnServerNameText, etOwnServerDescriptionText, etOwnServerSDNSText); + DnsServerFeatures features = new DnsServerFeatures(context, defaultPreferences.get()); + DnsServerItem item = new DnsServerItem(etOwnServerNameText, etOwnServerDescriptionText, etOwnServerSDNSText, features); item.setOwnServer(true); if (onServerAddedListener != null) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java index d328f6199..558075485 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/AgreementDialog.java @@ -32,6 +32,8 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; +import com.google.android.material.button.MaterialButton; + import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; @@ -70,22 +72,27 @@ public AlertDialog.Builder assignBuilder() { return null; } + MaterialButton buttonAccept = view.findViewById(R.id.buttonAcceptAgreement); + MaterialButton buttonDecline = view.findViewById(R.id.buttonDeclineAgreement); + alertDialog.setView(view); alertDialog.setCancelable(false); - alertDialog.setPositiveButton(R.string.agree, (dialog, id) -> { + buttonAccept.setOnClickListener(v -> { exit = false; preferences.setBoolPreference(AGREEMENT_ACCEPTED, true); OnAgreementAcceptedListener listener = getListener(getActivity().getSupportFragmentManager()); if (listener != null) { listener.onAgreementAccepted(); } + dismiss(); }); - alertDialog.setNegativeButton(R.string.disagree, ((dialog, id) -> { + + buttonDecline.setOnClickListener(v -> { exit = true; dismiss(); - })); + }); return alertDialog; } @@ -101,7 +108,7 @@ public void onDismiss(@NonNull DialogInterface dialog) { } private OnAgreementAcceptedListener getListener(FragmentManager manager) { - for (Fragment fragment: manager.getFragments()) { + for (Fragment fragment : manager.getFragments()) { if (fragment instanceof OnAgreementAcceptedListener) { return (OnAgreementAcceptedListener) fragment; } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/RequestIgnoreBatteryOptimizationDialog.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/RequestIgnoreBatteryOptimizationDialog.kt index fda90437f..7aaf3aad4 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/RequestIgnoreBatteryOptimizationDialog.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/RequestIgnoreBatteryOptimizationDialog.kt @@ -93,7 +93,7 @@ class RequestIgnoreBatteryOptimizationDialog : ExtendedDialogFragment() { fun getInstance( context: Context, preferenceRepository: PreferenceRepository, - forceShow: Boolean = true + forceShow: Boolean = false ): DialogFragment? { val pref = PreferenceManager.getDefaultSharedPreferences(context) val packageName = context.packageName diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/SendCrashReport.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/SendCrashReport.kt index 8c90d3d06..e60afe0b0 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/SendCrashReport.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/SendCrashReport.kt @@ -26,11 +26,10 @@ import androidx.core.content.FileProvider import androidx.preference.PreferenceManager import pan.alexander.tordnscrypt.App import pan.alexander.tordnscrypt.R -import pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository import pan.alexander.tordnscrypt.help.Utils import pan.alexander.tordnscrypt.settings.PathVars -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.integrity.Verifier import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.logger.Logger.logw @@ -49,7 +48,7 @@ class SendCrashReport : ExtendedDialogFragment() { @Inject lateinit var pathVars: dagger.Lazy @Inject - lateinit var cachedExecutor: CachedExecutor + lateinit var executor: CoroutineExecutor @Inject lateinit var verifier: dagger.Lazy @@ -68,7 +67,7 @@ class SendCrashReport : ExtendedDialogFragment() { .setTitle(R.string.helper_dialog_title) .setPositiveButton(R.string.ok) { _, _ -> if (activity != null && activity?.isFinishing == false) { - cachedExecutor.submit { + executor.submit("SendCrashReport assignBuilder") { val ctx = activity as Context diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/UpdateDefaultBridgesDialog.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/UpdateDefaultBridgesDialog.kt index 26ae9b25a..1683f25db 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/UpdateDefaultBridgesDialog.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/UpdateDefaultBridgesDialog.kt @@ -22,6 +22,7 @@ package pan.alexander.tordnscrypt.dialogs import android.app.Activity import android.content.Intent import androidx.appcompat.app.AlertDialog +import kotlinx.coroutines.Job import pan.alexander.tordnscrypt.App import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.settings.SettingsActivity @@ -31,7 +32,6 @@ import java.io.File import java.io.FileOutputStream import java.io.InputStream import java.io.OutputStream -import java.util.concurrent.Future import java.util.zip.ZipInputStream class UpdateDefaultBridgesDialog private constructor() { @@ -64,8 +64,9 @@ class UpdateDefaultBridgesDialog private constructor() { return builder.create() } - private fun updateDefaultBridges(activity: Activity, useDefaultBridges: Boolean): Future<*>? { - return App.instance.daggerComponent.getCachedExecutor().submit { + private fun updateDefaultBridges(activity: Activity, useDefaultBridges: Boolean): Job { + return App.instance.daggerComponent + .getCoroutineExecutor().submit("UpdateDefaultBridgesDialog updateDefaultBridges") { val pathVars = App.instance.daggerComponent.getPathVars().get() val outputFile = File(pathVars.appDataDir + "/app_data/tor/bridges_default.lst") val installedBridgesSize = outputFile.length() diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/progressDialogs/CheckUpdatesDialog.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/progressDialogs/CheckUpdatesDialog.kt index 6b46402a4..1a24f6523 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/progressDialogs/CheckUpdatesDialog.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dialogs/progressDialogs/CheckUpdatesDialog.kt @@ -23,12 +23,12 @@ import android.app.Dialog import android.os.Bundle import android.widget.ProgressBar import androidx.appcompat.app.AlertDialog +import kotlinx.coroutines.Job import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.dialogs.ExtendedDialogFragment -import java.util.concurrent.Future class CheckUpdatesDialog: ExtendedDialogFragment() { - var checkUpdatesTask: Future<*>? = null + var checkUpdatesTask: Job? = null override fun assignBuilder(): AlertDialog.Builder? { @@ -42,7 +42,7 @@ class CheckUpdatesDialog: ExtendedDialogFragment() { builder.setMessage(R.string.update_checking_message) builder.setIcon(R.drawable.ic_visibility_off_black_24dp) builder.setPositiveButton(R.string.cancel) { dialogInterface, _ -> - checkUpdatesTask?.cancel(true) + checkUpdatesTask?.cancel() dialogInterface.dismiss() checkUpdatesTask = null } @@ -57,7 +57,7 @@ class CheckUpdatesDialog: ExtendedDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) - if (checkUpdatesTask?.isDone == true) { + if (checkUpdatesTask?.isCompleted == true) { dialog.dismiss() } else { dialog.setCanceledOnTouchOutside(false) @@ -68,7 +68,7 @@ class CheckUpdatesDialog: ExtendedDialogFragment() { override fun onDestroy() { super.onDestroy() - checkUpdatesTask?.cancel(true) + checkUpdatesTask?.cancel() checkUpdatesTask = null } } \ No newline at end of file diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java index 950d8e50f..d1348205c 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentPresenter.java @@ -19,15 +19,17 @@ package pan.alexander.tordnscrypt.dnscrypt_fragment; +import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY; + import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; -import android.text.Html; import android.text.Spanned; import android.view.ScaleGestureDetector; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.core.text.HtmlCompat; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentManager; import androidx.preference.PreferenceManager; @@ -317,12 +319,12 @@ public void onDNSCryptLogUpdated(@NonNull LogDataModel dnsCryptLogData) { Spanned htmlLines; if (savedConnectionRecords.isEmpty()) { - htmlLines = Html.fromHtml(dnsCryptLogData.getLines()); + htmlLines = HtmlCompat.fromHtml(dnsCryptLogData.getLines(), FROM_HTML_MODE_LEGACY); } else { - htmlLines = Html.fromHtml(dnsCryptLogData.getLines() + "
" + savedConnectionRecords); + htmlLines = HtmlCompat.fromHtml(dnsCryptLogData.getLines() + "
" + savedConnectionRecords, FROM_HTML_MODE_LEGACY); } - if (!isActive() || htmlLines == null) { + if (!isActive()) { return; } @@ -418,14 +420,14 @@ private void displayDnsResponses(String savedLogLines, String connectionRecords) if (!savedConnectionRecords.isEmpty()) { savedConnectionRecords = ""; - Spanned htmlLines = Html.fromHtml(savedLogLines); + Spanned htmlLines = HtmlCompat.fromHtml(savedLogLines, FROM_HTML_MODE_LEGACY); if (!isActive()) { return; } view.getFragmentActivity().runOnUiThread(() -> { - if (isActive() && htmlLines != null) { + if (isActive()) { view.setDNSCryptLogViewText(htmlLines); view.scrollDNSCryptLogViewToBottom(); } @@ -443,7 +445,7 @@ private void displayDnsResponses(String savedLogLines, String connectionRecords) return; } - Spanned htmlLines = Html.fromHtml(savedLogLines + "
" + connectionRecords); + Spanned htmlLines = HtmlCompat.fromHtml(savedLogLines + "
" + connectionRecords, FROM_HTML_MODE_LEGACY); if (!isActive()) { return; @@ -451,7 +453,7 @@ private void displayDnsResponses(String savedLogLines, String connectionRecords) view.getFragmentActivity().runOnUiThread(() -> { if (isActive()) { - if (htmlLines != null && dnsCryptLogAutoScroll) { + if (dnsCryptLogAutoScroll) { view.setDNSCryptLogViewText(htmlLines); view.scrollDNSCryptLogViewToBottom(); if (!savedLogLines.isEmpty()) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentReceiver.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentReceiver.java index 003570454..1307e3006 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentReceiver.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/dnscrypt_fragment/DNSCryptFragmentReceiver.java @@ -38,7 +38,7 @@ import pan.alexander.tordnscrypt.modules.ModulesAux; import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.root.RootCommands; import pan.alexander.tordnscrypt.utils.root.RootExecService; import pan.alexander.tordnscrypt.utils.integrity.Verifier; @@ -62,7 +62,7 @@ public class DNSCryptFragmentReceiver extends BroadcastReceiver { @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy verifierLazy; @@ -98,7 +98,7 @@ public void onReceive(Context context, Intent intent) { if (intent != null) { final String action = intent.getAction(); if (action == null - || action.equals("") + || action.isEmpty() || ((intent.getIntExtra("Mark", 0) != DNSCRYPT_RUN_FRAGMENT_MARK) && !action.equals(TOP_BROADCAST))) return; @@ -112,7 +112,7 @@ public void onReceive(Context context, Intent intent) { RootCommands comResult = (RootCommands) intent.getSerializableExtra("CommandsResult"); - if (comResult != null && comResult.getCommands().size() == 0) { + if (comResult != null && comResult.getCommands().isEmpty()) { presenter.setDnsCryptSomethingWrong(); modulesStatus.setDnsCryptState(FAULT); return; @@ -172,10 +172,10 @@ public void onReceive(Context context, Intent intent) { FragmentManager fragmentManager = view.getFragmentFragmentManager(); Activity activity = view.getFragmentActivity(); - cachedExecutor.submit(() -> { + executor.submit("DNSCryptFragmentReceiver onReceive", () -> { try { if (activity == null || activity.isFinishing()) { - return; + return null; } Verifier verifier = verifierLazy.get(); @@ -202,6 +202,7 @@ public void onReceive(Context context, Intent intent) { } loge("DNSCryptRunFragment fault", e, true); } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeInteractor.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeInteractor.kt index f148b7916..46f379f45 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeInteractor.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeInteractor.kt @@ -87,4 +87,8 @@ class DefaultVanillaBridgeInteractor @Inject constructor( .shuffled() .take(MAX_RELAY_COUNT) } + + suspend fun isAddressReachable(ip: String, port: Int): Boolean = withContext(dispatcherIo) { + repository.isAddressReachable(ip, port) + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeRepository.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeRepository.kt index dbadeb952..c3880bd53 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeRepository.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/bridges/DefaultVanillaBridgeRepository.kt @@ -28,4 +28,6 @@ interface DefaultVanillaBridgeRepository { suspend fun getRelaysWithFingerprintAndAddress( allowIPv6Relays: Boolean ): List + + fun isAddressReachable(ip: String, port: Int): Boolean } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_checker/ConnectionCheckerInteractorImpl.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_checker/ConnectionCheckerInteractorImpl.kt index d94b9da58..998eb09e8 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_checker/ConnectionCheckerInteractorImpl.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_checker/ConnectionCheckerInteractorImpl.kt @@ -77,6 +77,7 @@ class ConnectionCheckerInteractorImpl @Inject constructor( @Volatile private var networkAvailable = false + @Volatile private var networkAvailableViaNetworkCallback = false @@ -264,6 +265,13 @@ class ConnectionCheckerInteractorImpl @Inject constructor( } else { val dnsForConnectivityCheck = getNetworkDns() .plus(pathVars.dnsCryptFallbackRes.split(Regex(", ?"))) + .filter { + if (modulesStatus.mode == OperationMode.ROOT_MODE) { + !it.isIPv6() + } else { + true + } + } .shuffled() .first() @@ -297,6 +305,8 @@ class ConnectionCheckerInteractorImpl @Inject constructor( pathVars.dnsCryptFallbackRes.split(Regex(", ?")) } + private fun String.isIPv6() = contains(":") + private enum class Via { TOR, DIRECT diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsConverter.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsConverter.kt index dc29ea4ce..8776b1176 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsConverter.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsConverter.kt @@ -27,6 +27,7 @@ import android.content.SharedPreferences import android.os.Build import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.preference.PreferenceManager +import kotlinx.coroutines.Job import pan.alexander.tordnscrypt.domain.connection_records.entities.ConnectionData import pan.alexander.tordnscrypt.domain.connection_records.entities.ConnectionLogEntry import pan.alexander.tordnscrypt.domain.connection_records.entities.ConnectionProtocol.TCP @@ -47,7 +48,7 @@ import pan.alexander.tordnscrypt.utils.connectionchecker.NetworkChecker import pan.alexander.tordnscrypt.utils.connectivitycheck.ConnectivityCheckManager import pan.alexander.tordnscrypt.utils.enums.ModuleState import pan.alexander.tordnscrypt.utils.enums.OperationMode -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.* import pan.alexander.tordnscrypt.utils.root.RootCommandsMark.IPTABLES_MARK @@ -58,7 +59,6 @@ import pan.alexander.tordnscrypt.vpn.service.VpnBuilder import java.io.IOException import java.util.concurrent.ArrayBlockingQueue import java.util.concurrent.ConcurrentSkipListSet -import java.util.concurrent.Future import javax.inject.Inject private const val REVERSE_LOOKUP_QUEUE_CAPACITY = 32 @@ -69,7 +69,7 @@ class ConnectionRecordsConverter @Inject constructor( private val context: Context, private val preferenceRepository: PreferenceRepository, private val dnsInteractor: dagger.Lazy, - private val cachedExecutor: CachedExecutor, + private val executor: CoroutineExecutor, private val connectivityCheckManager: ConnectivityCheckManager, private val iptablesFirewall: dagger.Lazy ) { @@ -97,7 +97,7 @@ class ConnectionRecordsConverter @Inject constructor( private val logRecords = ArrayList() private val reverseLookupQueue = ArrayBlockingQueue(REVERSE_LOOKUP_QUEUE_CAPACITY, true) private val ipToHostAddressMap = mutableMapOf() - private var futureTask: Future<*>? = null + private var task: Job? = null private var firewallEnabled = isFirewallEnabled() @@ -118,7 +118,7 @@ class ConnectionRecordsConverter @Inject constructor( init { if (isRootMode()) { - cachedExecutor.submit { + executor.submit("ConnectionRecordsConverter init") { try { updateVars() } catch (e: Exception) { @@ -336,7 +336,7 @@ class ConnectionRecordsConverter @Inject constructor( if (consumed) { logRecords.add(packetLogEntry) } else if (vpnDNS == null || !vpnDNS.contains(packetRecord.daddr) || !packetRecord.allowed) { - if (!meteredNetwork && packetRecord.daddr.isNotEmpty()) { + if (!meteredNetwork && packetRecord.daddr.isNotEmpty() && !isIpInLanRange(packetRecord.daddr)) { val host = ipToHostAddressMap[IpToTime(packetRecord.daddr)] if (host == null) { makeReverseLookup(packetRecord.daddr) @@ -400,11 +400,11 @@ class ConnectionRecordsConverter @Inject constructor( private fun startReverseLookupQueue() { - if (futureTask?.isDone == false) { + if (task?.isCompleted == false) { return } - futureTask = cachedExecutor.submit { + task = executor.submit("ConnectionRecordsConverter startReverseLookupQueue") { try { while (!Thread.currentThread().isInterrupted) { @@ -438,10 +438,10 @@ class ConnectionRecordsConverter @Inject constructor( } fun onStop() { - futureTask?.let { - if (!it.isDone) { - it.cancel(true) - futureTask = null + task?.let { + if (!it.isCompleted) { + it.cancel() + task = null } } @@ -482,13 +482,13 @@ class ConnectionRecordsConverter @Inject constructor( ) { val result = goAsync() - cachedExecutor.submit { + executor.submit("ConnectionRecordsConverter iptablesReceiver") { try { updateVars() } catch (e: Exception) { loge("ConnectionRecordsConverter iptablesReceiver", e, true) } finally { - result.finish() + result?.finish() } } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsParser.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsParser.kt index fa1dc7f10..3b3156f2d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsParser.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/connection_records/ConnectionRecordsParser.kt @@ -22,6 +22,7 @@ package pan.alexander.tordnscrypt.domain.connection_records import android.content.Context import android.content.SharedPreferences import android.text.format.DateUtils +import androidx.annotation.ColorRes import androidx.core.content.ContextCompat import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.di.SharedPreferencesModule @@ -56,16 +57,16 @@ class ConnectionRecordsParser @Inject constructor( ) ?: Constants.STANDARD_ADDRESS_LOCAL_PC private val liveLogEntryBlocked by lazy { - ContextCompat.getColor(applicationContext, R.color.liveLogEntryBlocked) + applicationContext.getHexFromColors(R.color.liveLogEntryBlocked) } private val liveLogEntryNoDns by lazy { - ContextCompat.getColor(applicationContext, R.color.liveLogEntryNoDns) + applicationContext.getHexFromColors(R.color.liveLogEntryNoDns) } private val liveLogEntryDnsUnused by lazy { - ContextCompat.getColor(applicationContext, R.color.liveLogEntryDnsUnused) + applicationContext.getHexFromColors(R.color.liveLogEntryDnsUnused) } private val liveLogEntryDnsUsed by lazy { - ContextCompat.getColor(applicationContext, R.color.liveLogEntryDnsUsed) + applicationContext.getHexFromColors(R.color.liveLogEntryDnsUsed) } private val dateFormatToday by lazy { @@ -179,9 +180,6 @@ class ConnectionRecordsParser @Inject constructor( if (record.blocked && record.blockedByIpv6) { lines.append(" ipv6") } - if (!record.blocked && record.ips.isNotEmpty()) { - lines.append(" -> ").append(record.ips.joinToString(", ")) - } } lines.append("") @@ -193,4 +191,8 @@ class ConnectionRecordsParser @Inject constructor( return lines.toString() } + + private fun Context.getHexFromColors( + @ColorRes colorRes: Int + ): String = String.format("#%06X", 0xFFFFFF and ContextCompat.getColor(this, colorRes)) } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/log_reader/itpd/ITPDHtmlParser.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/log_reader/itpd/ITPDHtmlParser.kt index 0e6f34792..52cf1d093 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/log_reader/itpd/ITPDHtmlParser.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/domain/log_reader/itpd/ITPDHtmlParser.kt @@ -90,6 +90,7 @@ class ITPDHtmlParser(val modulesLogRepository: ModulesLogRepository) { lines.forEach { line -> var formattedLine = line if (line.contains("Network status:") + || line.contains("Network status v6:") || line.contains("Tunnel creation success rate:") || line.contains("Received: ") || line.contains("Sent:") diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivity.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivity.java index 86a8432a2..a8c3b4a4b 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivity.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivity.java @@ -57,8 +57,8 @@ import pan.alexander.tordnscrypt.dialogs.NotificationDialogFragment; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.ExternalStoragePermissions; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.utils.filemanager.OnBinaryFileOperationsCompleteListener; @@ -84,7 +84,7 @@ public class HelpActivity extends LangAppCompatActivity implements View.OnClickL @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy verifier; @@ -171,7 +171,10 @@ protected void onResume() { etLogsPath.setText(pathToSaveLogs); - cachedExecutor.submit(() -> new File(cacheDir + "/logs").mkdirs()); + executor.submit("HelpActivity onResume", () -> { + new File(cacheDir + "/logs").mkdirs(); + return null; + }); FileManager.setOnFileOperationCompleteListener(this); } @@ -204,7 +207,10 @@ public void onClick(View view) { if (modulesStatus.isRootAvailable()) { collectLogsMethodOne(info); } else { - cachedExecutor.submit(br.saveLogs(getApplicationContext(), null)); + executor.submit("HelpActivity onClick", () -> { + br.saveLogs(getApplicationContext(), null).run(); + return null; + }); } } else if (id == R.id.etLogsPath) { chooseOutputFolder(); @@ -339,7 +345,7 @@ public void OnFileOperationComplete(FileOperationsVariants currentFileOperation, } private void hideSelectionEditTextIfRequired() { - cachedExecutor.submit(() -> { + executor.submit("HelpActivity hideSelectionEditTextIfRequired", () -> { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { logsDirAccessible = pan.alexander.tordnscrypt.utils.Utils.INSTANCE.isLogsDirAccessible(); @@ -354,6 +360,7 @@ private void hideSelectionEditTextIfRequired() { }); } + return null; }); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivityReceiver.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivityReceiver.java index 4bc4f6d0c..94aa68a43 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivityReceiver.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/help/HelpActivityReceiver.java @@ -39,7 +39,7 @@ import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.iptables.Tethering; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.root.RootCommands; import pan.alexander.tordnscrypt.utils.root.RootExecService; import pan.alexander.tordnscrypt.utils.zipUtil.ZipFileManager; @@ -57,7 +57,7 @@ public class HelpActivityReceiver extends BroadcastReceiver { @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; private final Handler mHandler; private final String appDataDir; @@ -84,13 +84,16 @@ public void onReceive(Context context, Intent intent) { RootCommands comResult = (RootCommands) intent.getSerializableExtra("CommandsResult"); - if (comResult != null && comResult.getCommands().size() == 0) { + if (comResult != null && comResult.getCommands().isEmpty()) { closeProgressDialog(); showSomethingWrongToast(context); return; } - cachedExecutor.submit(saveLogs(context, comResult)); + executor.submit("HelpActivityReceiver onReceive", () -> { + saveLogs(context, comResult).run(); + return null; + }); } Runnable saveLogs(final Context context, final RootCommands comResult) { @@ -223,7 +226,7 @@ private boolean isBroadcastMatch(Intent intent) { String action = intent.getAction(); - if ((action == null) || (action.equals(""))) { + if (action == null || action.isEmpty()) { return false; } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java index 327bd4a29..a879b6ddc 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/Installer.java @@ -46,7 +46,7 @@ import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.modules.ModulesVersions; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.root.RootCommands; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; @@ -70,7 +70,7 @@ public class Installer implements TopFragment.OnActivityChangeListener { @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy modulesVersions; @Inject @@ -425,7 +425,7 @@ protected void stopAllRunningModulesWithRootCommand() { protected void stopAllRunningModulesWithNoRootCommand() { - cachedExecutor.submit(() -> { + executor.submit("Installer stopAllRunningModulesWithNoRootCommand", () -> { ModulesAux.stopModulesIfRunning(activity); int counter = 15; @@ -452,6 +452,7 @@ protected void stopAllRunningModulesWithNoRootCommand() { sendModulesStopResult(""); } + return null; }); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerHelper.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerHelper.java index 98e281e8e..f2115a9d1 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerHelper.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/installer/InstallerHelper.java @@ -21,6 +21,7 @@ import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.FIREWALL_NO_BLOCK_NEW_APP; import android.annotation.SuppressLint; import android.content.Context; @@ -49,9 +50,12 @@ public InstallerHelper(Context context, @Named(DEFAULT_PREFERENCES_NAME) SharedP @SuppressLint("SdCardPath") public List prepareDNSCryptForGP(List lines) { + SharedPreferences.Editor preferences = defaultPreferences.edit(); + preferences.putBoolean(FIREWALL_NO_BLOCK_NEW_APP, true); if (!accelerated) { - defaultPreferences.edit().putBoolean("require_nofilter", true).apply(); + preferences.putBoolean("require_nofilter", true); } + preferences.apply(); ArrayList prepared = new ArrayList<>(); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/iptables/ModulesIptablesRules.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/iptables/ModulesIptablesRules.java index 78443c6e2..644eb0e7e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/iptables/ModulesIptablesRules.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/iptables/ModulesIptablesRules.java @@ -307,12 +307,16 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor String dnsCryptSystemDNSAllowedFilter = ""; String dnsCryptRootDNSAllowedNat = ""; String dnsCryptRootDNSAllowedFilter = ""; + String dnsCryptDnsDaemonDNSAllowedNat = ""; + String dnsCryptDnsDaemonDNSAllowedFilter = ""; if (dnsCryptSystemDNSAllowed) { dnsCryptSystemDNSAllowedFilter = iptables + "-A " + FILTER_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT"; dnsCryptSystemDNSAllowedNat = iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT"; if (!runModulesWithRoot) { dnsCryptRootDNSAllowedNat = iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner 0 -j ACCEPT"; dnsCryptRootDNSAllowedFilter = iptables + "-A " + FILTER_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner 0 -j ACCEPT"; + dnsCryptDnsDaemonDNSAllowedNat = iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner 1051 -j ACCEPT"; + dnsCryptDnsDaemonDNSAllowedFilter = iptables + "-A " + FILTER_OUTPUT_CORE + " -p udp --dport 53 -m owner --uid-owner 1051 -j ACCEPT"; } } @@ -410,6 +414,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d 10.191.0.1 -j DNAT --to-destination 127.0.0.1:" + pathVars.getITPDHttpProxyPort(), dnsCryptSystemDNSAllowedNat, dnsCryptRootDNSAllowedNat, + dnsCryptDnsDaemonDNSAllowedNat, iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d " + dnscryptBootstrapResolver + " --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT", //handle onion websites iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -m string --algo bm --from 16 --to 128 --hex-string " + ONION_HEX + " -j DNAT --to-destination 127.0.0.1:" + pathVars.getTorDNSPort() + " 2> /dev/null || true", @@ -430,6 +435,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-A " + FILTER_OUTPUT_CORE + " -d 127.0.0.1/32 -p udp -m udp --dport " + pathVars.getTorDNSPort() + " -j ACCEPT", dnsCryptSystemDNSAllowedFilter, dnsCryptRootDNSAllowedFilter, + dnsCryptDnsDaemonDNSAllowedFilter, iptables + "-A " + FILTER_OUTPUT_CORE + " -p udp -d " + dnscryptBootstrapResolver + " --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT", blockRejectAddressFilter, proxyAppsBypassNat, @@ -480,6 +486,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d 10.191.0.1 -j DNAT --to-destination 127.0.0.1:" + pathVars.getITPDHttpProxyPort(), dnsCryptSystemDNSAllowedNat, dnsCryptRootDNSAllowedNat, + dnsCryptDnsDaemonDNSAllowedNat, iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d " + dnscryptBootstrapResolver + " --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT", //handle onion websites iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -m string --algo bm --from 16 --to 128 --hex-string " + ONION_HEX + " -j DNAT --to-destination 127.0.0.1:" + pathVars.getTorDNSPort() + " 2> /dev/null || true", @@ -510,6 +517,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-A " + FILTER_OUTPUT_CORE + " -m owner --uid-owner " + appUID + " -j RETURN", dnsCryptSystemDNSAllowedFilter, dnsCryptRootDNSAllowedFilter, + dnsCryptDnsDaemonDNSAllowedFilter, blockRejectAddressFilter, iptables + "-A " + FILTER_OUTPUT_CORE + " -m state --state ESTABLISHED,RELATED -j RETURN", torSitesBypassFilter, @@ -527,7 +535,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor } List commandsTether = tethering.activateTethering(false); - if (commandsTether.size() > 0) { + if (!commandsTether.isEmpty()) { commands.addAll(commandsTether); } if (firewallEnabled) { @@ -565,6 +573,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d 10.191.0.1 -j DNAT --to-destination 127.0.0.1:" + pathVars.getITPDHttpProxyPort(), dnsCryptSystemDNSAllowedNat, dnsCryptRootDNSAllowedNat, + dnsCryptDnsDaemonDNSAllowedNat, iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp -d " + dnscryptBootstrapResolver + " --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT", iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:" + pathVars.getDNSCryptPort(), iptables + "-t nat -A " + NAT_OUTPUT_CORE + " -p tcp --dport 53 -j DNAT --to-destination 127.0.0.1:" + pathVars.getDNSCryptPort(), @@ -579,6 +588,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor iptables + "-A " + FILTER_OUTPUT_CORE + " -d 127.0.0.1/32 -p tcp -m tcp --dport " + pathVars.getDNSCryptPort() + " -j ACCEPT", dnsCryptSystemDNSAllowedFilter, dnsCryptRootDNSAllowedFilter, + dnsCryptDnsDaemonDNSAllowedFilter, iptables + "-A " + FILTER_OUTPUT_CORE + " -p udp -d " + dnscryptBootstrapResolver + " --dport 53 -m owner --uid-owner " + appUID + " -j ACCEPT", blockRejectAddressFilter, iptables + "-A " + FILTER_OUTPUT_CORE + " -m state --state ESTABLISHED,RELATED -j RETURN", @@ -589,7 +599,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor )); List commandsTether = tethering.activateTethering(false); - if (commandsTether.size() > 0) { + if (!commandsTether.isEmpty()) { commands.addAll(commandsTether); } if (firewallEnabled) { @@ -616,7 +626,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor )); List commandsTether = tethering.activateTethering(false); - if (commandsTether.size() > 0) { + if (!commandsTether.isEmpty()) { commands.addAll(commandsTether); } commands.addAll(firewall.getClearFirewallRules()); @@ -752,7 +762,7 @@ public List configureIptables(ModuleState dnsCryptState, ModuleState tor List commandsTether = tethering.activateTethering(false); - if (commandsTether.size() > 0) { + if (!commandsTether.isEmpty()) { commands.addAll(commandsTether); } if (firewallEnabled) { @@ -859,7 +869,7 @@ public List fastUpdate() { )); List commandsTether = tethering.fastUpdate(); - if (commandsTether.size() > 0) { + if (!commandsTether.isEmpty()) { commands.addAll(commandsTether); } IptablesFirewall firewall = iptablesFirewall.get(); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/itpd_fragment/ITPDFragmentPresenter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/itpd_fragment/ITPDFragmentPresenter.java index c696e8399..94c2c8328 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/itpd_fragment/ITPDFragmentPresenter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/itpd_fragment/ITPDFragmentPresenter.java @@ -52,7 +52,7 @@ import pan.alexander.tordnscrypt.modules.ModulesRunner; import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileShortener; import pan.alexander.tordnscrypt.utils.enums.ModuleState; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; @@ -82,7 +82,7 @@ public class ITPDFragmentPresenter implements ITPDFragmentPresenterInterface, @Inject public Lazy itpdInteractor; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; private boolean runI2PDWithRoot = false; @@ -431,18 +431,19 @@ private void copyCertificatesNoRootMethod() { final String certificateFolder = appDataDir + "/i2pd_data/certificates"; final String certificateDestination = appDataDir + "/i2pd_data"; - cachedExecutor.submit(() -> { + executor.submit("ITPDFragmentPresenter copyCertificatesNoRootMethod", () -> { File certificateFolderDir = new File(certificateFolder); if (certificateFolderDir.isDirectory() && certificateFolderDir.listFiles() != null && Objects.requireNonNull(certificateFolderDir.listFiles()).length > 0) { - return; + return null; } FileManager.copyFolderSynchronous(context, certificateSource, certificateDestination); logi("Copy i2p certificates"); + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/main_fragment/ViewPagerAdapter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/main_fragment/ViewPagerAdapter.java index 3c6082595..2bba1182e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/main_fragment/ViewPagerAdapter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/main_fragment/ViewPagerAdapter.java @@ -19,6 +19,11 @@ package pan.alexander.tordnscrypt.main_fragment; +import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED; +import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; + +import android.view.ViewGroup; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -26,10 +31,21 @@ import androidx.fragment.app.FragmentPagerAdapter; import java.util.ArrayList; +import java.util.List; + +import pan.alexander.tordnscrypt.dnscrypt_fragment.DNSCryptRunFragment; +import pan.alexander.tordnscrypt.itpd_fragment.ITPDRunFragment; +import pan.alexander.tordnscrypt.modules.ModulesStatus; +import pan.alexander.tordnscrypt.tor_fragment.TorRunFragment; public class ViewPagerAdapter extends FragmentPagerAdapter { - private final ArrayList viewPagerFragments = new ArrayList<>(4); + public final static int MAIN_SCREEN_FRAGMENT_QUANTITY = 4; + + private final ModulesStatus modulesStatus = ModulesStatus.getInstance(); + private final ArrayList viewPagerFragments = new ArrayList<>( + MAIN_SCREEN_FRAGMENT_QUANTITY + ); public ViewPagerAdapter(@NonNull FragmentManager fm, int behavior) { super(fm, behavior); @@ -38,31 +54,216 @@ public ViewPagerAdapter(@NonNull FragmentManager fm, int behavior) { @NonNull @Override public Fragment getItem(int position) { + if (viewPagerFragments.isEmpty()) { + addFragments(true); + } + Fragment fragment = viewPagerFragments.get(position).fragment; + if (fragment == null) { + loge("ViewPagerAdapter getItem for " + viewPagerFragments.get(position).title.toString() + " is null"); + addFragments(true); + } return viewPagerFragments.get(position).fragment; } @Override public int getCount() { + if (viewPagerFragments.isEmpty()) { + addFragments(true); + } return viewPagerFragments.size(); } - public void addFragment(ViewPagerFragment fragment) { - viewPagerFragments.add(fragment); + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + if (viewPagerFragments.isEmpty()) { + addFragments(false); + } + if (fragment instanceof MainFragment) { + viewPagerFragments.set( + getFragmentPositionByTitle(PagerTitle.MAIN), + new ViewPagerFragment(PagerTitle.MAIN, fragment) + ); + } else if (fragment instanceof DNSCryptRunFragment) { + viewPagerFragments.set( + getFragmentPositionByTitle(PagerTitle.DNS), + new ViewPagerFragment(PagerTitle.DNS, fragment) + ); + } else if (fragment instanceof TorRunFragment) { + viewPagerFragments.set( + getFragmentPositionByTitle(PagerTitle.TOR), + new ViewPagerFragment(PagerTitle.TOR, fragment) + ); + } else if (fragment instanceof ITPDRunFragment) { + viewPagerFragments.set( + getFragmentPositionByTitle(PagerTitle.I2P), + new ViewPagerFragment(PagerTitle.I2P, fragment) + ); + } + return fragment; + } + + @Override + public int getItemPosition(@NonNull Object object) { + if (viewPagerFragments.isEmpty()) { + addFragments(true); + } + Fragment fragment = (Fragment) object; + for (int i = 0; i < viewPagerFragments.size(); i++) { + if (fragment.equals(viewPagerFragments.get(i).fragment)) { + return i; + } + } + return super.getItemPosition(object); } @Nullable @Override public CharSequence getPageTitle(int position) { - return viewPagerFragments.get(position).title; + if (viewPagerFragments.isEmpty()) { + addFragments(true); + } + return viewPagerFragments.get(position).title.toString(); + } + + @Override + public void notifyDataSetChanged() { + List fragments = new ArrayList<>(viewPagerFragments); + viewPagerFragments.clear(); + viewPagerFragments.addAll(sorted(fragments)); + super.notifyDataSetChanged(); + } + + private int getFragmentPositionByTitle(PagerTitle title) { + for (int i = 0; i < viewPagerFragments.size(); i++) { + if (viewPagerFragments.get(i).title.equals(title)) { + return i; + } + } + loge("ViewPagerAdapter unable to find fragment with title " + title.toString()); + return -1; + } + + public void addFragments(boolean initialise) { + viewPagerFragments.clear(); + List fragments = initiateAndGetFragments(initialise); + viewPagerFragments.addAll(sorted(fragments)); + } + + private List initiateAndGetFragments(boolean initialise) { + + List fragments = new ArrayList<>(); + + MainFragment mainFragment; + if (initialise) { + mainFragment = new MainFragment(); + } else { + mainFragment = null; + } + DNSCryptRunFragment dnsCryptRunFragment; + if (initialise) { + dnsCryptRunFragment = new DNSCryptRunFragment(); + } else { + dnsCryptRunFragment = null; + } + TorRunFragment torRunFragment; + if (initialise) { + torRunFragment = new TorRunFragment(); + } else { + torRunFragment = null; + } + ITPDRunFragment itpdRunFragment; + if (initialise) { + itpdRunFragment = new ITPDRunFragment(); + } else { + itpdRunFragment = null; + } + + fragments.add(new ViewPagerFragment(ViewPagerAdapter.PagerTitle.MAIN, mainFragment)); + fragments.add(new ViewPagerFragment(ViewPagerAdapter.PagerTitle.DNS, dnsCryptRunFragment)); + fragments.add(new ViewPagerFragment(ViewPagerAdapter.PagerTitle.TOR, torRunFragment)); + fragments.add(new ViewPagerFragment(ViewPagerAdapter.PagerTitle.I2P, itpdRunFragment)); + + return fragments; + } + + private List sorted(List fragments) { + + ViewPagerFragment mainFragment = null; + ViewPagerFragment dnsCryptRunFragment = null; + ViewPagerFragment torRunFragment = null; + ViewPagerFragment itpdRunFragment = null; + + boolean dnsCryptRunning = isDNSCryptRunning(); + boolean torRunning = isTorRunning(); + boolean itpdRunning = isI2PDRunning(); + + List sortedFragments = new ArrayList<>(); + + for (ViewPagerFragment fragment : fragments) { + if (PagerTitle.MAIN.equals(fragment.title)) { + mainFragment = fragment; + } else if (PagerTitle.DNS.equals(fragment.title)) { + dnsCryptRunFragment = fragment; + } else if (PagerTitle.TOR.equals(fragment.title)) { + torRunFragment = fragment; + } else if (PagerTitle.I2P.equals(fragment.title)) { + itpdRunFragment = fragment; + } + } + + sortedFragments.add(mainFragment); + + if (dnsCryptRunning) { + sortedFragments.add(dnsCryptRunFragment); + } + if (torRunning) { + sortedFragments.add(torRunFragment); + } + if (itpdRunning) { + sortedFragments.add(itpdRunFragment); + } + + if (!dnsCryptRunning) { + sortedFragments.add(dnsCryptRunFragment); + } + if (!torRunning) { + sortedFragments.add(torRunFragment); + } + if (!itpdRunning) { + sortedFragments.add(itpdRunFragment); + } + + return sortedFragments; + } + + private boolean isDNSCryptRunning() { + return modulesStatus.getDnsCryptState() != STOPPED; + } + + private boolean isTorRunning() { + return modulesStatus.getTorState() != STOPPED; + } + + private boolean isI2PDRunning() { + return modulesStatus.getItpdState() != STOPPED; } public static class ViewPagerFragment { - private final String title; + private final PagerTitle title; private final Fragment fragment; - public ViewPagerFragment(String title, Fragment fragment) { + public ViewPagerFragment(PagerTitle title, Fragment fragment) { this.title = title; this.fragment = fragment; } } + + public enum PagerTitle { + MAIN, + DNS, + TOR, + I2P + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java deleted file mode 100644 index 7f66d0250..000000000 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesBroadcastReceiver.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - This file is part of InviZible Pro. - - InviZible Pro is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - InviZible Pro is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with InviZible Pro. If not, see . - - Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com - */ - -package pan.alexander.tordnscrypt.modules; - -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.net.ConnectivityManager; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.os.Build; -import android.os.PowerManager; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; - -import java.io.Serializable; -import java.net.InetAddress; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import dagger.Lazy; -import pan.alexander.tordnscrypt.arp.ArpScanner; -import pan.alexander.tordnscrypt.domain.connection_checker.ConnectionCheckerInteractor; -import pan.alexander.tordnscrypt.domain.connection_checker.OnInternetConnectionCheckedListener; -import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; -import pan.alexander.tordnscrypt.utils.ap.InternetSharingChecker; -import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys; -import pan.alexander.tordnscrypt.utils.privatedns.PrivateDnsProxyManager; - -import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; -import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; -import static pan.alexander.tordnscrypt.utils.logger.Logger.logi; -import static pan.alexander.tordnscrypt.utils.logger.Logger.logw; -import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.ARP_SPOOFING_DETECTION; -import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.REFRESH_RULES; -import static pan.alexander.tordnscrypt.utils.enums.OperationMode.ROOT_MODE; - - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; - -public class ModulesBroadcastReceiver extends BroadcastReceiver implements OnInternetConnectionCheckedListener { - - @Inject - public Lazy preferenceRepository; - @Inject - @Named(DEFAULT_PREFERENCES_NAME) - public Lazy defaultSharedPreferences; - @Inject - public Lazy connectionCheckerInteractor; - @Inject - public Provider internetSharingChecker; - @Inject - public CachedExecutor cachedExecutor; - - private final static int DELAY_BEFORE_CHECKING_INTERNET_SHARING_SEC = 5; - private final static int DELAY_BEFORE_UPDATING_IPTABLES_RULES_SEC = 5; - private final static String EXTRA_ACTIVE_TETHER = "tetherArray"; - - private final Context context; - private boolean receiverRegistered = false; - private Object networkCallback; - private final ModulesStatus modulesStatus = ModulesStatus.getInstance(); - private volatile boolean lock = false; - private static final String AP_STATE_FILTER_ACTION = "android.net.wifi.WIFI_AP_STATE_CHANGED"; - private static final String TETHER_STATE_FILTER_ACTION = "android.net.conn.TETHER_STATE_CHANGED"; - private static final String SHUTDOWN_FILTER_ACTION = "android.intent.action.ACTION_SHUTDOWN"; - private static final String POWER_OFF_FILTER_ACTION = "android.intent.action.QUICKBOOT_POWEROFF"; - private volatile Future checkTetheringTask; - - public ModulesBroadcastReceiver(Context context) { - //App.getInstance().getDaggerComponent().inject(this); - this.context = context; - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - if (action == null) { - return; - } - - if (action.equalsIgnoreCase(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED) - && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - - logi("ModulesBroadcastReceiver Received " + intent); - - idleStateChanged(context); - - } else if (action.equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) { - connectivityStateChanged(intent); - } else if (action.equalsIgnoreCase(AP_STATE_FILTER_ACTION)) { - checkInternetSharingState(intent); - } else if (action.equalsIgnoreCase(TETHER_STATE_FILTER_ACTION)) { - checkInternetSharingState(intent); - } else if (action.equalsIgnoreCase(POWER_OFF_FILTER_ACTION) || action.equalsIgnoreCase(SHUTDOWN_FILTER_ACTION)) { - powerOFFDetected(); - } else if (action.equalsIgnoreCase(Intent.ACTION_PACKAGE_ADDED) || action.equalsIgnoreCase(Intent.ACTION_PACKAGE_REMOVED)) { - packageChanged(); - } - } - - void registerReceivers() { - registerIdleStateChanged(); - registerConnectivityChanges(); - registerAPisOn(); - registerUSBModemIsOn(); - registerPowerOFF(); - registerPackageChanged(); - } - - void unregisterReceivers() { - if (context == null) { - return; - } - - if (receiverRegistered) { - context.unregisterReceiver(this); - receiverRegistered = false; - } - - if (networkCallback != null) { - unlistenNetworkChanges(); - networkCallback = null; - } - } - - private void registerIdleStateChanged() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - IntentFilter ifIdle = new IntentFilter(); - ifIdle.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); - context.registerReceiver(this, ifIdle); - receiverRegistered = true; - } - } - - private void registerConnectivityChanges() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - try { - listenNetworkChanges(); - } catch (Throwable ex) { - logw("ModulesBroadcastReceiver registerConnectivityChanges", ex); - listenConnectivityChanges(); - } - } else { - listenConnectivityChanges(); - } - } - - private void registerAPisOn() { - IntentFilter apStateChanged = new IntentFilter(); - apStateChanged.addAction(AP_STATE_FILTER_ACTION); - context.registerReceiver(this, apStateChanged); - receiverRegistered = true; - } - - private void registerUSBModemIsOn() { - IntentFilter apStateChanged = new IntentFilter(); - apStateChanged.addAction(TETHER_STATE_FILTER_ACTION); - context.registerReceiver(this, apStateChanged); - receiverRegistered = true; - } - - private void registerPowerOFF() { - IntentFilter powerOFF = new IntentFilter(); - powerOFF.addAction(SHUTDOWN_FILTER_ACTION); - powerOFF.addAction(POWER_OFF_FILTER_ACTION); - context.registerReceiver(this, powerOFF); - receiverRegistered = true; - } - - private void registerPackageChanged() { - // Listen for added/removed applications - IntentFilter ifPackage = new IntentFilter(); - ifPackage.addAction(Intent.ACTION_PACKAGE_ADDED); - ifPackage.addAction(Intent.ACTION_PACKAGE_REMOVED); - ifPackage.addDataScheme("package"); - context.registerReceiver(this, ifPackage); - receiverRegistered = true; - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void listenNetworkChanges() { - // Listen for network changes - logi("ModulesBroadcastReceiver Starting listening to network changes"); - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); - } - - ConnectivityManager.NetworkCallback nc = new ConnectivityManager.NetworkCallback() { - private List last_dns = null; - private int last_network = 0; - - @Override - public void onAvailable(@NonNull Network network) { - logi("ModulesBroadcastReceiver Available network=" + network); - updateIptablesRules(false); - resetArpScanner(true); - setInternetAvailable(true); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && last_network != network.hashCode()) { - PrivateDnsProxyManager.INSTANCE.checkPrivateDNSAndProxy( - context, null - ); - } - - last_network = network.hashCode(); - - } - - @Override - public void onLinkPropertiesChanged(@NonNull Network network, LinkProperties linkProperties) { - // Make sure the right DNS servers are being used - List dns = linkProperties.getDnsServers(); - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !same(last_dns, dns)) { - logi("ModulesBroadcastReceiver Changed link properties=" + linkProperties + - "ModulesBroadcastReceiver cur=" + TextUtils.join(",", dns) + - "ModulesBroadcastReceiver prv=" + (last_dns == null ? null : TextUtils.join(",", last_dns))); - last_dns = dns; - logi("ModulesBroadcastReceiver Changed link properties=" + linkProperties); - updateIptablesRules(false); - } - - if (network.hashCode() != last_network) { - last_network = network.hashCode(); - resetArpScanner(); - checkInternetConnection(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - PrivateDnsProxyManager.INSTANCE.checkPrivateDNSAndProxy( - context, linkProperties - ); - } - } - } - - @Override - public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) { - if (last_network != network.hashCode()) { - updateIptablesRules(false); - resetArpScanner(); - last_network = network.hashCode(); - checkInternetConnection(); - logi("ModulesBroadcastReceiver Changed capabilities=" + network); - } - } - - @Override - public void onLost(@NonNull Network network) { - logi("ModulesBroadcastReceiver Lost network=" + network); - updateIptablesRules(false); - resetArpScanner(false); - last_network = 0; - setInternetAvailable(false); - } - - boolean same(List last, List current) { - if (last == null || current == null) - return false; - if (last.size() != current.size()) - return false; - - for (int i = 0; i < current.size(); i++) - if (!last.get(i).equals(current.get(i))) - return false; - - return true; - } - }; - if (cm != null) { - cm.registerNetworkCallback(builder.build(), nc); - networkCallback = nc; - } - } - - private void listenConnectivityChanges() { - // Listen for connectivity updates - logi("ModulesBroadcastReceiver Starting listening to connectivity changes"); - IntentFilter ifConnectivity = new IntentFilter(); - ifConnectivity.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - context.registerReceiver(this, ifConnectivity); - receiverRegistered = true; - } - - @TargetApi(Build.VERSION_CODES.M) - private void idleStateChanged(Context context) { - PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - if (pm != null) { - logi("ModulesBroadcastReceiver device idle=" + pm.isDeviceIdleMode()); - } - - // Reload rules when coming from idle mode - if (pm != null && !pm.isDeviceIdleMode()) { - updateIptablesRules(false); - resetArpScanner(); - checkInternetConnection(); - } - } - - private void connectivityStateChanged(Intent intent) { - // Reload rules - logi("ModulesBroadcastReceiver connectivityStateChanged Received " + intent); - updateIptablesRules(false); - - resetArpScanner(); - } - - @SuppressWarnings("unchecked") - private synchronized void checkInternetSharingState(Intent intent) { - - if (checkTetheringTask != null && !checkTetheringTask.isDone()) { - if (TETHER_STATE_FILTER_ACTION.equals(intent.getAction())) { - checkTetheringTask.cancel(true); - } else { - return; - } - } - - checkTetheringTask = cachedExecutor.submit(() -> { - boolean wifiAccessPointOn = false; - boolean usbTetherOn = false; - String action = intent.getAction(); - - try { - - List tetherList = null; - Serializable serializable = intent.getSerializableExtra(EXTRA_ACTIVE_TETHER); - if (serializable instanceof List) { - tetherList = (List) intent.getSerializableExtra(EXTRA_ACTIVE_TETHER); - } - - TimeUnit.SECONDS.sleep(DELAY_BEFORE_CHECKING_INTERNET_SHARING_SEC); - - InternetSharingChecker checker = internetSharingChecker.get(); - if (tetherList != null) { - if (tetherList.isEmpty()) { - checker.setTetherInterfaceName(Collections.emptyList()); - } else { - checker.setTetherInterfaceName(tetherList); - } - } else if (TETHER_STATE_FILTER_ACTION.equals(action)) { - checker.setTetherInterfaceName(null); - } - checker.updateData(); - wifiAccessPointOn = checker.isApOn(); - usbTetherOn = checker.isUsbTetherOn(); - - } catch (InterruptedException ignored) { - logi("ModulesBroadcastReceiver checkInternetSharingState action " - + action + " interrupted"); - } catch (Exception e) { - loge("ModulesBroadcastReceiver checkInternetSharingState exception", e); - } - - PreferenceRepository preferences = preferenceRepository.get(); - - if (wifiAccessPointOn && !preferences.getBoolPreference(PreferenceKeys.WIFI_ACCESS_POINT_IS_ON)) { - preferences.setBoolPreference(PreferenceKeys.WIFI_ACCESS_POINT_IS_ON, true); - modulesStatus.setIptablesRulesUpdateRequested(context, true); - } else if (!wifiAccessPointOn && preferences.getBoolPreference(PreferenceKeys.WIFI_ACCESS_POINT_IS_ON)) { - preferences.setBoolPreference(PreferenceKeys.WIFI_ACCESS_POINT_IS_ON, false); - modulesStatus.setIptablesRulesUpdateRequested(context, true); - } - - if (usbTetherOn && !preferences.getBoolPreference(PreferenceKeys.USB_MODEM_IS_ON)) { - preferences.setBoolPreference(PreferenceKeys.USB_MODEM_IS_ON, true); - ModulesStatus.getInstance().setIptablesRulesUpdateRequested(context, true); - } else if (!usbTetherOn && preferences.getBoolPreference(PreferenceKeys.USB_MODEM_IS_ON)) { - preferences.setBoolPreference(PreferenceKeys.USB_MODEM_IS_ON, false); - ModulesStatus.getInstance().setIptablesRulesUpdateRequested(context, true); - } - - logi("ModulesBroadcastReceiver " + - "WiFi Access Point state is " + (wifiAccessPointOn ? "ON" : "OFF") + "\n" - + " USB modem state is " + (usbTetherOn ? "ON" : "OFF")); - }); - } - - private void powerOFFDetected() { - ModulesAux.saveDNSCryptStateRunning(false); - ModulesAux.saveTorStateRunning(false); - ModulesAux.saveITPDStateRunning(false); - - ModulesAux.stopModulesIfRunning(context); - } - - private void packageChanged() { - logi("ModulesBroadcastReceiver packageChanged"); - updateIptablesRules(true); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void unlistenNetworkChanges() { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (cm != null) { - cm.unregisterNetworkCallback((ConnectivityManager.NetworkCallback) networkCallback); - } - } - - private void updateIptablesRules(boolean forceUpdate) { - - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); - boolean refreshRules = sharedPreferences.getBoolean(REFRESH_RULES, false); - - if (!refreshRules && !forceUpdate) { - return; - } - - if (modulesStatus.getMode() == ROOT_MODE - && !modulesStatus.isUseModulesWithRoot() - && !lock) { - - cachedExecutor.submit(() -> { - if (!lock) { - - lock = true; - - try { - TimeUnit.SECONDS.sleep(DELAY_BEFORE_UPDATING_IPTABLES_RULES_SEC); - } catch (InterruptedException e) { - logw("ModulesBroadcastReceiver sleep interrupted", e); - } - - if (modulesStatus.getMode() == ROOT_MODE && !modulesStatus.isUseModulesWithRoot()) { - modulesStatus.setIptablesRulesUpdateRequested(context, true); - } - - lock = false; - } - - }); - } - } - - private void resetArpScanner(boolean connectionAvailable) { - if (defaultSharedPreferences.get().getBoolean(ARP_SPOOFING_DETECTION, false)) { - ArpScanner.getArpComponent().get().reset(connectionAvailable); - } - } - - private void resetArpScanner() { - if (context != null && defaultSharedPreferences.get().getBoolean(ARP_SPOOFING_DETECTION, false)) { - ConnectionCheckerInteractor interactor = connectionCheckerInteractor.get(); - interactor.checkNetworkConnection(); - ArpScanner.getArpComponent().get().reset(interactor.getNetworkConnectionResult()); - } - } - - private void setInternetAvailable(boolean available) { - ConnectionCheckerInteractor interactor = connectionCheckerInteractor.get(); - interactor.setInternetConnectionResult(available); - interactor.checkNetworkConnection(); - } - - private void checkInternetConnection() { - ConnectionCheckerInteractor interactor = connectionCheckerInteractor.get(); - interactor.setInternetConnectionResult(false); - interactor.checkInternetConnection(); - } - - @Override - public void onConnectionChecked(boolean available) { - if (available) { - logi("Internet is available due to confirmation."); - } else { - logi("Internet is not available due to confirmation."); - } - } - - @Override - public boolean isActive() { - return true; - } -} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesReceiver.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesReceiver.java index cbb83c041..66fc499f3 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesReceiver.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesReceiver.java @@ -30,6 +30,7 @@ import static pan.alexander.tordnscrypt.utils.logger.Logger.logi; import static pan.alexander.tordnscrypt.utils.logger.Logger.logw; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.ARP_SPOOFING_DETECTION; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_BLOCK_IPv6; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_DNS64; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_DNS64_PREFIX; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.FIREWALL_ENABLED; @@ -70,7 +71,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.concurrent.Future; +import java.util.concurrent.CancellationException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; @@ -81,6 +82,7 @@ import javax.inject.Provider; import dagger.Lazy; +import kotlinx.coroutines.Job; import pan.alexander.tordnscrypt.arp.ArpScanner; import pan.alexander.tordnscrypt.domain.connection_checker.ConnectionCheckerInteractor; import pan.alexander.tordnscrypt.domain.connection_checker.OnInternetConnectionCheckedListener; @@ -91,7 +93,7 @@ import pan.alexander.tordnscrypt.utils.apps.InstalledAppNamesStorage; import pan.alexander.tordnscrypt.utils.connectionchecker.NetworkChecker; import pan.alexander.tordnscrypt.utils.enums.OperationMode; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys; import pan.alexander.tordnscrypt.utils.privatedns.PrivateDnsProxyManager; @@ -120,7 +122,7 @@ public class ModulesReceiver extends BroadcastReceiver implements OnInternetConn private final Lazy defaultPreferences; private final Lazy connectionCheckerInteractor; private final Provider internetSharingChecker; - private final CachedExecutor cachedExecutor; + private final CoroutineExecutor executor; private final Lazy handler; private final Lazy torRestarterReconnector; private final Lazy installedAppNamesStorage; @@ -136,7 +138,7 @@ public class ModulesReceiver extends BroadcastReceiver implements OnInternetConn private volatile boolean rootReceiversRegistered = false; private volatile boolean rootVpnReceiverRegistered = false; private volatile boolean lock = false; - private volatile Future checkTetheringTask; + private volatile Job checkTetheringTask; private volatile boolean vpnRevoked = false; private static final int CHECK_INTERNET_CONNECTION_DELAY_SEC = 30; @@ -149,7 +151,7 @@ public ModulesReceiver( @Named(DEFAULT_PREFERENCES_NAME) Lazy defaultSharedPreferences, Lazy connectionCheckerInteractor, Provider internetSharingChecker, - CachedExecutor cachedExecutor, + CoroutineExecutor executor, Lazy handler, Lazy torRestarterReconnector, Lazy installedAppNamesStorage, @@ -159,7 +161,7 @@ public ModulesReceiver( this.defaultPreferences = defaultSharedPreferences; this.connectionCheckerInteractor = connectionCheckerInteractor; this.internetSharingChecker = internetSharingChecker; - this.cachedExecutor = cachedExecutor; + this.executor = executor; this.handler = handler; this.torRestarterReconnector = torRestarterReconnector; this.installedAppNamesStorage = installedAppNamesStorage; @@ -197,14 +199,17 @@ public void onReceive(Context context, Intent intent) { PendingResult pendingResult = goAsync(); - cachedExecutor.submit(() -> { + executor.submit("ModulesReceiver onReceive", () -> { try { intentOnReceive(intent, action); } catch (Exception e) { loge("ModulesReceiver onReceive", e, true); } finally { - pendingResult.finish(); + if (pendingResult != null) { + pendingResult.finish(); + } } + return null; }); @@ -401,26 +406,29 @@ private void listenNetworkChanges() { ConnectivityManager.NetworkCallback nc = new ConnectivityManager.NetworkCallback() { private final Pattern SIGNAL_STRENGTH_PATTERN = Pattern.compile("SignalStrength: ?-(\\d+)"); private static final int SIGNAL_STRENGTH_THRESHOLD = 20; - private volatile Boolean last_connected = null; - private volatile List last_dns = null; - private volatile int last_network = 0; - private volatile int last_signal_strength = 0; + private volatile Boolean lastConnected = null; + private volatile List lastDns = null; + private volatile String lastNat64 = ""; + private volatile boolean dnsChanged; + private volatile int lastNetwork = 0; + private volatile int lastSignalStrength = 0; + private volatile boolean restartLocked = false; @Override public void onAvailable(@NonNull Network network) { if (isVpnNetwork(cm, network)) { - logi("ModulesReceiver available VPN network=" + network + " connected=" + last_connected); + logi("ModulesReceiver available VPN network=" + network + " connected=" + lastConnected); return; } else { - logi("ModulesReceiver available network=" + network + " connected=" + last_connected); + logi("ModulesReceiver available network=" + network + " connected=" + lastConnected); } - last_connected = true; + lastConnected = true; setNetworkAvailable(true); - if (!last_connected) { - last_connected = true; + if (!lastConnected) { + lastConnected = true; if (isVpnMode() || isRootMode()) { setInternetAvailable(true); @@ -436,13 +444,13 @@ public void onAvailable(@NonNull Network network) { resetArpScanner(true); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && last_network != network.hashCode()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && lastNetwork != network.hashCode()) { PrivateDnsProxyManager.INSTANCE.checkPrivateDNSAndProxy( context, null ); } - last_network = network.hashCode(); + lastNetwork = network.hashCode(); } @@ -460,41 +468,68 @@ public void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkPrope // Make sure the right DNS servers are being used List dns = linkProperties.getDnsServers(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !same(last_dns, dns)) { - logi(" DNS cur=" + (dns == null ? null : TextUtils.join(",", dns)) + - " DNS prv=" + (last_dns == null ? null : TextUtils.join(",", last_dns))); - - String nat64 = ""; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R - && linkProperties.getNat64Prefix() != null) { - nat64 = linkProperties.getNat64Prefix().toString(); + String nat64 = ""; + if (isRootMode() || isDNSCryptBlockIPv6()) { + nat64 = ""; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R + && linkProperties.getNat64Prefix() != null) { + nat64 = linkProperties.getNat64Prefix().toString(); + } else if (linkProperties.toString().contains("Nat64Prefix:")) { + Pattern pattern = Pattern.compile("Nat64Prefix: +(" + IPv6_REGEX_NO_BOUNDS + "/\\d+)"); + Matcher matcher = pattern.matcher(linkProperties.toString()); + if (matcher.find()) { + nat64 = matcher.group(1); + } + if (nat64 == null) { + nat64 = ""; } + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O + || !same(lastDns, dns) || !nat64.equals(lastNat64)) { + logi("DNS cur: " + TextUtils.join(",", dns) + + " prv: " + (lastDns == null ? null : TextUtils.join(",", lastDns)) + + " NAT64 cur: " + nat64 + " prev: " + lastNat64); + boolean restartRequested = false; - if (!nat64.isEmpty() && isNat64Active() && !getSavedNat64Prefix().equals(nat64)) { - updateDNSCryptNat64Prefix(nat64); + if (nat64.isEmpty() && isNat64Active()) { + restartRequested = true; + } else if (!nat64.isEmpty() && (!isNat64Active() || !nat64.equals(getSavedNat64Prefix()))) { + restartRequested = true; + } + + if (isRestartNeeded(lastDns, dns)) { + dnsChanged = true; restartRequested = true; } - if (!restartRequested - && modulesStatus.getDnsCryptState() == RUNNING - && isRestartNeeded(last_dns, dns)) { + if (restartRequested && !restartLocked) { + restartLocked = true; handler.get().postDelayed(() -> { - if (modulesStatus.getDnsCryptState() == RUNNING) { - logi("Restart DNSCrypt on network DNS change"); - ModulesRestarter.restartDNSCrypt(context); + if (lastNat64.isEmpty() && isNat64Active()) { + updateDNSCryptNat64Prefix(false, getSavedNat64Prefix()); + restartDNSCryptIfRunning(); + } else if (!lastNat64.isEmpty() && (!isNat64Active() || !lastNat64.equals(getSavedNat64Prefix()))) { + updateDNSCryptNat64Prefix(true, lastNat64); + restartDNSCryptIfRunning(); + } else if (dnsChanged) { + restartDNSCryptIfRunning(); } + restartLocked = false; + dnsChanged = false; }, RESTART_DNSCRYPT_DELAY_SEC * 1000); } - last_dns = dns; + lastDns = dns; + lastNat64 = nat64; if (isRootMode()) { updateIptablesRules(false); } - if (network.hashCode() != last_network) { - last_network = network.hashCode(); + if (network.hashCode() != lastNetwork) { + lastNetwork = network.hashCode(); if (isVpnMode() && !vpnRevoked) { setInternetAvailable(false); @@ -525,9 +560,9 @@ public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapa setNetworkAvailable(true); - if (last_connected == null || !last_connected) { + if (lastConnected == null || !lastConnected) { - last_connected = true; + lastConnected = true; if (isVpnMode()) { if (vpnRevoked) { @@ -538,7 +573,7 @@ public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapa reload("Connected state changed", context); } logi("ModulesReceiver changed capabilities=" + network); - } else if (isRootMode() && last_network != network.hashCode()) { + } else if (isRootMode() && lastNetwork != network.hashCode()) { updateIptablesRules(false); resetArpScanner(); checkInternetConnection(); @@ -554,16 +589,16 @@ public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapa String signalStrength = matcher.group(1); if (signalStrength != null) { int signal_strength = Integer.parseInt(signalStrength); - if (Math.abs(signal_strength - last_signal_strength) > SIGNAL_STRENGTH_THRESHOLD + if (Math.abs(signal_strength - lastSignalStrength) > SIGNAL_STRENGTH_THRESHOLD && isCheckingInternetConnection.compareAndSet(false, true)) { checkInternetConnectionWithDelay(); logi("ModulesReceiver changed signal strength. " + "Network " + network + " " + "SignalStrength " + signalStrength); } - last_signal_strength = signal_strength; + lastSignalStrength = signal_strength; } - } else if (network.hashCode() != last_network + } else if (network.hashCode() != lastNetwork && isCheckingInternetConnection.compareAndSet(false, true)) { checkInternetConnectionWithDelay(); logi("ModulesReceiver network has changed. " @@ -571,7 +606,7 @@ public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapa } } - last_network = network.hashCode(); + lastNetwork = network.hashCode(); } @@ -585,7 +620,7 @@ public void onLost(@NonNull Network network) { logi("ModulesReceiver lost network=" + network + " connected=false"); } - last_connected = false; + lastConnected = false; setNetworkAvailable(false); if (isVpnMode() && !vpnRevoked) { @@ -602,7 +637,7 @@ public void onLost(@NonNull Network network) { resetArpScanner(false); } - last_network = 0; + lastNetwork = 0; } boolean same(List last, List current) { @@ -639,6 +674,10 @@ boolean isNat64Active() { return defaultPreferences.get().getBoolean(DNSCRYPT_DNS64, false); } + void saveNat64Active(boolean active) { + defaultPreferences.get().edit().putBoolean(DNSCRYPT_DNS64, active).apply(); + } + String getSavedNat64Prefix() { return defaultPreferences.get().getString(DNSCRYPT_DNS64_PREFIX, "64:ff9b::/96"); } @@ -647,41 +686,57 @@ void saveNat64Prefix(String prefix) { defaultPreferences.get().edit().putString(DNSCRYPT_DNS64_PREFIX, prefix).apply(); } - void updateDNSCryptNat64Prefix(String prefix) { - cachedExecutor.submit(() -> { + boolean isDNSCryptBlockIPv6() { + return defaultPreferences.get().getBoolean(DNSCRYPT_BLOCK_IPv6, false); + } + + void updateDNSCryptNat64Prefix(boolean active, String prefix) { + executor.submit("ModulesReceiver updateDNSCryptNat64Prefix", () -> { boolean consumed = false; - Pattern pattern = Pattern.compile("prefix ?= ?\\['" + IPv6_REGEX_NO_BOUNDS + "/\\d+']"); + Pattern pattern = Pattern.compile("#?prefix ?= ?\\['" + IPv6_REGEX_NO_BOUNDS + "/\\d+']"); List conf = FileManager.readTextFileSynchronous( context, pathVars.get().getDnscryptConfPath() ); + String prefixLine; + if (active) { + prefixLine = "prefix = ['" + prefix + "']"; + } else { + prefixLine = "#prefix = ['" + prefix + "']"; + } + if (!pattern.matcher(prefixLine).matches()) { + return null; + } for (int i = 0; i < conf.size(); i++) { String line = conf.get(i); - if (line.startsWith("prefix =")) { - Matcher matcher = pattern.matcher(line); - if (matcher.matches()) { - line = "prefix = ['" + prefix + "']"; - conf.set(i, line); - consumed = true; - break; - } + if (pattern.matcher(line).matches() && !line.equals(prefixLine)) { + conf.set(i, prefixLine); + consumed = true; + break; } } - if (!consumed) { - return; - } - FileManager.writeTextFileSynchronous( - context, - pathVars.get().getDnscryptConfPath(), - conf - ); - saveNat64Prefix(prefix); - if (modulesStatus.getDnsCryptState() == RUNNING) { - logi("Restart DNSCrypt on network Nat64Prefix change"); - ModulesRestarter.restartDNSCrypt(context); + + if (consumed) { + saveNat64Active(active); + saveNat64Prefix(prefix); + + FileManager.writeTextFileSynchronous( + context, + pathVars.get().getDnscryptConfPath(), + conf + ); } + + return null; }); } + + private void restartDNSCryptIfRunning() { + if (modulesStatus.getDnsCryptState() == RUNNING) { + logi("Restart DNSCrypt on network DNS change"); + ModulesRestarter.restartDNSCrypt(context); + } + } }; if (cm != null) { @@ -883,15 +938,15 @@ private void interactiveStateChanged(Intent intent) { @SuppressWarnings("unchecked") private synchronized void checkInternetSharingState(Intent intent) { - if (checkTetheringTask != null && !checkTetheringTask.isDone()) { + if (checkTetheringTask != null && !checkTetheringTask.isCompleted()) { if (TETHER_STATE_FILTER_ACTION.equals(intent.getAction())) { - checkTetheringTask.cancel(true); + checkTetheringTask.cancel(new CancellationException()); } else { return; } } - checkTetheringTask = cachedExecutor.submit(() -> { + checkTetheringTask = executor.execute("ModulesReceiver checkTetheringTask", () -> { boolean wifiAccessPointOn = false; boolean usbTetherOn = false; String action = intent.getAction(); @@ -943,6 +998,7 @@ private synchronized void checkInternetSharingState(Intent intent) { logi("ModulesReceiver " + "WiFi Access Point state is " + (wifiAccessPointOn ? "ON" : "OFF") + "\n" + " USB modem state is " + (usbTetherOn ? "ON" : "OFF")); + return null; }); } @@ -1050,7 +1106,7 @@ private void updateIptablesRules(boolean forceUpdate) { && !modulesStatus.isUseModulesWithRoot() && !lock) { - cachedExecutor.submit(() -> { + executor.submit("ModulesReceiver updateIptablesRules", () -> { if (!lock) { lock = true; @@ -1067,7 +1123,7 @@ private void updateIptablesRules(boolean forceUpdate) { lock = false; } - + return null; }); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesService.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesService.java index d2275c51d..25dec7392 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesService.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesService.java @@ -51,8 +51,8 @@ import pan.alexander.tordnscrypt.settings.PathVars; import pan.alexander.tordnscrypt.utils.ap.InternetSharingChecker; import pan.alexander.tordnscrypt.utils.apps.InstalledAppNamesStorage; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.Utils; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.portchecker.PortChecker; import pan.alexander.tordnscrypt.utils.root.RootExecService; import pan.alexander.tordnscrypt.utils.wakelock.WakeLocksManager; @@ -133,7 +133,7 @@ public class ModulesService extends Service { @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy installedAppNamesStorage; @Inject @@ -175,6 +175,7 @@ public void onCreate() { systemNotificationManager, UsageStatistics.getStartTime() ); + serviceNotificationManager.createNotificationChannel(); serviceNotificationManager.sendNotification(title, message); } @@ -868,7 +869,10 @@ void slowdownTimer() { private void makeExtraLoop() { if (timerPeriod != TIMER_HIGH_SPEED && checkModulesStateTask != null) { - cachedExecutor.submit(checkModulesStateTask); + executor.submit("ModulesService makeExtraLoop", () -> { + checkModulesStateTask.run(); + return null; + }); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesServiceNotificationManager.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesServiceNotificationManager.java index c7f48d9b8..ed51ed117 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesServiceNotificationManager.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesServiceNotificationManager.java @@ -20,7 +20,9 @@ package pan.alexander.tordnscrypt.modules; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; @@ -31,12 +33,14 @@ import androidx.core.app.NotificationCompat; import pan.alexander.tordnscrypt.MainActivity; +import pan.alexander.tordnscrypt.R; -import static pan.alexander.tordnscrypt.AppKt.ANDROID_CHANNEL_ID; import static pan.alexander.tordnscrypt.modules.ModulesService.DEFAULT_NOTIFICATION_ID; import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; public class ModulesServiceNotificationManager { + + private final static String ANDROID_CHANNEL_ID = "InviZible"; private final Service service; private final NotificationManager notificationManager; private final Long startTime; @@ -75,6 +79,22 @@ private PendingIntent getContentIntent() { return contentIntent; } + @TargetApi(Build.VERSION_CODES.O) + public void createNotificationChannel() { + NotificationChannel channel = new NotificationChannel( + ANDROID_CHANNEL_ID, + service.getString(R.string.notification_channel_services), + NotificationManager.IMPORTANCE_MIN + ); + channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT); + channel.setDescription(""); + channel.enableLights(false); + channel.enableVibration(false); + channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); + channel.setShowBadge(false); + notificationManager.createNotificationChannel(channel); + } + private int getIconResource() { int iconResource = android.R.drawable.ic_menu_view; diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStarterHelper.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStarterHelper.java index bddb8a554..b482a27d9 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStarterHelper.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStarterHelper.java @@ -31,10 +31,15 @@ import com.jrummyapps.android.shell.CommandResult; import com.jrummyapps.android.shell.Shell; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -197,9 +202,7 @@ Runnable getDNSCryptStarterRunnable() { if (modulesStatus.getDnsCryptState() != STOPPING && modulesStatus.getDnsCryptState() != STOPPED) { if (pathVars.getAppVersion().startsWith("b") && handler != null) { - handler.post(() -> Toast.makeText(context, "DNSCrypt Module Fault: " - + shellResult.exitCode + "\n\n ERR = " + shellResult.getStderr() - + "\n\n OUT = " + shellResult.getStdout(), Toast.LENGTH_LONG).show()); + showErrorToast("DNSCrypt Module Fault:", shellResult); } checkModulesConfigPatches(true); @@ -211,6 +214,8 @@ Runnable getDNSCryptStarterRunnable() { + shellResult.exitCode + " ERR=" + shellResult.getStderr() + " OUT=" + shellResult.getStdout()); + logNativeCrash(); + if (!getApp(context).isAppForeground() && modulesStatus.getDnsCryptState() == RUNNING && modulesStatus.isDnsCryptReady()) { @@ -315,10 +320,9 @@ Runnable getTorStarterRunnable() { } if (modulesStatus.getTorState() != STOPPING && modulesStatus.getTorState() != STOPPED) { + if (pathVars.getAppVersion().startsWith("b") && handler != null) { - handler.post(() -> Toast.makeText(context, "Tor Module Fault: " + shellResult.exitCode - + "\n\n ERR = " + shellResult.getStderr() - + "\n\n OUT = " + shellResult.getStdout(), Toast.LENGTH_LONG).show()); + showErrorToast("Tor Module Fault:", shellResult); } checkModulesConfigPatches(true); @@ -335,6 +339,8 @@ Runnable getTorStarterRunnable() { loge("Error Tor: " + shellResult.exitCode + " ERR=" + shellResult.getStderr() + " OUT=" + shellResult.getStdout()); + logNativeCrash(); + if (!getApp(context).isAppForeground() && modulesStatus.getTorState() == RUNNING) { if (modulesStatus.isTorReady()) { @@ -409,10 +415,9 @@ Runnable getITPDStarterRunnable() { } if (modulesStatus.getItpdState() != STOPPING && modulesStatus.getItpdState() != STOPPED) { + if (pathVars.getAppVersion().startsWith("b") && handler != null) { - handler.post(() -> Toast.makeText(context, "Purple I2P Module Fault: " - + shellResult.exitCode + "\n\n ERR = " + shellResult.getStderr() - + "\n\n OUT = " + shellResult.getStdout(), Toast.LENGTH_LONG).show()); + showErrorToast("Purple I2P Module Fault:", shellResult); } checkModulesConfigPatches(true); @@ -423,6 +428,8 @@ Runnable getITPDStarterRunnable() { loge("Error ITPD: " + shellResult.exitCode + " ERR=" + shellResult.getStderr() + " OUT=" + shellResult.getStdout()); + logNativeCrash(); + if (!getApp(context).isAppForeground() && modulesStatus.getItpdState() == RUNNING && modulesStatus.isItpdReady()) { @@ -649,4 +656,40 @@ private String getFakeSniHosts() { return TextUtils.join(",", hosts); } + private void showErrorToast(String prefix, CommandResult shellResult) { + StringBuilder builder = new StringBuilder(prefix); + builder.append(" ").append(shellResult.exitCode); + if (!shellResult.getStderr().isEmpty()) { + builder.append("\n\n ERR: ").append(shellResult.getStderr()); + } + if (!shellResult.getStdout().isEmpty()) { + builder.append("\n\n OUT: ").append(shellResult.getStdout()); + } + handler.post(() -> Toast.makeText(context, builder.toString(), Toast.LENGTH_LONG).show()); + } + + private void logNativeCrash() { + try { + SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.getDefault()); + String time = sdf.format(new Date(System.currentTimeMillis() - 3000)); + Process process = new ProcessBuilder( + "logcat", + "-d", + "*:F", + "-t", + time + ).start(); + try(InputStreamReader is = new InputStreamReader(process.getInputStream()); + BufferedReader br = new BufferedReader(is)) { + String line = br.readLine(); + while (line != null) { + loge(line); + line = br.readLine(); + } + } + } catch (Exception e) { + loge("ModulesStarterHelper logNativeCrash" ,e); + } + } + } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStateLoop.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStateLoop.java index 07b25fbbc..a8180fa23 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStateLoop.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesStateLoop.java @@ -421,7 +421,8 @@ private void updateIptablesRules(ModuleState dnsCryptState, ModuleState torState } //Avoid too frequent iptables update - if (handler != null) { + if (handler != null + && (dnsCryptState != STOPPED || torState != STOPPED || itpdState != STOPPED)) { iptablesUpdateTemporaryBlocked = true; handler.get().postDelayed(() -> { iptablesUpdateTemporaryBlocked = false; diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesVersions.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesVersions.java index bfb1dc5b2..448a38673 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesVersions.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/modules/ModulesVersions.java @@ -34,7 +34,7 @@ import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.root.RootCommands; import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; @@ -48,7 +48,7 @@ @Singleton public class ModulesVersions { - private final CachedExecutor cachedExecutor; + private final CoroutineExecutor executor; private String dnsCryptVersion = ""; private String torVersion = ""; @@ -57,13 +57,13 @@ public class ModulesVersions { private Shell.Console console; @Inject - ModulesVersions(CachedExecutor cachedExecutor) { - this.cachedExecutor = cachedExecutor; + ModulesVersions(CoroutineExecutor executor) { + this.executor = executor; } public void refreshVersions(final Context context) { - cachedExecutor.submit(() -> { + executor.submit("ModulesVersions refreshVersions", () -> { //openCommandShell(); PathVars pathVars = App.getInstance().getDaggerComponent().getPathVars().get(); @@ -84,6 +84,7 @@ public void refreshVersions(final Context context) { } //closeCommandShell(); + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/ConfigUtil.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/ConfigUtil.kt index 0c0ad0516..3e4626a3e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/ConfigUtil.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/ConfigUtil.kt @@ -36,6 +36,7 @@ class ConfigUtil(private val context: Context) { readFromFile(pathVars.dnscryptConfPath).run { addLinesToFile(dnsCryptConfigPatches.filterIsInstance()) .replaceLinesInFile(dnsCryptConfigPatches.filterIsInstance()) + .addOdohDNSCryptSection(getOdohSection()) .takeIf { it.size != this.size || !it.containsAll(this) } ?.writeToFile(pathVars.dnscryptConfPath) } @@ -154,6 +155,50 @@ class ConfigUtil(private val context: Context) { return newLines } + private fun List.addOdohDNSCryptSection(lines: List): List { + + if (this.contains(lines.first())) { + return this + } + + val newLines = mutableListOf() + + this.forEach { line -> newLines.add(line.trim()) } + + var currentHeader = "" + for (index: Int in newLines.indices) { + + val line = newLines[index] + + if (line.matches(Regex("\\[.+]"))) { + currentHeader = line + } + + if (currentHeader == "[sources.'relays']" && line == "prefix = ''") { + newLines.addAll(index + 1, lines) + break + } + } + + return newLines + } + + private fun getOdohSection() = + """ + [sources.'odoh-servers'] + urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-servers.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-servers.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-servers.md'] + cache_file = 'odoh-servers.md' + minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + refresh_delay = 72 + prefix = '' + [sources.'odoh-relays'] + urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-relays.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-relays.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-relays.md'] + cache_file = 'odoh-relays.md' + minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3' + refresh_delay = 72 + prefix = '' + """.trimIndent().split("\n") + fun updateTorGeoip() { val geoip = File(pathVars.appDataDir + "/app_data/tor/geoip") val geoip6 = File(pathVars.appDataDir + "/app_data/tor/geoip6") diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/Patch.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/Patch.kt index 6a5334cec..b389bcfbb 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/Patch.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/patches/Patch.kt @@ -74,6 +74,7 @@ class Patch(private val context: Context, private val pathVars: PathVars) { clearFlagDoNotUpdateTorDefaultBridges() addTorDormantOption() fixTorIPv6VirtualAddresses() + addDNSCryptOdohServers() if (dnsCryptConfigPatches.isNotEmpty()) { configUtil.patchDNSCryptConfig(dnsCryptConfigPatches) @@ -290,4 +291,14 @@ class Patch(private val context: Context, private val pathVars: PathVars) { ) } + private fun addDNSCryptOdohServers() { + dnsCryptConfigPatches.add( + AlterConfig.AddLine( + "", + Regex("doh_servers = .+"), + "odoh_servers = true" + ) + ) + } + } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyFragment.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyFragment.kt index c964c877c..605f38e2a 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyFragment.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyFragment.kt @@ -37,6 +37,7 @@ import androidx.core.content.ContextCompat import androidx.core.widget.NestedScrollView import androidx.fragment.app.Fragment import androidx.preference.PreferenceManager +import kotlinx.coroutines.Job import pan.alexander.tordnscrypt.App import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.databinding.FragmentProxyBinding @@ -44,7 +45,7 @@ import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository import pan.alexander.tordnscrypt.settings.SettingsActivity import pan.alexander.tordnscrypt.utils.Constants.DEFAULT_PROXY_PORT import pan.alexander.tordnscrypt.utils.Constants.LOOPBACK_ADDRESS -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.PROXIFY_DNSCRYPT import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.PROXIFY_I2PD @@ -54,7 +55,6 @@ import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.PROXY_PASS import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.PROXY_PORT import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.PROXY_USER import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.USE_PROXY -import java.util.concurrent.Future import javax.inject.Inject const val CLEARNET_APPS_FOR_PROXY = "clearnetAppsForProxy" @@ -68,7 +68,7 @@ class ProxyFragment : Fragment(), View.OnClickListener, TextWatcher { lateinit var preferenceRepository: dagger.Lazy @Inject - lateinit var cachedExecutor: CachedExecutor + lateinit var executor: CoroutineExecutor @Inject lateinit var handler: dagger.Lazy @@ -82,7 +82,7 @@ class ProxyFragment : Fragment(), View.OnClickListener, TextWatcher { private var sharedPreferences: SharedPreferences? = null private var etBackground: Drawable? = null - private var futureTask: Future<*>? = null + private var task: Job? = null override fun onCreate(savedInstanceState: Bundle?) { App.instance.daggerComponent.inject(this) @@ -236,7 +236,7 @@ class ProxyFragment : Fragment(), View.OnClickListener, TextWatcher { handler.get().removeCallbacksAndMessages(null) - futureTask?.let { if (it.isCancelled) it.cancel(true) } + task?.let { if (!it.isCompleted) it.cancel() } _binding = null } @@ -311,7 +311,7 @@ class ProxyFragment : Fragment(), View.OnClickListener, TextWatcher { return } - futureTask = cachedExecutor.submit { + task = executor.submit("ProxyFragment checkProxy") { try { val result = proxyHelper.checkProxyConnectivity(server, port.toInt()) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyHelper.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyHelper.kt index 9879aba56..02f077acf 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyHelper.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/proxy/ProxyHelper.kt @@ -30,7 +30,7 @@ import pan.alexander.tordnscrypt.utils.Constants.IPv4_REGEX import pan.alexander.tordnscrypt.utils.Constants.LOOPBACK_ADDRESS import pan.alexander.tordnscrypt.utils.Constants.QUAD_DNS_41 import pan.alexander.tordnscrypt.utils.enums.ModuleState -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor import pan.alexander.tordnscrypt.utils.filemanager.FileManager import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_OUTBOUND_PROXY @@ -48,7 +48,7 @@ private const val CHECK_CONNECTION_TIMEOUT_MSEC = 500 class ProxyHelper @Inject constructor( private val context: Context, private val pathVars: PathVars, - private val cachedExecutor: CachedExecutor, + private val executor: CoroutineExecutor, @Named(DEFAULT_PREFERENCES_NAME) private val defaultPreferences: SharedPreferences ) { @@ -107,7 +107,7 @@ class ProxyHelper @Inject constructor( "$LOOPBACK_ADDRESS:$DEFAULT_PROXY_PORT" } - cachedExecutor.submit { + executor.submit("ProxyHelper manageProxy") { if ((enableDNSCryptProxy xor dnsCryptProxified) || serverOrPortChanged) { manageDNSCryptProxy(pathVars.dnscryptConfPath, proxyAddr, enableDNSCryptProxy) defaultPreferences.edit().putBoolean(DNSCRYPT_OUTBOUND_PROXY, enableDNSCryptProxy) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PathVars.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PathVars.java index 5ffddef48..af920fe5b 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PathVars.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PathVars.java @@ -384,6 +384,14 @@ public String getDNSCryptOwnResolversPath() { return appDataDir + "/app_data/dnscrypt-proxy/own-resolvers.md"; } + public String getOdohServersPath() { + return appDataDir + "/app_data/dnscrypt-proxy/odoh-servers.md"; + } + + public String getOdohRelaysPath() { + return appDataDir + "/app_data/dnscrypt-proxy/odoh-relays.md"; + } + public String getCacheDirPath(Context context) { String cacheDirPath = "/storage/emulated/0/Android/data/" + context.getPackageName() + "/cache"; diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java index 0c0bb785b..dcfb81ed8 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesCommonFragment.java @@ -60,8 +60,8 @@ import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.modules.ModulesStatusBroadcaster; import pan.alexander.tordnscrypt.proxy.ProxyHelper; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.Utils; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; @@ -114,7 +114,7 @@ public class PreferencesCommonFragment extends PreferenceFragmentCompat @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy handler; @Inject @@ -308,7 +308,7 @@ public void onResume() { } } - cachedExecutor.submit(() -> { + executor.submit("PreferencesCommonFragment verifier", () -> { try { Verifier verifier = verifierLazy.get(); String appSign = verifier.getAppSignature(); @@ -329,6 +329,7 @@ public void onResume() { } loge("PreferencesCommonFragment fault", e, true); } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java index 8ce65a42b..ae3a03bfd 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesFastFragment.java @@ -85,6 +85,7 @@ import static pan.alexander.tordnscrypt.utils.enums.ModuleState.RUNNING; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.ROOT_MODE; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.VPN_MODE; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_ENTRY_NODES; import javax.inject.Inject; import javax.inject.Named; @@ -146,7 +147,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, } Preference useBridges = findPreference("prefTorBridges"); - boolean entryNodes = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("EntryNodes", false); + boolean entryNodes = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TOR_ENTRY_NODES, false); if (useBridges != null && entryNodes) { useBridges.setEnabled(false); useBridges.setSummary(R.string.pref_fast_use_tor_bridges_alt_summ); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java index 4d69d90e8..c2705d995 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/PreferencesITPDFragment.java @@ -42,23 +42,29 @@ import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.modules.ModulesAux; import pan.alexander.tordnscrypt.modules.ModulesStatus; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.modules.ModulesRestarter; +import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED; import static pan.alexander.tordnscrypt.utils.enums.OperationMode.ROOT_MODE; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.I2PD_OUTBOUND_PROXY; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.I2PD_USE_IPV6; import javax.inject.Inject; +import javax.inject.Named; public class PreferencesITPDFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; + @Inject + @Named(DEFAULT_PREFERENCES_NAME) + public Lazy defaultPreferences; private ArrayList key_itpd; private ArrayList val_itpd; @@ -86,7 +92,7 @@ public void onCreate(Bundle savedInstanceState) { preferences.add(findPreference("incoming port")); preferences.add(findPreference("incoming host")); preferences.add(findPreference("ipv4")); - preferences.add(findPreference("ipv6")); + preferences.add(findPreference(I2PD_USE_IPV6)); preferences.add(findPreference("notransit")); preferences.add(findPreference("floodfill")); preferences.add(findPreference("bandwidth")); @@ -316,6 +322,11 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu } } } else if (Objects.equals(preference.getKey(), "ssu2 enabled")) { + + if (!defaultPreferences.get().getBoolean("ntcp2 enabled", true) && !Boolean.parseBoolean(newValue.toString())) { + return false; + } + if (!key_itpd.contains("[ssu2]") && key_itpd.contains("[ntcp2]")) { int positionNtcp2 = key_itpd.indexOf("[ntcp2]"); key_itpd.add(positionNtcp2, "[ssu2]"); @@ -331,6 +342,18 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu val_itpd.add(positionNtcp2 + 2, "false"); } } + } else if (Objects.equals(preference.getKey(), "ntcp2 enabled") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.get().getBoolean("ssu2 enabled", true)) { + return false; + } + } else if (Objects.equals(preference.getKey(), "ipv4") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.get().getBoolean(I2PD_USE_IPV6, true)) { + return false; + } + } else if (Objects.equals(preference.getKey(), I2PD_USE_IPV6) && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.get().getBoolean("ipv4", true)) { + return false; + } } if (key_itpd.contains(preference.getKey().trim())) { @@ -425,7 +448,7 @@ public boolean onPreferenceClick(@NonNull Preference preference) { return true; } - cachedExecutor.submit(() -> { + executor.submit("PreferencesITPDFragment onPreferenceClick", () -> { boolean successfully = false; if (getActivity() != null) { successfully = FileManager.deleteDirSynchronous(getActivity(), appDataDir + "/i2pd_data"); @@ -439,9 +462,8 @@ public boolean onPreferenceClick(@NonNull Preference preference) { } } + return null; }); - - return true; } else if ("editITPDConfDirectly".equals(preference.getKey()) && isAdded()) { ConfigEditorFragment.openEditorFragment(getParentFragmentManager(), "i2pd.conf"); @@ -454,28 +476,25 @@ public boolean onPreferenceClick(@NonNull Preference preference) { } private void changePreferencesForGPVersion() { - PreferenceCategory categoryCommon = findPreference("itpd_settings_common"); - if (categoryCommon != null) { - ArrayList preferences = new ArrayList<>(); - preferences.add(findPreference("Allow incoming connections")); - preferences.add(findPreference("incoming host")); - preferences.add(findPreference("incoming port")); + removeCategories(); - for (Preference preference : preferences) { - if (preference != null) { - categoryCommon.removePreference(preference); - } - } - } + removePreferencesFromLimitsCategory(); + + removePreferencesFromSocksProxyCategory(); + + removePreferencesFromHttpProxyCategory(); + + removePreferencesFromHttpOtherCategory(); + } + private void removeCategories() { PreferenceScreen preferenceScreen = findPreference("itpd_settings_screen"); if (preferenceScreen != null) { ArrayList categories = new ArrayList<>(); - categories.add(findPreference("category_itpd_sam_interface")); + categories.add(findPreference("itpd_settings_incoming")); categories.add(findPreference("category_itpd_cryptography")); - categories.add(findPreference("category_itpd_upnp")); categories.add(findPreference("category_itpd_reseeding")); for (PreferenceCategory category : categories) { @@ -484,7 +503,9 @@ private void changePreferencesForGPVersion() { } } } + } + private void removePreferencesFromLimitsCategory() { PreferenceCategory categoryLimits = findPreference("category_itpd_limits"); if (categoryLimits != null) { @@ -498,24 +519,37 @@ private void changePreferencesForGPVersion() { } } } + } + private void removePreferencesFromSocksProxyCategory() { + Preference proxyPort = findPreference("Socks proxy port"); + if (proxyPort != null) { + proxyPort.setDependency(null); + } PreferenceCategory categorySocksProxy = findPreference("itpd_category_socks_proxy"); Preference enableSocks = findPreference("Socks proxy"); if (categorySocksProxy != null && enableSocks != null) { categorySocksProxy.removePreference(enableSocks); } + } + private void removePreferencesFromHttpProxyCategory() { + Preference proxyPort = findPreference("HTTP proxy port"); + if (proxyPort != null) { + proxyPort.setDependency(null); + } PreferenceCategory categoryHTTPProxy = findPreference("itpd_category_http_proxy"); Preference enableHTTP = findPreference("HTTP proxy"); if (categoryHTTPProxy != null && enableHTTP != null) { categoryHTTPProxy.removePreference(enableHTTP); } + } + private void removePreferencesFromHttpOtherCategory() { PreferenceCategory otherCategory = findPreference("pref_itpd_other"); Preference editITPDConfDirectly = findPreference("editITPDConfDirectly"); if (otherCategory != null && editITPDConfDirectly != null) { otherCategory.removePreference(editITPDConfDirectly); } - } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/SettingsParser.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/SettingsParser.java index e92fd378c..fd73727a5 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/SettingsParser.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/SettingsParser.java @@ -24,6 +24,7 @@ import android.widget.Toast; import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.preference.PreferenceManager; @@ -48,6 +49,8 @@ import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_OUTBOUND_PROXY; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DORMANT_CLIENT_TIMEOUT; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.I2PD_OUTBOUND_PROXY; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_ENTRY_NODES; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_FASCIST_FIREWALL; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_OUTBOUND_PROXY; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_OUTBOUND_PROXY_ADDRESS; import static pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants.readTextFile; @@ -56,7 +59,6 @@ public class SettingsParser implements OnTextFileOperationsCompleteListener { private final SettingsActivity settingsActivity; private final String appDataDir; - private Bundle bundleForReadPublicResolversMdFunction; public SettingsParser(SettingsActivity settingsActivity, String appDataDir) { this.settingsActivity = settingsActivity; @@ -126,8 +128,13 @@ private void readDnscryptProxyToml(List lines) { key = "Relays"; } else if (header.matches("\\[sources\\.'?relays'?]") && key.equals("refresh_delay")) { key = "refresh_delay_relays"; - } else if (header.equals("[dns64]") && key.equals("prefix")) { - key = DNSCRYPT_DNS64_PREFIX; + } else if (header.equals("[dns64]") && key.matches("#?prefix")) { + if (key.equals("prefix")) { + editor.putBoolean("dns64", true); + } else if (key.equals("#prefix")) { + editor.putBoolean("dns64", false); + } + key = "dns64_prefix"; StringBuilder dns64Prefixes = new StringBuilder(); for (String dns64Prefix: val.split(", ?")) { dns64Prefix = dns64Prefix @@ -162,33 +169,32 @@ private void readDnscryptProxyToml(List lines) { if (val_saved_str != null && !val_saved_str.isEmpty() && !val_saved_str.equals(val)) { editor.putString(key, val); - } - if (isbool && val_saved_bool != Boolean.parseBoolean(val)) { + } else if (isbool && val_saved_bool != Boolean.parseBoolean(val)) { editor.putBoolean(key, Boolean.parseBoolean(val)); } if (key.equals("#proxy") && sp.getBoolean(DNSCRYPT_OUTBOUND_PROXY, false)) { editor.putBoolean(DNSCRYPT_OUTBOUND_PROXY, false); - } - if (key.equals("proxy_port") && !sp.getBoolean(DNSCRYPT_OUTBOUND_PROXY, false)) { + } else if (key.equals("proxy_port") && !sp.getBoolean(DNSCRYPT_OUTBOUND_PROXY, false)) { editor.putBoolean(DNSCRYPT_OUTBOUND_PROXY, true); - } - if (val.contains(appDataDir + "/cache/query.log") && !key.contains("#") && !sp.getBoolean("Enable Query logging", false)) { + } else if (val.contains(appDataDir + "/cache/query.log") && !key.contains("#") && !sp.getBoolean("Enable Query logging", false)) { editor.putBoolean("Enable Query logging", true); - } - if (val.contains(appDataDir + "/cache/query.log") && key.contains("#") && sp.getBoolean("Enable Query logging", false)) { + } else if (val.contains(appDataDir + "/cache/query.log") && key.contains("#") && sp.getBoolean("Enable Query logging", false)) { editor.putBoolean("Enable Query logging", false); - } - if (val.contains(appDataDir + "/cache/nx.log") && !key.contains("#") && !sp.getBoolean("Enable Query logging", false)) { + } else if (val.contains(appDataDir + "/cache/nx.log") && !key.contains("#") && !sp.getBoolean("Enable Query logging", false)) { editor.putBoolean("Enable Suspicious logging", true); - } - if (val.contains(appDataDir + "/cache/nx.log") && key.contains("#") && sp.getBoolean("Enable Query logging", false)) { + } else if (val.contains(appDataDir + "/cache/nx.log") && key.contains("#") && sp.getBoolean("Enable Query logging", false)) { editor.putBoolean("Enable Suspicious logging", false); } } editor.apply(); - FragmentTransaction fTrans = settingsActivity.getSupportFragmentManager().beginTransaction(); + FragmentManager manager = settingsActivity.getSupportFragmentManager(); + if (manager.isDestroyed()) { + return; + } + + FragmentTransaction fTrans = manager.beginTransaction(); Bundle bundle = new Bundle(); bundle.putStringArrayList("key_toml", key_toml); bundle.putStringArrayList("val_toml", val_toml); @@ -256,76 +262,43 @@ private void readTorConf(List lines) { switch (key) { - case "ExcludeNodes": - editor.putBoolean("ExcludeNodes", true); - break; - case "#ExcludeNodes": - editor.putBoolean("ExcludeNodes", false); - break; - case "EntryNodes": - editor.putBoolean("EntryNodes", true); - break; - case "#ExitNodes": - editor.putBoolean("ExitNodes", false); - break; - case "ExitNodes": - editor.putBoolean("ExitNodes", true); - break; - case "#ExcludeExitNodes": - editor.putBoolean("ExcludeExitNodes", false); - break; - case "ExcludeExitNodes": - editor.putBoolean("ExcludeExitNodes", true); - break; - case "#EntryNodes": - editor.putBoolean("EntryNodes", false); - break; - case "SOCKSPort": - editor.putBoolean("Enable SOCKS proxy", true); - break; - case "#SOCKSPort": - editor.putBoolean("Enable SOCKS proxy", false); - break; - case "TransPort": - editor.putBoolean("Enable Transparent proxy", true); - break; - case "#TransPort": - editor.putBoolean("Enable Transparent proxy", false); - break; - case "DNSPort": - editor.putBoolean("Enable DNS", true); - break; - case "#DNSPort": - editor.putBoolean("Enable DNS", false); - break; - case "HTTPTunnelPort": - editor.putBoolean("Enable HTTPTunnel", true); - break; - case "#HTTPTunnelPort": - editor.putBoolean("Enable HTTPTunnel", false); - break; - case TOR_OUTBOUND_PROXY_ADDRESS: - editor.putBoolean(TOR_OUTBOUND_PROXY, true); - break; - case "#Socks5Proxy": - editor.putBoolean(TOR_OUTBOUND_PROXY, false); - break; - case "TrackHostExits": - editor.putBoolean("Enable TrackHostExits", true); - break; - case "#TrackHostExits": - editor.putBoolean("Enable TrackHostExits", false); - break; + case "ExcludeNodes" -> editor.putBoolean("ExcludeNodes", true); + case "#ExcludeNodes" -> editor.putBoolean("ExcludeNodes", false); + case "EntryNodes" -> editor.putBoolean(TOR_ENTRY_NODES, true); + case "#ExitNodes" -> editor.putBoolean("ExitNodes", false); + case "ExitNodes" -> editor.putBoolean("ExitNodes", true); + case "#ExcludeExitNodes" -> editor.putBoolean("ExcludeExitNodes", false); + case "ExcludeExitNodes" -> editor.putBoolean("ExcludeExitNodes", true); + case "#EntryNodes" -> editor.putBoolean(TOR_ENTRY_NODES, false); + case "SOCKSPort" -> editor.putBoolean("Enable SOCKS proxy", true); + case "#SOCKSPort" -> editor.putBoolean("Enable SOCKS proxy", false); + case "TransPort" -> editor.putBoolean("Enable Transparent proxy", true); + case "#TransPort" -> editor.putBoolean("Enable Transparent proxy", false); + case "DNSPort" -> editor.putBoolean("Enable DNS", true); + case "#DNSPort" -> editor.putBoolean("Enable DNS", false); + case "HTTPTunnelPort" -> editor.putBoolean("Enable HTTPTunnel", true); + case "#HTTPTunnelPort" -> editor.putBoolean("Enable HTTPTunnel", false); + case TOR_OUTBOUND_PROXY_ADDRESS -> editor.putBoolean(TOR_OUTBOUND_PROXY, true); + case "#Socks5Proxy" -> editor.putBoolean(TOR_OUTBOUND_PROXY, false); + case "TrackHostExits" -> editor.putBoolean("Enable TrackHostExits", true); + case "#TrackHostExits" -> editor.putBoolean("Enable TrackHostExits", false); + case "ReachableAddresses" -> editor.putBoolean(TOR_FASCIST_FIREWALL, true); + case "#ReachableAddresses" -> editor.putBoolean(TOR_FASCIST_FIREWALL, false); } } editor.apply(); + FragmentManager manager = settingsActivity.getSupportFragmentManager(); + if (manager.isDestroyed()) { + return; + } + Bundle bundle = new Bundle(); bundle.putStringArrayList("key_tor", key_tor); bundle.putStringArrayList("val_tor", val_tor); PreferencesTorFragment frag = new PreferencesTorFragment(); frag.setArguments(bundle); - FragmentTransaction fTrans = settingsActivity.getSupportFragmentManager().beginTransaction(); + FragmentTransaction fTrans = manager.beginTransaction(); fTrans.replace(android.R.id.content, frag); fTrans.commit(); } @@ -441,7 +414,12 @@ private void readITPDconf(List lines) { } editor.apply(); - FragmentTransaction fTrans = settingsActivity.getSupportFragmentManager().beginTransaction(); + FragmentManager manager = settingsActivity.getSupportFragmentManager(); + if (manager.isDestroyed()) { + return; + } + + FragmentTransaction fTrans = manager.beginTransaction(); Bundle bundle = new Bundle(); bundle.putStringArrayList("key_itpd", key_itpd); bundle.putStringArrayList("val_itpd", val_itpd); @@ -459,7 +437,11 @@ private void readRules(String path, List lines) { } else { rules_file.add(""); } - FragmentTransaction fTrans = settingsActivity.getSupportFragmentManager().beginTransaction(); + FragmentManager manager = settingsActivity.getSupportFragmentManager(); + if (manager.isDestroyed()) { + return; + } + FragmentTransaction fTrans = manager.beginTransaction(); Bundle bundle = new Bundle(); bundle.putStringArrayList("rules_file", rules_file); bundle.putString("path", path); @@ -474,10 +456,6 @@ public void activateSettingsParser() { } public void deactivateSettingsParser() { - if (bundleForReadPublicResolversMdFunction != null) { - bundleForReadPublicResolversMdFunction.clear(); - } - FileManager.deleteOnFileOperationCompleteListener(this); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelay.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelay.kt new file mode 100644 index 000000000..b9cd43b8b --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelay.kt @@ -0,0 +1,25 @@ +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see . + + Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com + */ + +package pan.alexander.tordnscrypt.settings.dnscrypt_relays + +data class DnsRelay( + val name: String, + val description: String +) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelayViewModel.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelayViewModel.kt new file mode 100644 index 000000000..ebc2976d4 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelayViewModel.kt @@ -0,0 +1,90 @@ +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see . + + Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com + */ + +package pan.alexander.tordnscrypt.settings.dnscrypt_relays + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runInterruptible +import kotlinx.coroutines.withTimeout +import pan.alexander.tordnscrypt.di.CoroutinesModule +import pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.RelayType +import pan.alexander.tordnscrypt.utils.logger.Logger.loge +import pan.alexander.tordnscrypt.utils.parsers.DnsCryptConfigurationParser +import javax.inject.Inject +import javax.inject.Named + +class DnsRelayViewModel @Inject constructor( + private val dnsCryptConfigurationParser: DnsCryptConfigurationParser, + @Named(CoroutinesModule.DISPATCHER_IO) + private val dispatcherIo: CoroutineDispatcher +) : ViewModel() { + + private val relaysConfigurationMutable = + MutableLiveData(RelayConfigurationResult.Undefined) + val relaysConfigurationState: LiveData get() = relaysConfigurationMutable + + fun getRelaysConfiguration(type: RelayType) { + viewModelScope.launch { + try { + + relaysConfigurationMutable.value = RelayConfigurationResult.Loading + + val relaysMd = executeOnWorkerThread { + when (type) { + RelayType.DNSCRYPT_RELAY -> dnsCryptConfigurationParser.dnsCryptRelaysMd + RelayType.ODOH_RELAY -> dnsCryptConfigurationParser.odohRelaysMd + } + } + + val relays = executeOnWorkerThread { + dnsCryptConfigurationParser.parseDnsCryptRelaysMd(relaysMd) + } + + waitForObserverBecomeActive() + + relaysConfigurationMutable.value = RelayConfigurationResult.Relays(relays.toList()) + } catch (e: Exception) { + loge("DnsRelayViewModel getRelaysConfiguration", e) + } finally { + relaysConfigurationMutable.value = RelayConfigurationResult.Finished + delay(10) + relaysConfigurationMutable.value = RelayConfigurationResult.Undefined + } + } + } + + private suspend fun executeOnWorkerThread(block: () -> T): T = + runInterruptible(viewModelScope.coroutineContext + dispatcherIo) { + block() + } + + private suspend fun waitForObserverBecomeActive() { + withTimeout(5000) { + while (!relaysConfigurationState.hasActiveObservers()) { + delay(100) + } + } + } +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelaysAdapter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelaysAdapter.java index 825194fe8..678793dee 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelaysAdapter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/DnsRelaysAdapter.java @@ -19,39 +19,59 @@ package pan.alexander.tordnscrypt.settings.dnscrypt_relays; +import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; + import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.card.MaterialCardView; + import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import pan.alexander.tordnscrypt.R; class DnsRelaysAdapter extends RecyclerView.Adapter { - private final Context context; - private final ArrayList dnsRelayItems; - private final LayoutInflater lInflater; + private final List dnsRelayItems = new ArrayList<>(); + + private final int colorFirst; + private final int colorSecond; + + DnsRelaysAdapter(Context context) { + colorFirst = context.getResources().getColor(R.color.colorFirst); + colorSecond = context.getResources().getColor(R.color.colorSecond); + } + + void addItems(List items) { + dnsRelayItems.clear(); + dnsRelayItems.addAll(items); + Collections.sort(dnsRelayItems); + notifyItemRangeInserted(0, items.size()); + } + List getItems() { + return new ArrayList<>(dnsRelayItems); + } - DnsRelaysAdapter(Context context, ArrayList dnsRelayItems) { - this.context = context; - this.dnsRelayItems = dnsRelayItems; - this.lInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + @Override + public long getItemId(int position) { + return getItem(position).hashCode(); } @NonNull @Override public DNSRelaysViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = lInflater.inflate(R.layout.item_dns_relay, parent, false); + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_dns_relay, parent, false); return new DNSRelaysViewHolder(view); } @@ -73,9 +93,8 @@ private void setItem(int position, DnsRelayItem dnsRelayItem) { dnsRelayItems.set(position, dnsRelayItem); } - - - class DNSRelaysViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, CompoundButton.OnCheckedChangeListener, View.OnFocusChangeListener { + class DNSRelaysViewHolder extends RecyclerView.ViewHolder + implements View.OnClickListener, View.OnFocusChangeListener { private final TextView tvDNSRelayName; private final TextView tvDNSRelayDescription; private final CheckBox chbDNSRelay; @@ -83,8 +102,8 @@ class DNSRelaysViewHolder extends RecyclerView.ViewHolder implements View.OnClic DNSRelaysViewHolder(@NonNull View itemView) { super(itemView); - CardView cardDNSRelay = itemView.findViewById(R.id.cardDNSRelay); - cardDNSRelay.setCardBackgroundColor(context.getResources().getColor(R.color.colorFirst)); + MaterialCardView cardDNSRelay = itemView.findViewById(R.id.cardDNSRelay); + cardDNSRelay.setCardBackgroundColor(colorFirst); cardDNSRelay.setFocusable(true); cardDNSRelay.setOnClickListener(this); cardDNSRelay.setOnFocusChangeListener(this); @@ -92,7 +111,7 @@ class DNSRelaysViewHolder extends RecyclerView.ViewHolder implements View.OnClic tvDNSRelayName = itemView.findViewById(R.id.tvDNSRelayName); tvDNSRelayDescription = itemView.findViewById(R.id.tvDNSRelayDescription); chbDNSRelay = itemView.findViewById(R.id.chbDNSRelay); - chbDNSRelay.setOnCheckedChangeListener(this); + chbDNSRelay.setOnClickListener(this); } private void bind(int position) { @@ -105,31 +124,26 @@ private void bind(int position) { @Override public void onClick(View view) { - if (view.getId() == R.id.cardDNSRelay) { - int position = getAdapterPosition(); - DnsRelayItem dnsRelayItem = getItem(position); - dnsRelayItem.setChecked(!dnsRelayItem.isChecked()); - setItem(position, dnsRelayItem); - notifyItemChanged(position); + int position = getBindingAdapterPosition(); + if (position == NO_POSITION) { + return; } - } - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean newValue) { - int position = getAdapterPosition(); - DnsRelayItem dnsRelayItem = getItem(position); - if (dnsRelayItem.isChecked() != newValue) { - dnsRelayItem.setChecked(newValue); + int id = view.getId(); + if (id == R.id.cardDNSRelay || id == R.id.chbDNSRelay) { + DnsRelayItem dnsRelayItem = getItem(position); + dnsRelayItem.setChecked(!dnsRelayItem.isChecked()); setItem(position, dnsRelayItem); + notifyItemChanged(position, new Object()); } } @Override public void onFocusChange(View view, boolean newValue) { if (newValue) { - ((CardView) view).setCardBackgroundColor(context.getResources().getColor(R.color.colorSecond)); + ((CardView) view).setCardBackgroundColor(colorSecond); } else { - ((CardView) view).setCardBackgroundColor(context.getResources().getColor(R.color.colorFirst)); + ((CardView) view).setCardBackgroundColor(colorFirst); } } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/PreferencesDNSCryptRelays.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/PreferencesDNSCryptRelays.java index b642f57c2..8b8a5b9a4 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/PreferencesDNSCryptRelays.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/PreferencesDNSCryptRelays.java @@ -27,53 +27,46 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; import dagger.Lazy; import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; -import pan.alexander.tordnscrypt.dialogs.progressDialogs.PleaseWaitProgressDialog; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants; -import pan.alexander.tordnscrypt.utils.filemanager.FileManager; -import pan.alexander.tordnscrypt.utils.filemanager.OnTextFileOperationsCompleteListener; -import static pan.alexander.tordnscrypt.utils.logger.Logger.logw; +import com.google.android.material.progressindicator.LinearProgressIndicator; import javax.inject.Inject; -public class PreferencesDNSCryptRelays extends Fragment implements OnTextFileOperationsCompleteListener { +public class PreferencesDNSCryptRelays extends Fragment { + + public static String RELAY_TYPE_ARG = "pan.alexander.tordnscrypt.RELAY_TYPE_ARG"; + public static String SERVER_NAME_ARG = "pan.alexander.tordnscrypt.SERVER_NAME_ARG"; + public static String IPV6_SERVER_ARG = "pan.alexander.tordnscrypt.IPV6_SERVER_ARG"; + public static String ROUTES_ARG = "pan.alexander.tordnscrypt.ROUTES_ARG"; @Inject public Lazy pathVars; + @Inject + public ViewModelProvider.Factory viewModelFactory; - private String dnsServerName; - private final ArrayList dnsRelayItems = new ArrayList<>(); - private List routesCurrent = new ArrayList<>(); - private RecyclerView.Adapter adapter; - private OnRoutesChangeListener onRoutesChangeListener; - private DialogFragment pleaseWaitDialog; - private boolean serverIPv6; - + private DnsRelayViewModel viewModel; + private DnsRelaysAdapter adapter; + private LinearProgressIndicator pbDnsCryptRelays; public PreferencesDNSCryptRelays() { } public interface OnRoutesChangeListener { - void onRoutesChange(CopyOnWriteArrayList routesNew); - } - - public void setOnRoutesChangeListener(OnRoutesChangeListener onRoutesChangeListener) { - this.onRoutesChangeListener = onRoutesChangeListener; + void onRoutesChange(List routes, String currentServer); } @Override @@ -81,11 +74,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { App.getInstance().getDaggerComponent().inject(this); super.onCreate(savedInstanceState); - setRetainInstance(true); - - takeArguments(getArguments()); - - openPleaseWaitDialog(); + viewModel = new ViewModelProvider(this, viewModelFactory).get(DnsRelayViewModel.class); } @Override @@ -101,63 +90,42 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, View view = inflater.inflate(R.layout.fragment_preferences_dnscrypt_relays, container, false); + pbDnsCryptRelays = view.findViewById(R.id.pbDnsCryptRelays); RecyclerView rvDNSRelay = view.findViewById(R.id.rvDNSRelays); RecyclerView.LayoutManager manager = new LinearLayoutManager(activity); rvDNSRelay.setLayoutManager(manager); - adapter = new DnsRelaysAdapter(activity, dnsRelayItems); + adapter = new DnsRelaysAdapter(activity); + adapter.setHasStableIds(true); rvDNSRelay.setAdapter(adapter); return view; } @Override - public void onResume() { - super.onResume(); + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); - FileManager.setOnFileOperationCompleteListener(this); - - if (dnsRelayItems.isEmpty()) { - FileManager.readTextFile( - requireContext(), - pathVars.get().getAppDataDir() + "/app_data/dnscrypt-proxy/relays.md", "relays.md" - ); - } - } - - @Override - public void OnFileOperationComplete(FileOperationsVariants currentFileOperation, boolean fileOperationResult, String path, String tag, List lines) { - closePleaseWaitDialog(); - if (currentFileOperation == FileOperationsVariants.readTextFile && fileOperationResult && tag.equals("relays.md")) { - fillDnsRelaysList(new ArrayList<>(lines)); - } - } - - @Override - public void onPause() { - super.onPause(); - - FileManager.deleteOnFileOperationCompleteListener(this); + observeConfigurationState(); + requestRelaysConfiguration(); } @Override public void onStop() { super.onStop(); - if (dnsServerName == null || dnsRelayItems.isEmpty()) { - return; - } + List dnsRelayItems = adapter.getItems(); - if (routesCurrent == null) { - routesCurrent = new CopyOnWriteArrayList<>(); + if (dnsRelayItems.isEmpty()) { + return; } - DnsServerRelay dnsServerRelaysNew = createRelaysObjForCurrentServer(); + DnsServerRelay serverRoutes = getRelaysForCurrentServer(dnsRelayItems); - CopyOnWriteArrayList routesNew = updateRelaysListForAllServers(dnsServerRelaysNew); + List allRoutes = updateAndGetRelaysForAllServers(serverRoutes); - callbackToPreferencesDNSCryptServers(routesNew); + saveRoutes(allRoutes); } @Override @@ -165,98 +133,94 @@ public void onDestroyView() { super.onDestroyView(); adapter = null; - pleaseWaitDialog = null; + pbDnsCryptRelays = null; } - @SuppressWarnings("unchecked") - private void takeArguments(Bundle args) { - if (args != null) { - dnsServerName = args.getString("dnsServerName"); - - ArrayList routesCurrentTmp = (ArrayList) args.getSerializable("routesCurrent"); - - if (routesCurrentTmp != null) { - routesCurrent = routesCurrentTmp; - } - - serverIPv6 = args.getBoolean("dnsServerIPv6"); - + private void requestRelaysConfiguration() { + Bundle bundle = getArguments(); + if (bundle == null) { + return; + } + Object type = bundle.get(RELAY_TYPE_ARG); + if (type != null) { + viewModel.getRelaysConfiguration((RelayType) type); } } - private void fillDnsRelaysList(List lines) { - String name = ""; - String description = ""; - boolean lockRelay = false; - - for (String line : lines) { - if (line.isEmpty()) { - continue; - } - - if (line.contains("##")) { - name = line.replace("##", "").trim(); - lockRelay = true; - } else if (lockRelay && line.contains("sdns://")) { - lockRelay = false; - } else if (lockRelay) { - description = line.replaceAll("\\s", " ").trim(); + private void observeConfigurationState() { + viewModel.getRelaysConfigurationState().observe(getViewLifecycleOwner(), state -> { + if (state instanceof RelayConfigurationResult.Loading) { + showProgress(); + } else if (state instanceof RelayConfigurationResult.Relays) { + List relays = ((RelayConfigurationResult.Relays) state).getRelays(); + fillDnsRelaysList(relays); + } else if (state instanceof RelayConfigurationResult.Finished) { + hideProgress(); } + }); + } - if (!name.isEmpty() && !description.isEmpty() && !lockRelay) { - DnsRelayItem dnsRelayItem = new DnsRelayItem(name, description); - - dnsRelayItem.setChecked(isDnsRelaySelected(name)); - - boolean addServer; - - boolean relayIPv6 = name.contains("ipv6"); - - if (serverIPv6) { - addServer = relayIPv6; - } else { - addServer = !relayIPv6; - } - - if (addServer) { - dnsRelayItems.add(dnsRelayItem); - } - - - name = ""; - description = ""; + private void fillDnsRelaysList(List relays) { + List recyclerItems = new ArrayList<>(); + String dnsServerName = getServerName(); + boolean ipv6Server = isServerIPv6(); + List routes = getRoutes(); + for (DnsRelay relay : relays) { + if (ipv6Server && isRelayIPv6(relay) || !ipv6Server && !isRelayIPv6(relay)) { + DnsRelayItem item = new DnsRelayItem(relay.getName(), relay.getDescription()); + item.setChecked(isDnsRelaySelected(routes, dnsServerName, relay.getName())); + recyclerItems.add(item); } } - Collections.sort(dnsRelayItems); + adapter.addItems(recyclerItems); + } - Activity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(() -> adapter.notifyDataSetChanged()); + private String getServerName() { + Bundle bundle = getArguments(); + if (bundle == null) { + return ""; } + return bundle.getString(SERVER_NAME_ARG); } - private boolean isDnsRelaySelected(String name) { - boolean result = false; - - if (routesCurrent == null || dnsServerName == null) { + private boolean isServerIPv6() { + Bundle bundle = getArguments(); + if (bundle == null) { return false; } + return bundle.getBoolean(IPV6_SERVER_ARG); + } - for (int i = 0; i < routesCurrent.size(); i++) { - DnsServerRelay dnsServerRelays = routesCurrent.get(i); - if (dnsServerRelays.dnsServerName().equals(dnsServerName)) { - if (dnsServerRelays.dnsServerRelays().contains(name)) { - result = true; - break; - } - } + @SuppressWarnings("unchecked") + private List getRoutes() { + Bundle bundle = getArguments(); + if (bundle == null) { + return Collections.emptyList(); } + Object routes = bundle.getSerializable(ROUTES_ARG); + if (routes != null) { + return (ArrayList) routes; + } + return Collections.emptyList(); + } + + private boolean isRelayIPv6(DnsRelay relay) { + return relay.getName().contains("ipv6"); + } - return result; + private boolean isDnsRelaySelected(List routes, String serverName, String relayName) { + for (int i = 0; i < routes.size(); i++) { + DnsServerRelay route = routes.get(i); + if (route.dnsServerName().equals(serverName) + && route.dnsServerRelays().contains(relayName)) { + return true; + } + } + return false; } - private DnsServerRelay createRelaysObjForCurrentServer() { - ArrayList dnsRelaysNamesForCurrentServer = new ArrayList<>(); + private DnsServerRelay getRelaysForCurrentServer(List dnsRelayItems) { + List dnsRelaysNamesForCurrentServer = new ArrayList<>(); for (DnsRelayItem dnsRelayItem : dnsRelayItems) { if (dnsRelayItem.isChecked()) { dnsRelaysNamesForCurrentServer.add(dnsRelayItem.getName()); @@ -265,15 +229,17 @@ private DnsServerRelay createRelaysObjForCurrentServer() { DnsServerRelay dnsServerRelaysNew = null; if (!dnsRelaysNamesForCurrentServer.isEmpty()) { - dnsServerRelaysNew = new DnsServerRelay(dnsServerName, dnsRelaysNamesForCurrentServer); + dnsServerRelaysNew = new DnsServerRelay(getServerName(), dnsRelaysNamesForCurrentServer); } return dnsServerRelaysNew; } - private CopyOnWriteArrayList updateRelaysListForAllServers(DnsServerRelay dnsServerRelaysNew) { - CopyOnWriteArrayList routesNew = new CopyOnWriteArrayList<>(); + private List updateAndGetRelaysForAllServers(DnsServerRelay dnsServerRelaysNew) { + List routesNew = new ArrayList<>(); + List routesCurrent = getRoutes(); + String dnsServerName = getServerName(); for (int i = 0; i < routesCurrent.size(); i++) { DnsServerRelay dnsServerRelays = routesCurrent.get(i); @@ -294,28 +260,29 @@ private CopyOnWriteArrayList updateRelaysListForAllServers(DnsSe return routesNew; } - private void callbackToPreferencesDNSCryptServers(CopyOnWriteArrayList routesNew) { - if (onRoutesChangeListener != null) { - onRoutesChangeListener.onRoutesChange(routesNew); + private void saveRoutes(List routesNew) { + String server = getServerName(); + for (Fragment fragment: getParentFragmentManager().getFragments()) { + if (fragment instanceof OnRoutesChangeListener) { + ((OnRoutesChangeListener) fragment).onRoutesChange(routesNew, server); + break; + } } } - private void openPleaseWaitDialog() { - if (isAdded()) { - pleaseWaitDialog = new PleaseWaitProgressDialog(); - pleaseWaitDialog.show(getParentFragmentManager(), "PleaseWaitProgressDialog"); - } + private void showProgress() { + pbDnsCryptRelays.setVisibility(View.VISIBLE); + pbDnsCryptRelays.setIndeterminate(true); } - private void closePleaseWaitDialog() { - if (pleaseWaitDialog != null && pleaseWaitDialog.isAdded()) { - try { - pleaseWaitDialog.dismiss(); - pleaseWaitDialog = null; - } catch (Exception e) { - logw("PreferencesDNSCryptRelays closePleaseWaitDialog", e); - } - } + private void hideProgress() { + pbDnsCryptRelays.setIndeterminate(false); + pbDnsCryptRelays.setVisibility(View.GONE); + } + + public enum RelayType { + DNSCRYPT_RELAY, + ODOH_RELAY } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/RelayConfigurationResult.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/RelayConfigurationResult.kt new file mode 100644 index 000000000..64db0e930 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_relays/RelayConfigurationResult.kt @@ -0,0 +1,27 @@ +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see . + + Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com + */ + +package pan.alexander.tordnscrypt.settings.dnscrypt_relays + +interface RelayConfigurationResult { + data object Loading : RelayConfigurationResult + data class Relays(val relays: List) : RelayConfigurationResult + data object Finished : RelayConfigurationResult + data object Undefined : RelayConfigurationResult +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsCryptConfigurationResult.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsCryptConfigurationResult.kt index b76b65baf..847372143 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsCryptConfigurationResult.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsCryptConfigurationResult.kt @@ -28,6 +28,7 @@ sealed interface DnsCryptConfigurationResult { data class DnsCryptRoutes(val routes: List): DnsCryptConfigurationResult data class DnsCryptPublicResolvers(val resolvers: List): DnsCryptConfigurationResult data class DnsCryptOwnResolvers(val resolvers: List): DnsCryptConfigurationResult + data class DnsCryptOdohResolvers(val resolvers: List): DnsCryptConfigurationResult data object Finished: DnsCryptConfigurationResult data object Undefined: DnsCryptConfigurationResult } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerFeatures.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerFeatures.kt new file mode 100644 index 000000000..d7dab5b22 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerFeatures.kt @@ -0,0 +1,48 @@ +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see . + + Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com + */ + +package pan.alexander.tordnscrypt.settings.dnscrypt_servers + +import android.content.Context +import android.content.SharedPreferences +import pan.alexander.tordnscrypt.R +import pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated + +data class DnsServerFeatures( + val requireDnssec: Boolean, + val requireNofilter: Boolean, + var requireNolog: Boolean, + val useDnsServers: Boolean, + val useDohServers: Boolean, + val useOdohServers: Boolean, + val useIPv4Servers: Boolean, + val useIPv6Servers: Boolean +) { + constructor(context: Context, defaultPreferences: SharedPreferences) : this( + requireDnssec = defaultPreferences.getBoolean("require_dnssec", false), + requireNofilter = defaultPreferences.getBoolean("require_nofilter", false) + || context.getText(R.string.package_name).contains(".gp") && !accelerated, + requireNolog = defaultPreferences.getBoolean("require_nolog", false), + useDnsServers = defaultPreferences.getBoolean("dnscrypt_servers", true), + useDohServers = defaultPreferences.getBoolean("doh_servers", true), + useOdohServers = defaultPreferences.getBoolean("odoh_servers", true), + useIPv4Servers = defaultPreferences.getBoolean("ipv4_servers", true), + useIPv6Servers = defaultPreferences.getBoolean("ipv6_servers", true) + ) +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerItem.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerItem.java index f70dd705b..48ab9c45f 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerItem.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerItem.java @@ -19,60 +19,47 @@ package pan.alexander.tordnscrypt.settings.dnscrypt_servers; -import static pan.alexander.tordnscrypt.assistance.AccelerateDevelop.accelerated; - -import android.content.Context; -import android.content.SharedPreferences; import android.util.Base64; import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import pan.alexander.tordnscrypt.R; - public class DnsServerItem implements Comparable { private boolean checked = false; private boolean dnssec = false; private boolean nolog = false; private boolean nofilter = false; private boolean protoDoH = false; + private boolean protoODoH = false; private boolean protoDNSCrypt = false; private boolean ipv6 = false; private boolean visibility = true; private String name; private final String description; private final String sdns; - private boolean ownServer = false; + private boolean ownServer; private final ArrayList routes = new ArrayList<>(); - public DnsServerItem(Context context, String name, String description, String sdns) throws IllegalArgumentException { + public DnsServerItem( + String name, + String description, + String sdns, + DnsServerFeatures features + ) throws IllegalArgumentException { this.name = name; this.description = description; this.sdns = sdns; - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - - boolean require_dnssec = sp.getBoolean("require_dnssec", false); - boolean require_nofilter = sp.getBoolean("require_nofilter", false); - boolean require_nolog = sp.getBoolean("require_nolog", false); - boolean use_dns_servers = sp.getBoolean("dnscrypt_servers", true); - boolean use_doh_servers = sp.getBoolean("doh_servers", true); - boolean use_ipv4_servers = sp.getBoolean("ipv4_servers", true); - boolean use_ipv6_servers = sp.getBoolean("ipv6_servers", true); - - if (!accelerated && context.getText(R.string.package_name).toString().contains(".gp")) { - require_nofilter = true; - } - byte[] bin = Base64.decode(sdns.substring(0, 7).getBytes(), 16); if (bin[0] == 0x01) { protoDNSCrypt = true; } else if (bin[0] == 0x02) { protoDoH = true; + } else if (bin[0] == 0x05) { + protoODoH = true; } else { throw new IllegalArgumentException("Wrong sever type"); } @@ -91,26 +78,32 @@ public DnsServerItem(Context context, String name, String description, String sd ipv6 = true; } - if (require_dnssec) + if (features.getRequireDnssec()) this.visibility = this.dnssec; - if (require_nofilter) + if (features.getRequireNofilter()) this.visibility = this.visibility && this.nofilter; - if (require_nolog) + if (features.getRequireNolog()) this.visibility = this.visibility && this.nolog; - if (!use_dns_servers) + if (!features.getUseDnsServers()) this.visibility = this.visibility && !this.protoDNSCrypt; - if (!use_doh_servers) + if (!features.getUseDohServers()) this.visibility = this.visibility && !this.protoDoH; - if (!use_ipv4_servers) + if (!features.getUseOdohServers()) + this.visibility = this.visibility && !this.protoODoH; + + if (!features.getUseIPv4Servers()) this.visibility = this.visibility && ipv6; - if (!use_ipv6_servers) + if (!features.getUseIPv6Servers()) this.visibility = this.visibility && !ipv6; + + if (ownServer) + this.visibility = true; } public boolean isChecked() { @@ -137,6 +130,10 @@ boolean isProtoDoH() { return protoDoH; } + boolean isProtoODoH() { + return protoODoH; + } + boolean isProtoDNSCrypt() { return protoDNSCrypt; } @@ -174,6 +171,7 @@ ArrayList getRoutes() { } void setRoutes(List routes) { + this.routes.clear(); this.routes.addAll(routes); } @@ -190,6 +188,7 @@ public boolean equals(Object o) { nolog == that.nolog && nofilter == that.nofilter && protoDoH == that.protoDoH && + protoODoH == that.protoODoH && protoDNSCrypt == that.protoDNSCrypt && name.equals(that.name) && description.equals(that.description) && @@ -198,7 +197,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(dnssec, nolog, nofilter, protoDoH, protoDNSCrypt, name, description, sdns); + return Objects.hash(dnssec, nolog, nofilter, protoDoH, protoODoH, protoDNSCrypt, name, description, sdns); } @NonNull @@ -210,6 +209,7 @@ public String toString() { ", nolog=" + nolog + ", nofilter=" + nofilter + ", protoDoH=" + protoDoH + + ", protoODoH=" + protoODoH + ", protoDNSCrypt=" + protoDNSCrypt + ", visibility=" + visibility + ", name='" + name + '\'' + @@ -225,7 +225,7 @@ public int compareTo(DnsServerItem dnsServerItem) { } else if (this.checked && !dnsServerItem.checked) { return -1; } else { - return 0; + return this.name.compareTo(dnsServerItem.name); } } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerViewModel.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerViewModel.kt index 592a1ae7a..a368dca55 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerViewModel.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServerViewModel.kt @@ -24,29 +24,32 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel import kotlinx.coroutines.delay +import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import kotlinx.coroutines.plus +import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.withTimeout import pan.alexander.tordnscrypt.di.CoroutinesModule import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.parsers.DnsCryptConfigurationParser import javax.inject.Inject import javax.inject.Named -import kotlin.coroutines.CoroutineContext class DnsServerViewModel @Inject constructor( private val dnsCryptConfigurationParser: DnsCryptConfigurationParser, @Named(CoroutinesModule.DISPATCHER_IO) - private val dispatcherIo: CoroutineDispatcher + private val dispatcherIo: CoroutineDispatcher, + @Named(CoroutinesModule.SUPERVISOR_JOB_IO_DISPATCHER_SCOPE) + private val baseCoroutineScope: CoroutineScope, + coroutineExceptionHandler: CoroutineExceptionHandler ) : ViewModel() { - private val coroutineContext: CoroutineContext = - SupervisorJob() + dispatcherIo + CoroutineName("DnsServerViewModelCoroutine") + private val scope: CoroutineScope = + baseCoroutineScope + CoroutineName("DnsServerViewModelCoroutine") + coroutineExceptionHandler var searchQuery: String? = "" @@ -58,13 +61,13 @@ class DnsServerViewModel @Inject constructor( viewModelScope.launch { try { - waitForObserverBecomeActive() - dnsCryptConfigurationMutable.value = DnsCryptConfigurationResult.Loading + ensureActive() val dnsCryptProxyToml = executeOnWorkerThread { dnsCryptConfigurationParser.dnsCryptProxyToml } + waitForObserverBecomeActive() dnsCryptConfigurationMutable.value = DnsCryptConfigurationResult.DnsCryptProxyToml(dnsCryptProxyToml) @@ -73,13 +76,13 @@ class DnsServerViewModel @Inject constructor( } dnsCryptConfigurationMutable.value = DnsCryptConfigurationResult.DnsCryptServers(dnsCryptServers) - + ensureActive() val dnsCryptRoutes = executeOnWorkerThread { dnsCryptConfigurationParser.getDnsCryptRoutes(dnsCryptProxyToml) } dnsCryptConfigurationMutable.value = DnsCryptConfigurationResult.DnsCryptRoutes(dnsCryptRoutes) - + ensureActive() val publicResolversMd = executeOnWorkerThread { dnsCryptConfigurationParser.publicResolversMd } @@ -88,7 +91,16 @@ class DnsServerViewModel @Inject constructor( } dnsCryptConfigurationMutable.value = DnsCryptConfigurationResult.DnsCryptPublicResolvers(dnsCryptPublicResolvers.toList()) - + ensureActive() + val odohServersMd = executeOnWorkerThread { + dnsCryptConfigurationParser.odohServersMd + } + val dnsCryptOdohResolvers = executeOnWorkerThread { + dnsCryptConfigurationParser.parseDnsCryptResolversMd(odohServersMd) + } + dnsCryptConfigurationMutable.value = + DnsCryptConfigurationResult.DnsCryptOdohResolvers(dnsCryptOdohResolvers.toList()) + ensureActive() val ownResolversMd = executeOnWorkerThread { dnsCryptConfigurationParser.ownResolversMd } @@ -108,7 +120,7 @@ class DnsServerViewModel @Inject constructor( } private suspend fun executeOnWorkerThread(block: () -> T): T = - withContext(coroutineContext) { + runInterruptible(viewModelScope.coroutineContext + dispatcherIo) { block() } @@ -121,22 +133,14 @@ class DnsServerViewModel @Inject constructor( } fun saveOwnResolversMd(lines: List) { - CoroutineScope(coroutineContext).launch { + scope.launch { dnsCryptConfigurationParser.saveOwnResolversMd(lines) } } fun saveDnsCryptProxyToml(lines: List) { - CoroutineScope(coroutineContext).launch { + scope.launch { dnsCryptConfigurationParser.saveDnsCryptProxyToml(lines) } } - - override fun onCleared() { - super.onCleared() - CoroutineScope(coroutineContext).launch { - delay(3000) - coroutineContext.cancel() - } - } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServersAdapter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServersAdapter.java index 55cf61d2e..df69eecc7 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServersAdapter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/DnsServersAdapter.java @@ -29,10 +29,10 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.ImageButton; import android.widget.TextView; +import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.appcompat.widget.LinearLayoutCompat; import androidx.appcompat.widget.SearchView; @@ -40,6 +40,8 @@ import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.card.MaterialCardView; + import java.util.List; import pan.alexander.tordnscrypt.R; @@ -53,6 +55,7 @@ class DnsServersAdapter extends RecyclerView.Adapter= 0) { @@ -157,10 +168,9 @@ private void removeItem(int position) { class DNSServersViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener, - CompoundButton.OnCheckedChangeListener, View.OnFocusChangeListener { - private final CardView cardDNSServer; + private final MaterialCardView cardDNSServer; private final TextView tvDNSServerName; private final CheckBox chbDNSServer; private final TextView tvDNSServerDescription; @@ -184,7 +194,7 @@ class DNSServersViewHolder extends RecyclerView.ViewHolder chbDNSServer = itemView.findViewById(R.id.chbDNSServer); chbDNSServer.setFocusable(false); - chbDNSServer.setOnCheckedChangeListener(this); + chbDNSServer.setOnClickListener(this); tvDNSServerDescription = itemView.findViewById(R.id.tvDNSServerDescription); tvDNSServerFlags = itemView.findViewById(R.id.tvDNSServerFlags); btnDNSServerRelay = itemView.findViewById(R.id.btnDNSServerRelay); @@ -226,6 +236,16 @@ private void bind(int position) { } else if (dnsServer.isProtoDoH()) { sb.append("").append(dohServer).append(" "); btnDNSServerRelay.setVisibility(View.GONE); + } else if (dnsServer.isProtoODoH()) { + sb.append("").append(odohServer).append(" "); + if (dnsServer.isChecked()) { + String routes = getRoutes(dnsServer).toString(); + btnDNSServerRelay.setVisibility(View.VISIBLE); + btnDNSServerRelay.setText(routes); + } else { + btnDNSServerRelay.setVisibility(View.GONE); + btnDNSServerRelay.setText(""); + } } if (dnsServer.isNofilter()) { sb.append("").append(nonFilteringServer).append(" "); @@ -262,11 +282,14 @@ public void onClick(View view) { } int id = view.getId(); - if (id == R.id.cardDNSServer) { + if (id == R.id.cardDNSServer || id == R.id.chbDNSServer) { DnsServerItem dnsServer = getItem(position); dnsServer.setChecked(!dnsServer.isChecked()); setItem(position, dnsServer); - DnsServersAdapter.this.notifyItemChanged(position); + DnsServersAdapter.this.notifyItemChanged(position, new Object()); + if (dnsServer.isChecked() && dnsServer.isProtoODoH() && dnsServer.getRoutes().isEmpty()) { + preferencesDNSCryptServers.openDNSRelaysPref(dnsServer); + } } else if (id == R.id.btnDNSServerRelay) { preferencesDNSCryptServers.openDNSRelaysPref(getItem(position)); } else if (id == R.id.delBtnDNSServer) { @@ -286,21 +309,6 @@ public void onFocusChange(View view, boolean hasFocus) { } } - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - int position = getBindingAdapterPosition(); - if (position == NO_POSITION) { - return; - } - - DnsServerItem dnsServer = getItem(position); - if (dnsServer.isChecked() != checked) { - dnsServer.setChecked(checked); - setItem(position, dnsServer); - DnsServersAdapter.this.notifyItemChanged(position); - } - } - @Override public boolean onLongClick(View view) { int position = getBindingAdapterPosition(); @@ -348,4 +356,8 @@ private StringBuilder getRoutes(DnsServerItem dnsServer) { } return routes; } + + private String getHexFromColors(Context context, @ColorRes int colorRes) { + return String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(context, colorRes))); + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/PreferencesDNSCryptServers.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/PreferencesDNSCryptServers.java index fb2284c1a..239d5251d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/PreferencesDNSCryptServers.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_servers/PreferencesDNSCryptServers.java @@ -21,6 +21,7 @@ import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; @@ -49,7 +50,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; import dagger.Lazy; import pan.alexander.tordnscrypt.App; @@ -63,10 +63,17 @@ import pan.alexander.tordnscrypt.settings.dnscrypt_relays.DnsServerRelay; import pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays; import pan.alexander.tordnscrypt.utils.enums.ModuleState; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import static pan.alexander.tordnscrypt.TopFragment.TOP_BROADCAST; +import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.IPV6_SERVER_ARG; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.RELAY_TYPE_ARG; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.ROUTES_ARG; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.RelayType.DNSCRYPT_RELAY; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.RelayType.ODOH_RELAY; +import static pan.alexander.tordnscrypt.settings.dnscrypt_relays.PreferencesDNSCryptRelays.SERVER_NAME_ARG; import static pan.alexander.tordnscrypt.utils.logger.Logger.loge; import static pan.alexander.tordnscrypt.utils.logger.Logger.logw; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.DNSCRYPT_SERVERS; @@ -75,6 +82,7 @@ import com.google.android.material.progressindicator.LinearProgressIndicator; import javax.inject.Inject; +import javax.inject.Named; public class PreferencesDNSCryptServers extends Fragment implements View.OnClickListener, PreferencesDNSCryptRelays.OnRoutesChangeListener, @@ -83,9 +91,12 @@ public class PreferencesDNSCryptServers extends Fragment implements View.OnClick @Inject public Lazy preferenceRepository; @Inject + @Named(DEFAULT_PREFERENCES_NAME) + public Lazy defaultPreferences; + @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy verifierLazy; @Inject @@ -95,6 +106,7 @@ public class PreferencesDNSCryptServers extends Fragment implements View.OnClick private RecyclerView.Adapter dnsServersAdapter; private final List dnscryptProxyToml = new ArrayList<>(); private List dnsCryptPublicResolversMd; + private List dnsCryptOdohResolversMd; private List dnsCryptOwnResolversMd; private final Set savedOwnDNSCryptServers = new LinkedHashSet<>(); private final List dnscryptServersToml = new ArrayList<>(); @@ -123,7 +135,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { return; } - cachedExecutor.submit(() -> { + executor.submit("PreferencesDNSCryptServers verifier", () -> { try { Verifier verifier = verifierLazy.get(); String appSign = verifier.getAppSignature(); @@ -144,6 +156,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { } loge("PreferencesDNSCryptServers fault", e, true); } + return null; }); } @@ -182,7 +195,9 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } observeDnsCryptConfiguration(); - requestDnsCryptConfiguration(); + if (dnscryptProxyToml.isEmpty()) { + requestDnsCryptConfiguration(); + } } private void setTitle() { @@ -199,6 +214,7 @@ private void initRecycler() { rvDNSServers.setLayoutManager(mLayoutManager); dnsServersAdapter = new DnsServersAdapter(this); + dnsServersAdapter.setHasStableIds(true); try { rvDNSServers.setAdapter(dnsServersAdapter); @@ -212,7 +228,9 @@ private void initRecycler() { } private void updateRecycler() { - dnsServersAdapter.notifyDataSetChanged(); + if (dnsServersAdapter != null) { + dnsServersAdapter.notifyDataSetChanged(); + } } @RequiresApi(api = Build.VERSION_CODES.M) @@ -310,9 +328,17 @@ private void saveSettings() { } @Override - public void onRoutesChange(CopyOnWriteArrayList routesNew) { + public void onRoutesChange(List routes, String server) { dnsCryptRoutesToml.clear(); - dnsCryptRoutesToml.addAll(routesNew); + dnsCryptRoutesToml.addAll(routes); + for (DnsServerItem item: dnsServerItems) { + if (item.getName().equals(server)){ + item.setRoutes(getRoutes(item)); + item.setChecked(!item.isProtoODoH() || !item.getRoutes().isEmpty()); + break; + } + } + updateRecycler(); } private void requestDnsCryptConfiguration() { @@ -337,6 +363,8 @@ private void observeDnsCryptConfiguration() { dnsCryptRoutesToml.addAll(routes); } else if (configuration instanceof DnsCryptConfigurationResult.DnsCryptPublicResolvers) { dnsCryptPublicResolversMd = ((DnsCryptConfigurationResult.DnsCryptPublicResolvers) configuration).getResolvers(); + } else if (configuration instanceof DnsCryptConfigurationResult.DnsCryptOdohResolvers) { + dnsCryptOdohResolversMd = ((DnsCryptConfigurationResult.DnsCryptOdohResolvers) configuration).getResolvers(); } else if (configuration instanceof DnsCryptConfigurationResult.DnsCryptOwnResolvers) { dnsCryptOwnResolversMd = ((DnsCryptConfigurationResult.DnsCryptOwnResolvers) configuration).getResolvers(); } else if (configuration instanceof DnsCryptConfigurationResult.Finished) { @@ -357,14 +385,25 @@ private void observeDnsCryptConfiguration() { private void fillDnsServersList() { dnsServerItems.clear(); + + addServersFromPublicResolversMd(); + addServersFromOdohServersMd(); + + Collections.sort(dnsServerItems); + dnsServerItemsSaved.clear(); + dnsServerItemsSaved.addAll(dnsServerItems); + } + + private void addServersFromPublicResolversMd() { Context context = requireContext(); + DnsServerFeatures features = new DnsServerFeatures(context, defaultPreferences.get()); for (int i = 0; i < dnsCryptPublicResolversMd.size(); i++) { try { DnsServerItem dnsServer = new DnsServerItem( - context, dnsCryptPublicResolversMd.get(i).getName(), dnsCryptPublicResolversMd.get(i).getDescription(), - dnsCryptPublicResolversMd.get(i).getSdns() + dnsCryptPublicResolversMd.get(i).getSdns(), + features ); dnsServer.setChecked(isDnsServerActive(dnsServer)); dnsServer.setRoutes(getRoutes(dnsServer)); @@ -378,10 +417,30 @@ private void fillDnsServersList() { } } + } - Collections.sort(dnsServerItems); - dnsServerItemsSaved.clear(); - dnsServerItemsSaved.addAll(dnsServerItems); + private void addServersFromOdohServersMd() { + Context context = requireContext(); + DnsServerFeatures features = new DnsServerFeatures(context, defaultPreferences.get()); + for (int i = 0; i < dnsCryptOdohResolversMd.size(); i++) { + try { + DnsServerItem dnsServer = new DnsServerItem( + dnsCryptOdohResolversMd.get(i).getName(), + dnsCryptOdohResolversMd.get(i).getDescription(), + dnsCryptOdohResolversMd.get(i).getSdns(), + features + ); + dnsServer.setChecked(isDnsServerActive(dnsServer)); + dnsServer.setRoutes(getRoutes(dnsServer)); + if (dnsServer.isVisible()) { + dnsServerItems.add(dnsServer); + } + } catch (Exception e) { + logw("Trying to add wrong ODoH server " + + e.getMessage() + " " + e.getCause() + " " + + dnsCryptOdohResolversMd.get(i)); + } + } } private boolean isDnsServerActive(DnsServerItem dnsServer) { @@ -395,7 +454,7 @@ private boolean isDnsServerActive(DnsServerItem dnsServer) { } private List getRoutes(DnsServerItem dnsServer) { - if (dnsServer.isProtoDNSCrypt()) { + if (dnsServer.isProtoDNSCrypt() || dnsServer.isProtoODoH()) { for (int i = 0; i < dnsCryptRoutesToml.size(); i++) { if (dnsCryptRoutesToml.get(i).dnsServerName().equals(dnsServer.getName())) { return dnsCryptRoutesToml.get(i).dnsServerRelays(); @@ -412,6 +471,9 @@ private String dnsServersListToLine() { for (int i = 0; i < dnsServerItems.size(); i++) { if (dnsServerItems.get(i).isChecked()) { + if (dnsServerItems.get(i).isProtoODoH() && dnsServerItems.get(i).getRoutes().isEmpty()) { + continue; + } servers.append(dnsServerItems.get(i).getName()); servers.append("', '"); } @@ -599,14 +661,16 @@ public void onClick(View v) { } private void addOwnDnsCryptServers() { + Context context = requireContext(); + DnsServerFeatures features = new DnsServerFeatures(context, defaultPreferences.get()); List dnsServerItemsOwn = new ArrayList<>(); for (DnsCryptResolver resolver : dnsCryptOwnResolversMd) { try { DnsServerItem dnsServer = new DnsServerItem( - getContext(), resolver.getName(), resolver.getDescription(), - resolver.getSdns() + resolver.getSdns(), + features ); dnsServer.setOwnServer(true); dnsServer.setChecked(isDnsServerActive(dnsServer)); @@ -697,6 +761,7 @@ private boolean searchServer(String searchText) { || dnsServerItem.getDescription().toLowerCase().contains(searchText.toLowerCase()) || (dnsServerItem.isProtoDNSCrypt() && searchText.toLowerCase().contains("dnscrypt server")) || (dnsServerItem.isProtoDoH() && searchText.toLowerCase().contains("doh server")) + || (dnsServerItem.isProtoODoH() && searchText.toLowerCase().contains("odoh server")) || (dnsServerItem.isDnssec() && searchText.toLowerCase().contains("dnssec")) || (dnsServerItem.isNofilter() && searchText.toLowerCase().contains("non-filtering")) || (dnsServerItem.isNolog() && searchText.toLowerCase().contains("non-logging")) @@ -713,11 +778,15 @@ private boolean searchServer(String searchText) { void openDNSRelaysPref(DnsServerItem dnsServer) { Bundle bundle = new Bundle(); - bundle.putString("dnsServerName", dnsServer.getName()); - bundle.putBoolean("dnsServerIPv6", dnsServer.isIpv6()); - bundle.putSerializable("routesCurrent", dnsCryptRoutesToml); + if (dnsServer.isProtoDNSCrypt()) { + bundle.putSerializable(RELAY_TYPE_ARG, DNSCRYPT_RELAY); + } else if (dnsServer.isProtoODoH()) { + bundle.putSerializable(RELAY_TYPE_ARG, ODOH_RELAY); + } + bundle.putString(SERVER_NAME_ARG, dnsServer.getName()); + bundle.putBoolean(IPV6_SERVER_ARG, dnsServer.isIpv6()); + bundle.putSerializable(ROUTES_ARG, dnsCryptRoutesToml); PreferencesDNSCryptRelays preferencesDNSCryptRelays = new PreferencesDNSCryptRelays(); - preferencesDNSCryptRelays.setOnRoutesChangeListener(this); preferencesDNSCryptRelays.setArguments(bundle); FragmentTransaction fragmentTransaction = getParentFragmentManager().beginTransaction(); fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_settings/PreferencesDNSFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_settings/PreferencesDNSFragment.java index f938af1c2..bbce09044 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_settings/PreferencesDNSFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/dnscrypt_settings/PreferencesDNSFragment.java @@ -58,9 +58,9 @@ import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.settings.ConfigEditorFragment; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.Utils; import pan.alexander.tordnscrypt.utils.enums.DNSCryptRulesVariant; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.vpn.service.VpnBuilder; @@ -105,7 +105,7 @@ public class PreferencesDNSFragment extends PreferenceFragmentCompat @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject @Named(DEFAULT_PREFERENCES_NAME) public SharedPreferences defaultPreferences; @@ -138,6 +138,7 @@ public void onCreate(Bundle savedInstanceState) { preferences.add(findPreference(DNSCRYPT_LISTEN_PORT)); preferences.add(findPreference("dnscrypt_servers")); preferences.add(findPreference("doh_servers")); + preferences.add(findPreference("odoh_servers")); preferences.add(findPreference("require_dnssec")); preferences.add(findPreference("require_nolog")); preferences.add(findPreference("require_nofilter")); @@ -346,6 +347,22 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu val_toml.set(key_toml.indexOf("listen_addresses"), val); return true; + } else if (Objects.equals(preference.getKey(), "dnscrypt_servers") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.getBoolean("doh_servers", true)) { + return false; + } + } else if (Objects.equals(preference.getKey(), "doh_servers") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.getBoolean("dnscrypt_servers", true)) { + return false; + } + } else if (Objects.equals(preference.getKey(), "ipv4_servers") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.getBoolean("ipv6_servers", true)) { + return false; + } + } else if (Objects.equals(preference.getKey(), "ipv6_servers") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.getBoolean("ipv4_servers", true)) { + return false; + } } else if (Objects.equals(preference.getKey(), DNSCRYPT_BOOTSTRAP_RESOLVERS)) { List resolvers = getDNSCryptBootstrapResolvers(newValue.toString()); @@ -470,7 +487,7 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu return true; } else if (Objects.equals(preference.getKey().trim(), DNSCRYPT_DNS64_PREFIX)) { StringBuilder dns64Prefixes = new StringBuilder("["); - for (String dns64Prefix: newValue.toString().split(", ?")) { + for (String dns64Prefix : newValue.toString().split(", ?")) { if (dns64Prefix.matches(IPv6_REGEX_WITH_MASK)) { if (!dns64Prefixes.toString().equals("[")) { dns64Prefixes.append(", "); @@ -509,7 +526,7 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu changeDNSCryptBootstrapResolvers(resolvers); } else if (!Boolean.parseBoolean(newValue.toString())) { boolean containsIPv6Resolver = false; - for (String resolver: resolvers) { + for (String resolver : resolvers) { if (resolver.matches(IPv6_REGEX)) { containsIPv6Resolver = true; break; @@ -542,7 +559,7 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu private List getDNSCryptBootstrapResolvers(String newValue) { List resolvers = new ArrayList<>(); - for (String resolver: newValue.split(", ?")) { + for (String resolver : newValue.split(", ?")) { if ((resolver.matches(IPv4_REGEX) || resolver.matches(IPv6_REGEX)) && !resolver.equals(LOOPBACK_ADDRESS) && !resolver.equals(META_ADDRESS)) { resolvers.add(resolver); @@ -582,7 +599,7 @@ private void changeDNSCryptNetprobeAddress(List resolvers) { ipv4address = QUAD_DNS_41; } StringBuilder val = new StringBuilder(); - val.append("'").append(ipv4address).append( ":53'"); + val.append("'").append(ipv4address).append(":53'"); if (key_toml.indexOf(DNSCRYPT_NETPROBE_ADDRESS) > 0) { val_toml.set(key_toml.indexOf(DNSCRYPT_NETPROBE_ADDRESS), val.toString()); } @@ -636,7 +653,7 @@ private void changeDNSCryptSourcesForIPv6(boolean newValue) { && val_toml.get(i).contains(DNSCRYPT_RESOLVERS_SOURCE_IPV6)) { urls.setLength(0); String resolvers = clearUrlsLine(val_toml.get(i)); - for (String resolver: resolvers.split(", ?")) { + for (String resolver : resolvers.split(", ?")) { if (!resolver.equals(DNSCRYPT_RESOLVERS_SOURCE_IPV6)) { if (urls.length() == 0) { urls.append("["); @@ -656,7 +673,7 @@ private void changeDNSCryptSourcesForIPv6(boolean newValue) { && !val_toml.get(i).contains(DNSCRYPT_RESOLVERS_SOURCE_IPV6)) { urls.setLength(0); String resolvers = clearUrlsLine(val_toml.get(i)); - for (String resolver: resolvers.split(", ?")) { + for (String resolver : resolvers.split(", ?")) { if (urls.length() == 0) { urls.append("["); } else { @@ -673,7 +690,7 @@ private void changeDNSCryptSourcesForIPv6(boolean newValue) { && val_toml.get(i).contains(DNSCRYPT_RELAYS_SOURCE_IPV6)) { urls.setLength(0); String relays = clearUrlsLine(val_toml.get(i)); - for (String relay: relays.split(", ?")) { + for (String relay : relays.split(", ?")) { if (!relay.equals(DNSCRYPT_RELAYS_SOURCE_IPV6)) { if (urls.length() == 0) { urls.append("["); @@ -693,7 +710,7 @@ private void changeDNSCryptSourcesForIPv6(boolean newValue) { && !val_toml.get(i).contains(DNSCRYPT_RELAYS_SOURCE_IPV6)) { urls.setLength(0); String relays = clearUrlsLine(val_toml.get(i)); - for (String relay: relays.split(", ?")) { + for (String relay : relays.split(", ?")) { if (urls.length() == 0) { urls.append("["); } else { @@ -900,11 +917,31 @@ private void removePreferencesWithGPVersion() { if (otherCategory != null && editDNSTomlDirectly != null) { otherCategory.removePreference(editDNSTomlDirectly); } + + PreferenceCategory dnsCryptServersCategory = findPreference("pref_dnscrypt_servers"); + Preference serverSources = findPreference("Sources"); + + if (dnsCryptServersCategory != null && serverSources != null) { + dnsCryptServersCategory.removePreference(serverSources); + } + + PreferenceCategory dnsCryptRelaysCategory = findPreference("pref_dnscrypt_relays"); + Preference relaySources = findPreference("Relays"); + + if (dnsCryptRelaysCategory != null && relaySources != null) { + dnsCryptRelaysCategory.removePreference(relaySources); + } } private void checkRootDirAccessible() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - cachedExecutor.submit(() -> rootDirAccessible = Utils.INSTANCE.isLogsDirAccessible()); + executor.submit( + "PreferencesDNSFragment checkRootDirAccessible", + () -> { + rootDirAccessible = Utils.INSTANCE.isLogsDirAccessible(); + return null; + } + ); } } @@ -929,7 +966,7 @@ private void cleanModuleFolder(Context context) { return; } - cachedExecutor.submit(() -> { + executor.submit("PreferencesDNSFragment cleanModuleFolder", () -> { boolean successfully1 = !FileManager.deleteFileSynchronous(context, appDataDir + "/app_data/dnscrypt-proxy", "public-resolvers.md"); @@ -942,7 +979,7 @@ private void cleanModuleFolder(Context context) { Activity activity = getActivity(); if (activity == null) { - return; + return null; } if (successfully1 || successfully2 || successfully3 || successfully4) { @@ -950,6 +987,7 @@ private void cleanModuleFolder(Context context) { } else { activity.runOnUiThread(() -> Toast.makeText(activity, R.string.wrong, Toast.LENGTH_SHORT).show()); } + return null; }); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallAppModel.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallAppModel.kt index f6be7f7de..7e2b44858 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallAppModel.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallAppModel.kt @@ -21,12 +21,15 @@ package pan.alexander.tordnscrypt.settings.firewall import pan.alexander.tordnscrypt.settings.tor_apps.ApplicationData -data class FirewallAppModel(val applicationData: ApplicationData, - var allowLan: Boolean, - var allowWifi: Boolean, - var allowGsm: Boolean, - var allowRoaming: Boolean, - var allowVPN: Boolean): Comparable { +data class FirewallAppModel( + val applicationData: ApplicationData, + var allowLan: Boolean, + var allowWifi: Boolean, + var allowGsm: Boolean, + var allowRoaming: Boolean, + var allowVPN: Boolean, + val bypassVPN: Boolean +) : Comparable { override fun compareTo(other: FirewallAppModel): Int { return applicationData.uid.compareTo(other.applicationData.uid) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallNotification.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallNotification.kt index a688f3227..08abb510d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallNotification.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallNotification.kt @@ -22,6 +22,7 @@ package pan.alexander.tordnscrypt.settings.firewall import android.Manifest import android.annotation.SuppressLint import android.app.Notification +import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver @@ -32,10 +33,11 @@ import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.os.Build +import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import androidx.preference.PreferenceManager import pan.alexander.tordnscrypt.App -import pan.alexander.tordnscrypt.FIREWALL_CHANNEL_ID import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.settings.SettingsActivity import pan.alexander.tordnscrypt.modules.ModulesStatus @@ -49,6 +51,8 @@ const val DENY_ACTION = "pan.alexander.tordnscrypt.DENY_APP_FOR_FIREWALL" const val NOTIFICATION_ID = "pan.alexander.tordnscrypt.NOTIFICATION_ID" const val EXTRA_UID = "pan.alexander.tordnscrypt.EXTRA_UID" +private const val FIREWALL_CHANNEL_ID = "Firewall" + class FirewallNotification : BroadcastReceiver() { private val modulesStatus = ModulesStatus.getInstance() @@ -99,7 +103,7 @@ class FirewallNotification : BroadcastReceiver() { context.applicationContext?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager? val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - newAppsAreAllowed = sharedPreferences.getBoolean("NewAppsInternetAllowed", false) + newAppsAreAllowed = sharedPreferences.getBoolean(FIREWALL_NO_BLOCK_NEW_APP, false) val action = intent?.action ?: return @@ -332,6 +336,10 @@ class FirewallNotification : BroadcastReceiver() { return } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createFirewallChannel(context) + } + val notificationIntent = Intent(context, SettingsActivity::class.java) notificationIntent.action = "firewall" notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER) @@ -423,4 +431,22 @@ class FirewallNotification : BroadcastReceiver() { val notification = builder.build() notificationManager.notify(notificationId, notification) } + + @RequiresApi(Build.VERSION_CODES.O) + private fun createFirewallChannel(context: Context) { + val notificationManager = + ContextCompat.getSystemService(context, NotificationManager::class.java) + val channel = NotificationChannel( + FIREWALL_CHANNEL_ID, + context.getString(R.string.notification_channel_firewall), + NotificationManager.IMPORTANCE_HIGH + ) + channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT) + channel.description = "" + channel.enableLights(true) + channel.enableVibration(true) + channel.lockscreenVisibility = Notification.VISIBILITY_PRIVATE + channel.setShowBadge(true) + notificationManager?.createNotificationChannel(channel) + } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallViewModel.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallViewModel.kt index bfaa173f0..db7af7af8 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallViewModel.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/FirewallViewModel.kt @@ -33,6 +33,7 @@ import pan.alexander.tordnscrypt.settings.PathVars import pan.alexander.tordnscrypt.settings.tor_apps.ApplicationData import pan.alexander.tordnscrypt.utils.Utils import pan.alexander.tordnscrypt.utils.apps.InstalledApplicationsManager +import pan.alexander.tordnscrypt.utils.enums.OperationMode import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.* import java.util.concurrent.ConcurrentSkipListSet @@ -58,6 +59,7 @@ class FirewallViewModel @Inject constructor( var appsAllowGsm = mutableSetOf() var appsAllowRoaming = mutableSetOf() var appsAllowVpn = mutableSetOf() + private val appsBypassVpn = mutableSetOf() val criticalSystemUids = hashSetOf() @@ -90,6 +92,11 @@ class FirewallViewModel @Inject constructor( appsAllowVpn.addAll( preferences.getStringSetPreference(APPS_ALLOW_VPN).toIntSet() ) + if (modulesStatus.mode == OperationMode.VPN_MODE) { + appsBypassVpn.addAll( + preferences.getStringSetPreference(APPS_BYPASS_VPN) + ) + } val installedApps = InstalledApplicationsManager.Builder() .setOnAppAddListener(this) @@ -112,7 +119,8 @@ class FirewallViewModel @Inject constructor( appsAllowWifi.contains(uid), appsAllowGsm.contains(uid), appsAllowRoaming.contains(uid), - appsAllowVpn.contains(uid) + appsAllowVpn.contains(uid), + appsBypassVpn.contains(applicationData.pack) ) ) } @@ -133,7 +141,8 @@ class FirewallViewModel @Inject constructor( appsAllowWifi.contains(uid), appsAllowGsm.contains(uid), appsAllowRoaming.contains(uid), - appsAllowVpn.contains(uid) + appsAllowVpn.contains(uid), + appsBypassVpn.contains(application.pack) ) ) firewallStateMutableLiveData.postValue(FirewallState.Preparing) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/adapter/FirewallAdapter.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/adapter/FirewallAdapter.kt index 95e385bc4..5010338c3 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/adapter/FirewallAdapter.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/firewall/adapter/FirewallAdapter.kt @@ -22,6 +22,7 @@ package pan.alexander.tordnscrypt.settings.firewall.adapter import android.annotation.SuppressLint import android.content.Context import android.content.SharedPreferences +import android.graphics.Color import android.graphics.drawable.Drawable import android.text.Html import android.view.LayoutInflater @@ -31,9 +32,11 @@ import android.widget.ImageButton import android.widget.ImageView import android.widget.TextView import androidx.annotation.UiThread +import androidx.appcompat.widget.AppCompatImageButton import androidx.core.content.ContextCompat import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.card.MaterialCardView import pan.alexander.tordnscrypt.R import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository import pan.alexander.tordnscrypt.modules.ModulesStatus @@ -69,12 +72,14 @@ class FirewallAdapter( private val showAllApps = defaultPreferences.getBoolean(FIREWALL_SHOWS_ALL_APPS, false) private val comparatorByName: Comparator = compareBy( + { !it.bypassed }, { !it.newlyInstalled }, { !(it.lan || it.wifi || it.gsm || it.roaming || it.vpn && rootMode) }, { it.label } ) private val comparatorByUid: Comparator = compareBy( + { !it.bypassed }, { !it.newlyInstalled }, { !(it.lan || it.wifi || it.gsm || it.roaming || it.vpn && rootMode) }, { it.uid } @@ -95,7 +100,8 @@ class FirewallAdapter( gsm = it.allowGsm, roaming = it.allowRoaming, vpn = it.allowVPN, - newlyInstalled = appsNewlyInstalledSavedSet.contains(it.applicationData.uid) + newlyInstalled = appsNewlyInstalledSavedSet.contains(it.applicationData.uid), + bypassed = it.bypassVPN ) }.filter { if (showAllApps) { @@ -144,26 +150,12 @@ class FirewallAdapter( return diff.currentList[position] } - private val icFirewallLan = ContextCompat.getDrawable(context, R.drawable.ic_firewall_lan) - private val icFirewallLanGreen = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_lan_green) - private val icFirewallWifi = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_wifi_24) - private val icFirewallWifiGreen = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_wifi_green_24) - private val icFirewallGsm = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_gsm_24) - private val icFirewallGsmGreen = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_gsm_green_24) - private val icFirewallRoaming = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_roaming_24) - private val icFirewallRoamingGreen = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_roaming_green_24) - private val icFirewallVpn = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_vpn_key_24) - private val icFirewallVpnGreen = - ContextCompat.getDrawable(context, R.drawable.ic_firewall_vpn_key_green_24) - + private val colorIconGreen by lazy { + ContextCompat.getColor(context, R.color.colorIconGreen) + } + private val colorIconWhite by lazy { + ContextCompat.getColor(context, R.color.colorWhite) + } private val colorRed by lazy { ContextCompat.getColor(context, R.color.colorAlert) } @@ -181,16 +173,17 @@ class FirewallAdapter( View.OnClickListener { val context: Context = itemView.context + private val cardAppFirewall = itemView.findViewById(R.id.cardAppFirewall) private val imgAppIconFirewall = itemView.findViewById(R.id.imgAppIconFirewall) - private val btnLanFirewall = itemView.findViewById(R.id.btnLanFirewall) + private val btnLanFirewall = itemView.findViewById(R.id.btnLanFirewall) .also { it.setOnClickListener(this) } - private val btnWifiFirewall = itemView.findViewById(R.id.btnWifiFirewall) + private val btnWifiFirewall = itemView.findViewById(R.id.btnWifiFirewall) .also { it.setOnClickListener(this) } - private val btnGsmFirewall = itemView.findViewById(R.id.btnGsmFirewall) + private val btnGsmFirewall = itemView.findViewById(R.id.btnGsmFirewall) .also { it.setOnClickListener(this) } - private val btnRoamingFirewall = itemView.findViewById(R.id.btnRoamingFirewall) + private val btnRoamingFirewall = itemView.findViewById(R.id.btnRoamingFirewall) .also { it.setOnClickListener(this) } - private val btnVpnFirewall = itemView.findViewById(R.id.btnVpnFirewall) + private val btnVpnFirewall = itemView.findViewById(R.id.btnVpnFirewall) .also { it.setOnClickListener(this) } private val tvAppName = itemView.findViewById(R.id.tvAppName) @@ -202,7 +195,8 @@ class FirewallAdapter( val appFirewall = getItem(position) - imgAppIconFirewall.setImageDrawable(appFirewall.icon) + cardAppFirewall?.strokeColor = if (appFirewall.bypassed) colorRed else Color.TRANSPARENT + imgAppIconFirewall?.setImageDrawable(appFirewall.icon) val description = StringBuilder().apply { append(appFirewall.label) if (appFirewall.uid >= 0) { @@ -211,54 +205,104 @@ class FirewallAdapter( } } if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.M) { - tvAppName.text = Html.fromHtml(description.toString(), Html.FROM_HTML_MODE_COMPACT) + tvAppName?.text = Html.fromHtml(description.toString(), Html.FROM_HTML_MODE_COMPACT) } else { @Suppress("DEPRECATION") - tvAppName.text = Html.fromHtml(description.toString()) + tvAppName?.text = Html.fromHtml(description.toString()) } when { appFirewall.system && appFirewall.hasInternetPermission -> - tvAppName.setTextColor(colorRed) + tvAppName?.setTextColor(colorRed) appFirewall.system -> tvAppName.setTextColor(colorBrown) !appFirewall.hasInternetPermission -> - tvAppName.setTextColor(colorGreen) - else -> tvAppName.setTextColor(colorBlack) + tvAppName?.setTextColor(colorGreen) + else -> tvAppName?.setTextColor(colorBlack) } - btnLanFirewall.setImageDrawable( - if (appFirewall.lan) - icFirewallLanGreen - else - icFirewallLan - ) + btnLanFirewall?.apply { + when{ + appFirewall.bypassed -> { + isEnabled = false + setTint(colorIconGreen) + } + appFirewall.lan -> { + isEnabled = true + setTint(colorIconGreen) + } + else -> { + isEnabled = true + setTint(colorIconWhite) + } + } + } - btnWifiFirewall.setImageDrawable( - if (appFirewall.wifi) - icFirewallWifiGreen - else - icFirewallWifi - ) + btnWifiFirewall?.apply { + when{ + appFirewall.bypassed -> { + isEnabled = false + setTint(colorIconGreen) + } + appFirewall.wifi -> { + isEnabled = true + setTint(colorIconGreen) + } + else -> { + isEnabled = true + setTint(colorIconWhite) + } + } + } - btnGsmFirewall.setImageDrawable( - if (appFirewall.gsm) - icFirewallGsmGreen - else - icFirewallGsm - ) + btnGsmFirewall?.apply { + when{ + appFirewall.bypassed -> { + isEnabled = false + setTint(colorIconGreen) + } + appFirewall.gsm -> { + isEnabled = true + setTint(colorIconGreen) + } + else -> { + isEnabled = true + setTint(colorIconWhite) + } + } + } - btnRoamingFirewall.setImageDrawable( - if (appFirewall.roaming) - icFirewallRoamingGreen - else - icFirewallRoaming - ) + btnRoamingFirewall?.apply { + when{ + appFirewall.bypassed -> { + isEnabled = false + setTint(colorIconGreen) + } + appFirewall.roaming -> { + isEnabled = true + setTint(colorIconGreen) + } + else -> { + isEnabled = true + setTint(colorIconWhite) + } + } + } - btnVpnFirewall.setImageDrawable( - if (appFirewall.vpn) - icFirewallVpnGreen - else - icFirewallVpn - ) + btnVpnFirewall?.apply { + when{ + appFirewall.bypassed -> { + isEnabled = false + setTint(colorIconGreen) + } + appFirewall.vpn -> { + isEnabled = true + setTint(colorIconGreen) + } + else -> { + isEnabled = true + setTint(colorIconWhite) + } + } + } } @SuppressLint("NotifyDataSetChanged") @@ -301,6 +345,10 @@ class FirewallAdapter( } } + private fun AppCompatImageButton.setTint(color: Int) { + setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN) + } + enum class SortMethod { BY_NAME, BY_UID @@ -317,6 +365,7 @@ class FirewallAdapter( var gsm: Boolean, var roaming: Boolean, var vpn: Boolean, - val newlyInstalled: Boolean + val newlyInstalled: Boolean, + val bypassed: Boolean ) } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_apps/UnlockTorAppsFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_apps/UnlockTorAppsFragment.java index 608f78384..fab3df223 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_apps/UnlockTorAppsFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_apps/UnlockTorAppsFragment.java @@ -46,20 +46,21 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.CancellationException; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import dagger.Lazy; +import kotlinx.coroutines.Job; import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.di.SharedPreferencesModule; import pan.alexander.tordnscrypt.dialogs.NotificationHelper; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.modules.ModulesStatus; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.apps.InstalledApplicationsManager; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import static pan.alexander.tordnscrypt.TopFragment.TOP_BROADCAST; @@ -101,7 +102,7 @@ public class UnlockTorAppsFragment extends Fragment private Set setVpnBypassApps; String unlockAppsStr; - private FutureTask futureTask; + private Job task; private final ReentrantLock reentrantLock = new ReentrantLock(); private volatile boolean appsListComplete = false; private String searchText; @@ -111,7 +112,7 @@ public class UnlockTorAppsFragment extends Fragment @Inject public Lazy preferenceRepository; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy handler; @Inject @@ -226,7 +227,7 @@ private void onScrollWhenInNonTouchMode(int dy) { getDeviceApps(setUnlockApps); - cachedExecutor.submit(() -> { + executor.submit("UnlockTorAppsFragment verifier", () -> { try { Verifier verifier = verifierLazy.get(); String appSign = verifier.getAppSignature(); @@ -247,6 +248,7 @@ private void onScrollWhenInNonTouchMode(int dy) { } loge("UnlockTorAppsFragment fault", e, true); } + return null; }); } @@ -334,8 +336,8 @@ public void onDestroyView() { public void onDestroy() { super.onDestroy(); - if (futureTask != null && futureTask.cancel(true)) { - return; + if (task != null) { + task.cancel(new CancellationException()); } handler.get().removeCallbacksAndMessages(null); @@ -526,8 +528,7 @@ private void getDeviceApps(final Set unlockAppsArrListSaved) { return; } - futureTask = new FutureTask<>(() -> { - + task = executor.submit("UnlockTorAppsFragment getDeviceApps", () -> { try { reentrantLock.lockInterruptibly(); @@ -615,8 +616,6 @@ private void getDeviceApps(final Set unlockAppsArrListSaved) { return null; }); - cachedExecutor.submit(futureTask); - } private List filterUserAppsWithoutInternetPermission(List installedApps) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgeAdapter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgeAdapter.java index fc8fa035a..0a7df04e6 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgeAdapter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgeAdapter.java @@ -120,7 +120,7 @@ private void setActive(int position, boolean active) { bridgeList.set(position, brg); } - class BridgeViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener, + public class BridgeViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener, View.OnClickListener { private final TextView tvBridge; @@ -174,9 +174,7 @@ private void bind(int position) { tvBridgeText = bridgeComponents[0]; } - if (obfsType.contains(meek_lite.toString()) - || obfsType.contains(snowflake.toString()) - || obfsBridge.ping == 0) { + if (obfsBridge.ping == 0) { tvPing.setVisibility(View.GONE); } else { tvPing.setText(formatPing(obfsBridge.ping)); diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgePingHelper.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgePingHelper.kt new file mode 100644 index 000000000..7d509e848 --- /dev/null +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/BridgePingHelper.kt @@ -0,0 +1,236 @@ +/* + This file is part of InviZible Pro. + + InviZible Pro is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + InviZible Pro is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with InviZible Pro. If not, see . + + Copyright 2019-2024 by Garmatin Oleksandr invizible.soft@gmail.com + */ + +package pan.alexander.tordnscrypt.settings.tor_bridges + +import android.content.SharedPreferences +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.withContext +import pan.alexander.tordnscrypt.di.CoroutinesModule +import pan.alexander.tordnscrypt.di.SharedPreferencesModule.Companion.DEFAULT_PREFERENCES_NAME +import pan.alexander.tordnscrypt.domain.bridges.DefaultVanillaBridgeInteractor +import pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_USE_IPV6 +import pan.alexander.tordnscrypt.vpn.VpnUtils +import java.net.InetAddress +import java.util.concurrent.ConcurrentHashMap +import java.util.regex.Pattern +import javax.inject.Inject +import javax.inject.Named + +@ExperimentalCoroutinesApi +class BridgePingHelper @Inject constructor( + @Named(CoroutinesModule.DISPATCHER_IO) + private val dispatcherIo: CoroutineDispatcher, + private val defaultVanillaBridgeInteractor: DefaultVanillaBridgeInteractor, + @Named(DEFAULT_PREFERENCES_NAME) + private val defaultPreferences: SharedPreferences +) { + + private val webTunnelBridgePattern by lazy { + Pattern.compile("^webtunnel +(.+:\\d+)(?: +\\w+)? +url=(http(s)?://[\\w.-]+)(?:/[\\w.-]+)*/?") + } + + private val meekLiteBridgePattern by lazy { + Pattern.compile("^meek_lite +(.+:\\d+)(?: +\\w+)? +url=https://[\\w./-]+ +front=([\\w./-]+)(?: +utls=\\w+)?") + } + + private val snowFlakeBridgePattern by lazy { + Pattern.compile("^snowflake +(.+:\\d+)(?: +\\w+)? ") + } + + suspend fun getRealIPFromWebTunnelBridges( + bridges: List, + bridgesMatcherMap: ConcurrentHashMap + ) = try { + withContext(dispatcherIo) { + val bridgesToMeasure = mutableListOf() + for (bridge in bridges) { + + val matcher = webTunnelBridgePattern.matcher(bridge.bridge) + if (matcher.find()) { + val ipWithPort = matcher.group(1) ?: continue + val domain = matcher.group(2) ?: continue + val port = if (domain.startsWith("https")) { + 443 + } else { + 80 + } + val ip = getWorkingIp(domain.replace(Regex("http(s)?://"), ""), port) + + ensureActive() + if (ip.isEmpty()) { + continue + } + + val address = getAddress(ip, port) + val bridgeLine = bridge.bridge.replace(ipWithPort, address) + bridgesToMeasure.add(bridgeLine) + bridgesMatcherMap[bridgeLine.hashCode()] = + bridge.bridge.hashCode() + } + } + bridgesToMeasure + } + } catch (ignored: Exception) { + emptyList() + } + + suspend fun getRealIPFromMeekLiteBridges( + bridges: List, + bridgesMatcherMap: ConcurrentHashMap + ) = try { + withContext(dispatcherIo) { + val bridgesToMeasure = mutableListOf() + for (bridge in bridges) { + + val matcher = meekLiteBridgePattern.matcher(bridge.bridge) + if (matcher.find()) { + val ipWithPort = matcher.group(1) ?: continue + val domain = matcher.group(2) ?: continue + val port = 443 + val ip = getWorkingIp(domain, port) + + ensureActive() + if (ip.isEmpty()) { + continue + } + + val address = getAddress(ip, port) + val bridgeLine = bridge.bridge.replace(ipWithPort, address) + bridgesToMeasure.add(bridgeLine) + bridgesMatcherMap[bridgeLine.hashCode()] = + bridge.bridge.hashCode() + } + } + bridgesToMeasure + } + } catch (ignored: Exception) { + emptyList() + } + + suspend fun getRealIPFromSnowFlakeBridges( + bridges: List, + bridgesMatcherMap: ConcurrentHashMap + ) = try { + withContext(dispatcherIo) { + val bridgesToMeasure = mutableListOf() + for (bridge in bridges) { + + val matcher = snowFlakeBridgePattern.matcher(bridge.bridge) + if (matcher.find()) { + val ipWithPort = matcher.group(1) ?: continue + val front = "front=" + val fronts = "fronts=" + val sqs = "sqsqueue=https://" + val domains = if (bridge.bridge.contains(fronts)) { + bridge.bridge.split(Regex(" +")) + .first { it.contains(fronts) } + .removePrefix(fronts) + .split(",") + } else if (bridge.bridge.contains(front)) { + bridge.bridge.split(Regex(" +")) + .first { it.contains(front) } + .removePrefix(front) + .let { listOf(it) } + } else if (bridge.bridge.contains(sqs)) { + bridge.bridge.split(Regex(" +")) + .first { it.contains(sqs) } + .removePrefix(sqs) + .split("/") + .firstOrNull() + ?.let { listOf(it) } + ?: emptyList() + } else { + emptyList() + } + + if (domains.isEmpty()) { + continue + } + + var ip = "" + val port = 443 + for (domain in domains.shuffled()) { + ip = getWorkingIp(domain, port) + if (ip.isNotEmpty()) { + break + } + } + + ensureActive() + if (ip.isEmpty()) { + continue + } + + val address = getAddress(ip, port) + val bridgeLine = bridge.bridge.replace(ipWithPort, address) + bridgesToMeasure.add(bridgeLine) + bridgesMatcherMap[bridgeLine.hashCode()] = + bridge.bridge.hashCode() + } + } + bridgesToMeasure + } + } catch (ignored: Exception) { + emptyList() + } + + private suspend fun getWorkingIp(domain: String, port: Int) = try { + withContext(dispatcherIo) { + InetAddress.getAllByName(domain) + }.mapNotNull { it.hostAddress } + } catch (ignored: Exception) { + emptyList() + }.filter { + !VpnUtils.isIpInLanRange(it) && (isUseIPv6() || !it.isIPv6Address()) + }.let { ips -> + coroutineScope { + ips.map { ip -> + async { + try { + if (isAddressReachable(ip, port)) ip else "" + } catch (e: Exception) { + "" + } + } + }.awaitAll() + .filter { it.isNotEmpty() } + .minByOrNull { it.isIPv6Address() } ?: "" + } + } + + + private suspend fun isAddressReachable(ip: String, port: Int): Boolean = + defaultVanillaBridgeInteractor.isAddressReachable(ip, port) + + private fun getAddress(ip: String, port: Int) = if (ip.isIPv6Address()) { + "[$ip]:$port" + } else { + "$ip:$port" + } + + private fun String.isIPv6Address() = contains(":") + + private fun isUseIPv6() = defaultPreferences.getBoolean(TOR_USE_IPV6, true) +} diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridges.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridges.java index 9ac38bca8..996724e9d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridges.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridges.java @@ -57,13 +57,14 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.Future; +import java.util.concurrent.CancellationException; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import dagger.Lazy; +import kotlinx.coroutines.Job; import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.dialogs.BridgesCaptchaDialogFragment; @@ -81,10 +82,10 @@ import pan.alexander.tordnscrypt.modules.ModulesRestarter; import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.enums.BridgeType; import pan.alexander.tordnscrypt.utils.enums.BridgesSelector; import pan.alexander.tordnscrypt.utils.enums.FileOperationsVariants; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import pan.alexander.tordnscrypt.utils.filemanager.OnTextFileOperationsCompleteListener; @@ -98,6 +99,7 @@ import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.RELAY_BRIDGES_REQUESTED; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.OWN_BRIDGES_OBFS; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_FASCIST_FIREWALL; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_FASCIST_FIREWALL_LOCK; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_USE_IPV6; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.USE_DEFAULT_BRIDGES; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.USE_NO_BRIDGES; @@ -137,6 +139,9 @@ public class PreferencesTorBridges extends Fragment implements View.OnClickListe private final String ADD_BRIDGES_TAG = "pan.alexander.tordnscrypt/abstract_add_bridges"; private final String ADD_REQUESTED_BRIDGES_TAG = "pan.alexander.tordnscrypt/abstract_add_requested_bridges"; + private final static String ipv4BridgeBase = "(\\d{1,3}\\.){3}\\d{1,3}:\\d+( +\\w+)?"; + private final static String ipv6BridgeBase = "\\[" + IPv6_REGEX_NO_BOUNDS + "]" + ":\\d+( +\\w+)?"; + private final List tor_conf = new ArrayList<>(); private final Set bridgesInUse = new LinkedHashSet<>(); private final List bridgesInappropriateType = new ArrayList<>(); @@ -166,7 +171,7 @@ public class PreferencesTorBridges extends Fragment implements View.OnClickListe private BridgeType currentBridgesType = undefined; private String requestedBridgesToAdd; private BridgesSelector savedBridgesSelector; - private Future verifyDefaultBridgesTask; + private Job verifyDefaultBridgesTask; private PreferencesTorBridgesViewModel viewModel; private final ModulesStatus modulesStatus = ModulesStatus.getInstance(); @@ -179,7 +184,7 @@ public class PreferencesTorBridges extends Fragment implements View.OnClickListe @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy handlerLazy; @Inject @@ -365,10 +370,20 @@ public void onStop() { } } - List torConfCleaned = new ArrayList<>(); + boolean fascistFirewallShouldBeDisabled = isFascistFirewallShouldBeDisabled(); + if (fascistFirewallShouldBeDisabled) { + defaultPreferences.get().edit().putBoolean(TOR_FASCIST_FIREWALL, false).apply(); + preferenceRepository.get().setBoolPreference(TOR_FASCIST_FIREWALL_LOCK, true); + } else { + preferenceRepository.get().setBoolPreference(TOR_FASCIST_FIREWALL_LOCK, false); + } + List torConfCleaned = new ArrayList<>(); for (int i = 0; i < tor_conf.size(); i++) { String line = tor_conf.get(i); + if (fascistFirewallShouldBeDisabled && line.startsWith("ReachableAddresses")) { + line = "#" + line; + } if ((line.contains("#") || (!line.contains("Bridge ") && !line.contains("ClientTransportPlugin ") @@ -455,6 +470,36 @@ public void onStop() { } + private boolean isFascistFirewallShouldBeDisabled() { + + boolean useNoBridges = preferenceRepository.get().getBoolPreference(USE_NO_BRIDGES); + if (useNoBridges) { + return false; + } + + Pattern patternIPv4 = Pattern.compile(ipv4BridgeBase); + Pattern patternIPv6 = Pattern.compile(ipv6BridgeBase); + for (String currentBridge : bridgesInUse) { + Pattern pattern; + if (isBridgeIPv6(currentBridge)) { + pattern = patternIPv6; + } else { + pattern = patternIPv4; + } + Matcher matcher = pattern.matcher(currentBridge); + String ip; + if (matcher.find()) { + ip = matcher.group().substring(0, matcher.group().lastIndexOf(" ")); + } else { + ip = ""; + } + if (!ip.endsWith(":80") && !ip.endsWith(":443")) { + return true; + } + } + return false; + } + private void restartTorIfRequired(Context context) { if (modulesStatus.getTorState() == RUNNING) { ModulesRestarter.restartTor(context); @@ -497,8 +542,8 @@ public void onDestroy() { handlerLazy.get().removeCallbacksAndMessages(null); - if (verifyDefaultBridgesTask != null && !verifyDefaultBridgesTask.isCancelled()) { - verifyDefaultBridgesTask.cancel(false); + if (verifyDefaultBridgesTask != null && !verifyDefaultBridgesTask.isCompleted()) { + verifyDefaultBridgesTask.cancel(new CancellationException()); verifyDefaultBridgesTask = null; } @@ -685,14 +730,12 @@ private void addBridges(final List persistList) { builder.setView(inputView); builder.setPositiveButton(getText(R.string.ok), (dialogInterface, i) -> { - String ipv4BridgeBase = "(\\d{1,3}\\.){3}\\d{1,3}:\\d+( +\\w+)?"; - String ipv6BridgeBase = "\\[" + IPv6_REGEX_NO_BOUNDS + "]" + ":\\d+( +\\w+)?"; List bridgesListNew = new ArrayList<>(); String inputLinesStr = input.getText().toString().trim(); String bridgeBase; - if (inputLinesStr.contains("[") && inputLinesStr.contains("]")) { + if (isBridgeIPv6(inputLinesStr)) { bridgeBase = ipv6BridgeBase; } else { bridgeBase = ipv4BridgeBase; @@ -782,6 +825,10 @@ private void addBridges(final List persistList) { builder.show(); } + private boolean isBridgeIPv6(String bridge) { + return bridge.contains("[") && bridge.contains("]"); + } + private void addRequestedBridges(String bridgesToAdd, List savedCustomBridges) { List bridgesListNew = new ArrayList<>(); String[] bridgesArrNew = bridgesToAdd.split("\n"); @@ -1143,9 +1190,9 @@ public String getBridgesFilePath() { return currentBridgesFilePath; } - private Future verifyNewDefaultBridgesExist(Context context, boolean useDefaultBridges) { + private Job verifyNewDefaultBridgesExist(Context context, boolean useDefaultBridges) { - return cachedExecutor.submit(() -> { + return executor.submit("PreferencesTorBridges verifyNewDefaultBridgesExist", () -> { File outputFile = new File(appDataDir + "/app_data/tor/bridges_default.lst"); long installedBridgesSize = outputFile.length(); @@ -1174,6 +1221,7 @@ private Future verifyNewDefaultBridgesExist(Context context, boolean useDefau } catch (Exception e) { loge("PreferencesTorBridges verifyNewDefaultBridgesExist", e); } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridgesViewModel.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridgesViewModel.kt index 8c39e8f41..cd3c85ff9 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridgesViewModel.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_bridges/PreferencesTorBridgesViewModel.kt @@ -20,33 +20,46 @@ package pan.alexander.tordnscrypt.settings.tor_bridges import android.graphics.Bitmap -import androidx.lifecycle.* -import kotlinx.coroutines.* +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancelChildren +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach -import pan.alexander.tordnscrypt.di.CoroutinesModule -import pan.alexander.tordnscrypt.domain.bridges.* -import pan.alexander.tordnscrypt.domain.dns_resolver.DnsInteractor +import kotlinx.coroutines.launch +import pan.alexander.tordnscrypt.domain.bridges.BridgeCountryData +import pan.alexander.tordnscrypt.domain.bridges.BridgePingData +import pan.alexander.tordnscrypt.domain.bridges.BridgePingResult +import pan.alexander.tordnscrypt.domain.bridges.BridgesCountriesInteractor +import pan.alexander.tordnscrypt.domain.bridges.DefaultVanillaBridgeInteractor +import pan.alexander.tordnscrypt.domain.bridges.ParseBridgesResult +import pan.alexander.tordnscrypt.domain.bridges.PingCheckComplete +import pan.alexander.tordnscrypt.domain.bridges.RequestBridgesInteractor import pan.alexander.tordnscrypt.utils.enums.BridgeType import pan.alexander.tordnscrypt.utils.logger.Logger.loge import pan.alexander.tordnscrypt.utils.logger.Logger.logw import java.util.concurrent.ConcurrentHashMap -import java.util.regex.Pattern import javax.inject.Inject -import javax.inject.Named - -private const val DNS_RESOLVE_TIMEOUT_SEC = 3 +import kotlin.collections.ArrayList +import kotlin.collections.List +import kotlin.collections.first +import kotlin.collections.firstOrNull +import kotlin.collections.map +import kotlin.collections.mutableListOf @ExperimentalCoroutinesApi class PreferencesTorBridgesViewModel @Inject constructor( private val defaultVanillaBridgeInteractor: DefaultVanillaBridgeInteractor, private val requestBridgesInteractor: RequestBridgesInteractor, private val bridgesCountriesInteractor: BridgesCountriesInteractor, - private val dnsInteractor: DnsInteractor, - @Named(CoroutinesModule.DISPATCHER_IO) - private val dispatcherIo: CoroutineDispatcher + private val bridgePingHelper: BridgePingHelper ) : ViewModel() { private val timeouts = mutableListOf() @@ -74,11 +87,7 @@ class PreferencesTorBridgesViewModel @Inject constructor( private val errorsMutableLiveData = MutableLiveData() val errorsLiveData: LiveData get() = errorsMutableLiveData - private val webTunnelBridgePattern by lazy { - Pattern.compile("^webtunnel +(.+:\\d+)(?: +\\w+)? +url=(http(s)?://[\\w.-]+)(?:/[\\w.-]+)*/?") - } - - private val webTunnelBridgesMatcherMap by lazy { ConcurrentHashMap() } + private val bridgesMatcherMap by lazy { ConcurrentHashMap() } fun measureTimeouts(bridges: List) { @@ -92,68 +101,72 @@ class PreferencesTorBridgesViewModel @Inject constructor( initBridgeCheckerObserver() } - webTunnelBridgesMatcherMap.clear() + bridgesMatcherMap.clear() timeoutsMeasurementJob = viewModelScope.launch { - if (bridges.firstOrNull()?.obfsType == BridgeType.webtunnel) { - val bridgesToMeasure = getRealIPFromWebTunnelBridges(ArrayList(bridges)) - launch { - defaultVanillaBridgeInteractor.measureTimeouts(ArrayList(bridgesToMeasure)) - } - searchBridgeCountries(ArrayList(bridgesToMeasure).map { - ObfsBridge( - it, - BridgeType.vanilla, - false - ) - }) - } else { - defaultVanillaBridgeInteractor.measureTimeouts(bridges.map { it.bridge }) + when (bridges.firstOrNull()?.obfsType) { + BridgeType.webtunnel -> handleWebTunnelBridgesTimeout(bridges) + BridgeType.meek_lite -> handleMeekLiteBridgesTimeout(bridges) + BridgeType.snowflake -> handleSnowFlakeBridgesTimeout(bridges) + else -> handleOtherBridgesTimeout(bridges) } } } - private suspend fun getRealIPFromWebTunnelBridges(bridges: List) = try { - withContext(dispatcherIo) { - val bridgesToMeasure = mutableListOf() - for (bridge in bridges) { - - val matcher = webTunnelBridgePattern.matcher(bridge.bridge) - if (matcher.find()) { - val ipWithPort = matcher.group(1) ?: continue - val domain = matcher.group(2) ?: continue - val port = if (domain.startsWith("https")) { - 443 - } else { - 80 - } + private suspend fun handleWebTunnelBridgesTimeout(bridges: List) = coroutineScope { + val bridgesToMeasure = bridgePingHelper.getRealIPFromWebTunnelBridges( + ArrayList(bridges), + bridgesMatcherMap + ) + launch { + defaultVanillaBridgeInteractor.measureTimeouts(ArrayList(bridgesToMeasure)) + } + searchBridgeCountries(ArrayList(bridgesToMeasure).map { + ObfsBridge( + it, + BridgeType.vanilla, + false + ) + }) + } - val ips = try { - dnsInteractor.resolveDomain(domain, true, DNS_RESOLVE_TIMEOUT_SEC).toList() - } catch (ignored: Exception) { - emptyList() - } - ensureActive() - if (ips.isEmpty()) { - continue - } - val ipsSorted = ips.sortedBy { it.isIPv6Address() } - val address = if (ipsSorted.first().isIPv6Address()) { - "[${ipsSorted.first()}]:$port" - } else { - "${ipsSorted.first()}:$port" - } - val bridgeLine = bridge.bridge.replace(ipWithPort, address) - bridgesToMeasure.add(bridgeLine) - webTunnelBridgesMatcherMap[bridgeLine.hashCode()] = - bridge.bridge.hashCode() - } - } - bridgesToMeasure + private suspend fun handleMeekLiteBridgesTimeout(bridges: List) = coroutineScope { + val bridgesToMeasure = bridgePingHelper.getRealIPFromMeekLiteBridges( + ArrayList(bridges), + bridgesMatcherMap + ) + launch { + defaultVanillaBridgeInteractor.measureTimeouts(ArrayList(bridgesToMeasure)) } - } catch (ignored: Exception) { - emptyList() + searchBridgeCountries(ArrayList(bridgesToMeasure).map { + ObfsBridge( + it, + BridgeType.vanilla, + false + ) + }) + } + + private suspend fun handleSnowFlakeBridgesTimeout(bridges: List) = coroutineScope { + val bridgesToMeasure = bridgePingHelper.getRealIPFromSnowFlakeBridges( + ArrayList(bridges), + bridgesMatcherMap + ) + launch { + defaultVanillaBridgeInteractor.measureTimeouts(ArrayList(bridgesToMeasure)) + } + searchBridgeCountries(ArrayList(bridgesToMeasure).map { + ObfsBridge( + it, + BridgeType.vanilla, + false + ) + }) + } + + private suspend fun handleOtherBridgesTimeout(bridges: List) { + defaultVanillaBridgeInteractor.measureTimeouts(bridges.map { it.bridge }) } fun cancelMeasuringTimeouts() { @@ -170,8 +183,8 @@ class PreferencesTorBridgesViewModel @Inject constructor( is PingCheckComplete -> true } }.map { - if (it is BridgePingData && webTunnelBridgesMatcherMap.containsKey(it.bridgeHash)) { - BridgePingData(webTunnelBridgesMatcherMap[it.bridgeHash] ?: 0, it.ping) + if (it is BridgePingData && bridgesMatcherMap.containsKey(it.bridgeHash)) { + BridgePingData(bridgesMatcherMap[it.bridgeHash] ?: 0, it.ping) } else { it } @@ -301,7 +314,10 @@ class PreferencesTorBridgesViewModel @Inject constructor( return } - if (bridges.first().obfsType == BridgeType.webtunnel) { + if (bridges.first().obfsType == BridgeType.webtunnel + || bridges.first().obfsType == BridgeType.meek_lite + || bridges.first().obfsType == BridgeType.snowflake + ) { return } @@ -320,9 +336,9 @@ class PreferencesTorBridgesViewModel @Inject constructor( bridgeCountriesObserveJob = viewModelScope.launch { bridgesCountriesInteractor.observeBridgeCountries() .map { - if (webTunnelBridgesMatcherMap.containsKey(it.bridgeHash)) { + if (bridgesMatcherMap.containsKey(it.bridgeHash)) { BridgeCountryData( - webTunnelBridgesMatcherMap[it.bridgeHash] ?: 0, + bridgesMatcherMap[it.bridgeHash] ?: 0, it.country ) } else { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_ips/UnlockTorIpsFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_ips/UnlockTorIpsFragment.java index bfb0efad4..0c01b0420 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_ips/UnlockTorIpsFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_ips/UnlockTorIpsFragment.java @@ -44,7 +44,6 @@ import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.dialogs.NotificationHelper; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import pan.alexander.tordnscrypt.modules.ModulesStatus; @@ -74,7 +73,7 @@ public class UnlockTorIpsFragment extends Fragment { @Inject public Lazy coroutineExecutor; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject ViewModelProvider.Factory viewModelFactory; @Inject @Named(DEFAULT_PREFERENCES_NAME) @@ -130,7 +129,7 @@ public void onCreate(Bundle savedInstanceState) { routeAllThroughTorTether ); - cachedExecutor.submit(() -> { + executor.submit("UnlockTorIpsFragment verifier", () -> { try { Verifier verifier = verifierLazy.get(); String appSign = verifier.getAppSignature(); @@ -151,6 +150,7 @@ public void onCreate(Bundle savedInstanceState) { } loge("UnlockTorIpsFrag fault", e, true); } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_preferences/PreferencesTorFragment.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_preferences/PreferencesTorFragment.java index 012515de4..ba5d0ec71 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_preferences/PreferencesTorFragment.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/settings/tor_preferences/PreferencesTorFragment.java @@ -32,7 +32,6 @@ import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.PreferenceManager; import java.util.ArrayList; import java.util.LinkedList; @@ -53,7 +52,7 @@ import pan.alexander.tordnscrypt.settings.PathVars; import pan.alexander.tordnscrypt.settings.tor_bridges.SnowflakeConfigurator; import pan.alexander.tordnscrypt.settings.tor_countries.CountrySelectFragment; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; @@ -70,7 +69,9 @@ import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.SNOWFLAKE_RENDEZVOUS; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.STUN_SERVERS; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_DNS_PORT; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_ENTRY_NODES; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_FASCIST_FIREWALL; +import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_FASCIST_FIREWALL_LOCK; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_HTTP_TUNNEL_PORT; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_OUTBOUND_PROXY; import static pan.alexander.tordnscrypt.utils.preferences.PreferenceKeys.TOR_OUTBOUND_PROXY_ADDRESS; @@ -110,7 +111,7 @@ public class PreferencesTorFragment extends PreferenceFragmentCompat implements @Inject public Lazy pathVars; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy snowflakeConfigurator; @@ -178,10 +179,10 @@ public void onCreate(Bundle savedInstanceState) { } - Preference entryNodesPref = findPreference("EntryNodes"); + Preference entryNodesPref = findPreference(TOR_ENTRY_NODES); boolean useDefaultBridges = preferenceRepository.get().getBoolPreference(USE_DEFAULT_BRIDGES); boolean useOwnBridges = preferenceRepository.get().getBoolPreference(USE_OWN_BRIDGES); - boolean entryNodesActive = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("EntryNodes", false); + boolean entryNodesActive = defaultPreferences.get().getBoolean(TOR_ENTRY_NODES, false); if (entryNodesPref != null) { if (useDefaultBridges || useOwnBridges) { if (entryNodesActive) { @@ -195,6 +196,13 @@ public void onCreate(Bundle savedInstanceState) { } } + Preference fascistFirewall = findPreference(TOR_FASCIST_FIREWALL); + boolean fascistFirewallLock = preferenceRepository.get().getBoolPreference(TOR_FASCIST_FIREWALL_LOCK); + if (fascistFirewall != null && fascistFirewallLock) { + fascistFirewall.setSummary(R.string.pref_tor_fascist_firewall_lock_summ); + fascistFirewall.setEnabled(false); + } + Preference editTorConfDirectly = findPreference("editTorConfDirectly"); if (editTorConfDirectly != null) { editTorConfDirectly.setOnPreferenceClickListener(this); @@ -352,17 +360,17 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu key_tor.set(key_tor.indexOf("ExcludeNodes"), "#ExcludeNodes"); } return true; - } else if (Objects.equals(preference.getKey(), "EntryNodes")) { + } else if (Objects.equals(preference.getKey(), TOR_ENTRY_NODES)) { if (Boolean.parseBoolean(newValue.toString()) && key_tor.contains("#EntryNodes")) { key_tor.set(key_tor.indexOf("#EntryNodes"), "EntryNodes"); - openCountrySelectFragment(CountrySelectFragment.entryNodes, "EntryNodes"); + openCountrySelectFragment(CountrySelectFragment.entryNodes, TOR_ENTRY_NODES); } else if (key_tor.contains("EntryNodes")) { key_tor.set(key_tor.indexOf("EntryNodes"), "#EntryNodes"); } return true; } else if (Objects.equals(preference.getKey(), "HardwareAccel")) { if (Boolean.parseBoolean(newValue.toString()) - && !key_tor.contains("HardwareAccel") && key_tor.contains("Schedulers") ) { + && !key_tor.contains("HardwareAccel") && key_tor.contains("Schedulers")) { key_tor.add(key_tor.indexOf("Schedulers"), "HardwareAccel"); val_tor.add(key_tor.indexOf("HardwareAccel"), newValue.toString()); } @@ -452,7 +460,10 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu ModifyForwardingRules modifyForwardingRules = new ModifyForwardingRules(context, "onion 127.0.0.1:" + dnsPort.trim()); - cachedExecutor.submit(modifyForwardingRules.getRunnable()); + executor.submit("PreferencesTorFragment modifyForwardingRules", () -> { + modifyForwardingRules.getRunnable().run(); + return null; + }); return true; } else if (Objects.equals(preference.getKey(), SNOWFLAKE_RENDEZVOUS)) { for (int i = 0; i < key_tor.size(); i++) { @@ -484,7 +495,7 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu } String[] servers = serversStr.split(", ?"); - for (String server: servers) { + for (String server : servers) { if (!server.matches(HOST_NAME_REGEX + ":\\d+")) { return false; } @@ -543,18 +554,12 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu String key = key_tor.get(i); String val = val_tor.get(i); - String proxyType = ""; - switch (key) { - case "SOCKSPort": - proxyType = "SOCKSPort"; - break; - case "HTTPTunnelPort": - proxyType = "HTTPTunnelPort"; - break; - case "TransPort": - proxyType = "TransPort"; - break; - } + String proxyType = switch (key) { + case "SOCKSPort" -> "SOCKSPort"; + case "HTTPTunnelPort" -> "HTTPTunnelPort"; + case "TransPort" -> "TransPort"; + default -> ""; + }; if (proxyType.isEmpty()) { continue; @@ -595,18 +600,12 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu String key = key_tor.get(i); String val = val_tor.get(i); - String proxyType = ""; - switch (key) { - case "SOCKSPort": - proxyType = "SOCKSPort"; - break; - case "HTTPTunnelPort": - proxyType = "HTTPTunnelPort"; - break; - case "TransPort": - proxyType = "TransPort"; - break; - } + String proxyType = switch (key) { + case "SOCKSPort" -> "SOCKSPort"; + case "HTTPTunnelPort" -> "HTTPTunnelPort"; + case "TransPort" -> "TransPort"; + default -> ""; + }; if (proxyType.isEmpty()) { continue; @@ -697,8 +696,17 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu } else if (Objects.equals(preference.getKey(), "Socks5Proxy") && !newValue.toString().matches(IPv4_REGEX_WITH_PORT)) { return false; + } else if (Objects.equals(preference.getKey(), "ClientUseIPv4") && !Boolean.parseBoolean(newValue.toString())) { + if (!defaultPreferences.get().getBoolean(TOR_USE_IPV6, true)) { + return false; + } } else if (Objects.equals(preference.getKey(), TOR_USE_IPV6)) { + if (!defaultPreferences.get().getBoolean("ClientUseIPv4", true) + && !Boolean.parseBoolean(newValue.toString())) { + return false; + } + boolean useIPv6 = Boolean.parseBoolean(newValue.toString()); for (int i = 0; i < key_tor.size(); i++) { @@ -712,7 +720,7 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu allowTorTethering, isolateDestAddress, isolateDestPort)); - if (i < key_tor.size() -1 && !key_tor.get(i + 1).equals("SOCKSPort")) { + if (i < key_tor.size() - 1 && !key_tor.get(i + 1).equals("SOCKSPort")) { key_tor.add(i + 1, "SOCKSPort"); proxyLine = "[" + LOOPBACK_ADDRESS_IPv6 + "]:" + pathVars.get().getTorSOCKSPort(); val_tor.add(i + 1, addIsolateFlags( @@ -722,11 +730,11 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu isolateDestPort)); } } else if (!useIPv6 && key.equals("SOCKSPort") && val.contains(LOOPBACK_ADDRESS_IPv6)) { - key_tor.set(i, ""); - val_tor.set(i, ""); + key_tor.set(i, ""); + val_tor.set(i, ""); } else if (useIPv6 && key.equals("DNSPort") && !val.contains(LOOPBACK_ADDRESS_IPv6)) { val_tor.set(i, LOOPBACK_ADDRESS + ":" + pathVars.get().getTorDNSPort()); - if (i < key_tor.size() -1 && !key_tor.get(i + 1).equals("DNSPort")) { + if (i < key_tor.size() - 1 && !key_tor.get(i + 1).equals("DNSPort")) { key_tor.add(i + 1, "DNSPort"); val_tor.add( i + 1, @@ -757,6 +765,31 @@ public boolean onPreferenceChange(@NonNull Preference preference, Object newValu key_tor.set(index, ""); val_tor.set(index, ""); } + } else if (Objects.equals(preference.getKey(), TOR_FASCIST_FIREWALL)) { + if (Boolean.parseBoolean(newValue.toString())) { + int indexReachableAddresses = key_tor.indexOf("#ReachableAddresses"); + if (indexReachableAddresses >= 0) { + key_tor.set(indexReachableAddresses, "ReachableAddresses"); + } else if (!key_tor.contains("ReachableAddresses")) { + int indexFascistFirewall = key_tor.indexOf("FascistFirewall"); + if (indexFascistFirewall >= 0) { + key_tor.set(indexFascistFirewall, "ReachableAddresses"); + val_tor.set(indexFascistFirewall, "*:80,*:443"); + } + } + } else { + int indexReachableAddresses = key_tor.indexOf("ReachableAddresses"); + if (indexReachableAddresses >= 0) { + key_tor.set(indexReachableAddresses, "#ReachableAddresses"); + } else if (!key_tor.contains("#ReachableAddresses")) { + int indexFascistFirewall = key_tor.indexOf("FascistFirewall"); + if (indexFascistFirewall >= 0) { + key_tor.set(indexFascistFirewall, "#ReachableAddresses"); + val_tor.set(indexFascistFirewall, "*:80,*:443"); + } + } + } + return true; } if (key_tor.contains(preference.getKey().trim())) { @@ -817,10 +850,10 @@ public boolean onPreferenceClick(@NonNull Preference preference) { return true; } - cachedExecutor.submit(() -> { + executor.submit("PreferencesTorFragment cleanTorFolder", () -> { Activity activity = getActivity(); if (activity == null) { - return; + return null; } boolean successfully = FileManager.deleteDirSynchronous(activity, appDataDir + "/tor_data"); @@ -830,6 +863,7 @@ public boolean onPreferenceClick(@NonNull Preference preference) { } else { activity.runOnUiThread(() -> Toast.makeText(activity, R.string.wrong, Toast.LENGTH_SHORT).show()); } + return null; }); @@ -842,13 +876,50 @@ public boolean onPreferenceClick(@NonNull Preference preference) { } private void changePreferencesForGPVersion() { - PreferenceCategory torSettingsCategory = findPreference("tor_settings"); + removePreferencesFromTorSettingsCategory(); + + removeDependenciesFromTorProxySettingsCategory(); + + removePreferencesFromTorProxySettingsCategory(); + + removePreferencesFromTorSnowflakeCategory(); - if (torSettingsCategory != null) { + removePreferencesFromTorOtherCategory(); + } + + private void removePreferencesFromTorSettingsCategory() { + PreferenceCategory category = findPreference("tor_settings"); + if (category != null) { ArrayList preferences = new ArrayList<>(); preferences.add(findPreference("AvoidDiskWrites")); preferences.add(findPreference("ConnectionPadding")); preferences.add(findPreference("ReducedConnectionPadding")); + + for (Preference preference : preferences) { + if (preference != null) { + category.removePreference(preference); + } + } + } + } + + private void removeDependenciesFromTorProxySettingsCategory() { + ArrayList preferences = new ArrayList<>(); + preferences.add(findPreference("SOCKSPort")); + preferences.add(findPreference("HTTPTunnelPort")); + preferences.add(findPreference("TransPort")); + preferences.add(findPreference("DNSPort")); + for (Preference preference : preferences) { + if (preference != null) { + preference.setDependency(null); + } + } + } + + private void removePreferencesFromTorProxySettingsCategory() { + PreferenceCategory category = findPreference("tor_proxy_settings"); + if (category != null) { + ArrayList preferences = new ArrayList<>(); preferences.add(findPreference("Enable SOCKS proxy")); preferences.add(findPreference("Enable HTTPTunnel")); preferences.add(findPreference("Enable Transparent proxy")); @@ -856,11 +927,21 @@ private void changePreferencesForGPVersion() { for (Preference preference : preferences) { if (preference != null) { - torSettingsCategory.removePreference(preference); + category.removePreference(preference); } } } + } + + private void removePreferencesFromTorSnowflakeCategory() { + PreferenceCategory category = findPreference("pref_tor_snowflake_categ"); + Preference preference = findPreference("pref_tor_snowflake_stun"); + if (category != null && preference != null) { + category.removePreference(preference); + } + } + private void removePreferencesFromTorOtherCategory() { PreferenceCategory otherCategory = findPreference("pref_tor_other"); Preference editTorConfDirectly = findPreference("editTorConfDirectly"); if (otherCategory != null && editTorConfDirectly != null) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ChangeTorIpTileManager.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ChangeTorIpTileManager.kt index a0f8cda56..ae881ef16 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ChangeTorIpTileManager.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ChangeTorIpTileManager.kt @@ -23,6 +23,7 @@ import android.content.Context import android.os.Build import android.service.quicksettings.Tile import android.widget.Toast +import androidx.annotation.Keep import androidx.annotation.RequiresApi import kotlinx.coroutines.* import pan.alexander.tordnscrypt.R @@ -34,6 +35,7 @@ import pan.alexander.tordnscrypt.utils.enums.ModuleState import javax.inject.Inject import javax.inject.Named +@Keep @RequiresApi(Build.VERSION_CODES.N) class ChangeTorIpTileManager @Inject constructor( private val dispatcherMain: MainCoroutineDispatcher, diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ModulesControlTileManager.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ModulesControlTileManager.kt index 831e45183..4eb91f465 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ModulesControlTileManager.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tiles/ModulesControlTileManager.kt @@ -27,6 +27,7 @@ import android.os.Build import android.os.Handler import android.service.quicksettings.Tile import android.widget.Toast +import androidx.annotation.Keep import androidx.annotation.RequiresApi import androidx.annotation.StringRes import androidx.core.os.postDelayed @@ -54,6 +55,7 @@ import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper import javax.inject.Inject import javax.inject.Named +@Keep @RequiresApi(Build.VERSION_CODES.N) class ModulesControlTileManager @Inject constructor( private val dispatcherMain: MainCoroutineDispatcher, diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tor_fragment/TorFragmentPresenter.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tor_fragment/TorFragmentPresenter.java index e67004064..a78848dfc 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tor_fragment/TorFragmentPresenter.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/tor_fragment/TorFragmentPresenter.java @@ -50,7 +50,7 @@ import pan.alexander.tordnscrypt.modules.ModulesRunner; import pan.alexander.tordnscrypt.modules.ModulesStatus; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import pan.alexander.tordnscrypt.utils.enums.ModuleState; import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper; @@ -81,7 +81,7 @@ public class TorFragmentPresenter implements TorFragmentPresenterInterface, @Inject public Lazy torInteractor; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; @Inject public Lazy verifierLazy; @Inject @@ -568,15 +568,15 @@ public void startButtonOnClick() { return; } - cachedExecutor.submit(() -> { + executor.submit("TorFragmentPresenter verifier", () -> { if (!isActive() || activity == null) { - return; + return null; } FragmentManager fragmentManager = view.getFragmentFragmentManager(); if (fragmentManager == null) { - return; + return null; } try { @@ -599,6 +599,7 @@ public void startButtonOnClick() { } loge("TorRunFragment fault", e, true); } + return null; }); if (modulesStatus.getTorState() != RUNNING) { diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java index b907fa692..650f6763d 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/update/UpdateCheck.java @@ -40,19 +40,19 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.CancellationException; -import java.util.concurrent.Future; import javax.crypto.Cipher; import javax.inject.Inject; import dagger.Lazy; +import kotlinx.coroutines.Job; import pan.alexander.tordnscrypt.App; import pan.alexander.tordnscrypt.BuildConfig; import pan.alexander.tordnscrypt.R; import pan.alexander.tordnscrypt.TopFragment; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.utils.integrity.Verifier; import pan.alexander.tordnscrypt.utils.web.HttpsConnectionManager; @@ -69,7 +69,7 @@ public class UpdateCheck { @Inject public Lazy verifier; @Inject - public Lazy cachedExecutor; + public Lazy executor; @Inject public Lazy pathVars; @@ -241,12 +241,12 @@ private String convertKeyForPHP(byte[] key) { return Base64.encodeToString(key, Base64.DEFAULT); } - public synchronized Future requestUpdateData(final String domainName) { + public synchronized Job requestUpdateData(final String domainName) { if (pathVars.get().getAppVersion().endsWith("p") || pathVars.get().getAppVersion().startsWith("f")) { return null; } - return cachedExecutor.get().submit(() -> { + return executor.get().submit("UpdateCheck requestUpdateData", () -> { String serverAnswerEncoded = ""; String serverAnswer = ""; @@ -256,7 +256,7 @@ public synchronized Future requestUpdateData(final String domainName) { if (rsaSign == null) { showUpdateMessageAndSaveResult(R.string.update_fault); loge("RSASign(appSign) returns null"); - return; + return null; } String registrationCode = preferenceRepository.get().getStringPreference("registrationCode"); @@ -286,16 +286,16 @@ public synchronized Future requestUpdateData(final String domainName) { preferenceRepository.get().setStringPreference("updateTimeLast", ""); wrongRegistrationCode = true; loge("requestUpdateData function fault - server returns wrong code"); - return; + return null; } else if (serverAnswerEncoded.contains("over 3 activations")) { showUpdateMessageAndSaveResult(R.string.update_over_three_activations, R.string.update_fault); wrongRegistrationCode = true; loge("requestUpdateData function fault - server returns over 3 activations"); - return; + return null; } else if (serverAnswerEncoded.contains("over 5 times")) { showUpdateMessageAndSaveResult(R.string.update_over_five_times, R.string.update_fault); loge("requestUpdateData function fault - server returns over 5 times"); - return; + return null; } else { throw new IllegalStateException("requestUpdateData function fault - server returns fault"); } @@ -316,6 +316,7 @@ public synchronized Future requestUpdateData(final String domainName) { + "; serverAnswerEncoded " + serverAnswerEncoded + "; serverAnswer " + serverAnswer); } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/apps/InstalledApplicationsManager.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/apps/InstalledApplicationsManager.kt index 6f300e91a..9378b20be 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/apps/InstalledApplicationsManager.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/apps/InstalledApplicationsManager.kt @@ -136,10 +136,20 @@ class InstalledApplicationsManager private constructor( application = userAppsMap[applicationInfo.uid] //val name = packageManager.getApplicationLabel(applicationInfo)?.toString() ?: "Undefined" - val name = applicationInfo.loadLabel(packageManager)?.toString() ?: "Undefined" + val name = try { + applicationInfo.loadLabel(packageManager)?.toString() ?: applicationInfo.packageName + } catch (e: Exception) { + logw("InstalledApplications get name", e) + applicationInfo.packageName + } val icon = if (iconIsRequired) { //packageManager.getApplicationIcon(applicationInfo) - applicationInfo.loadIcon(packageManager) + try { + applicationInfo.loadIcon(packageManager) + } catch (e: Exception) { + logw("InstalledApplications get icon", e) + null + } } else { null } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/connectionchecker/SocketInternetChecker.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/connectionchecker/SocketInternetChecker.kt index a1bc2fea3..0f06c9601 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/connectionchecker/SocketInternetChecker.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/connectionchecker/SocketInternetChecker.kt @@ -33,7 +33,9 @@ class SocketInternetChecker @Inject constructor() { ip: String, port: Int, proxyAddress: String, - proxyPort: Int + proxyPort: Int, + connectTimeout: Int = CONNECT_TIMEOUT_SEC, + reachableTimeout: Int = CHECK_ADDRESS_REACHABLE_TIMEOUT_SEC ): Boolean { var socket: Socket? = null @@ -53,11 +55,11 @@ class SocketInternetChecker @Inject constructor() { val sockAddress: SocketAddress = InetSocketAddress(InetAddress.getByName(ip), port) - socket.connect(sockAddress, CONNECT_TIMEOUT_SEC * 1000) + socket.connect(sockAddress, connectTimeout * 1000) socket.soTimeout = 100 return if (isProxyUsed(proxyAddress, proxyPort)) { - socket.inetAddress.isReachable(CHECK_ADDRESS_REACHABLE_TIMEOUT_SEC * 1000) + socket.inetAddress.isReachable(reachableTimeout * 1000) } else { socket.isConnected } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CachedExecutor.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CachedExecutor.kt index f8b8ec80c..007ad9cfc 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CachedExecutor.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CachedExecutor.kt @@ -34,7 +34,6 @@ class CachedExecutor @Inject constructor() { private val executorService: ExecutorService by lazy { Executors.newCachedThreadPool() } - @Synchronized fun submit(block: Runnable): Future<*>? = try { executorService.submit(block) diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CoroutineExecutor.kt b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CoroutineExecutor.kt index 2ec6e41b1..86d9c7d9e 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CoroutineExecutor.kt +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/executors/CoroutineExecutor.kt @@ -25,10 +25,21 @@ import javax.inject.Inject import javax.inject.Named class CoroutineExecutor @Inject constructor( - @Named(CoroutinesModule.SUPERVISOR_JOB_IO_DISPATCHER_SCOPE) + @Named(CoroutinesModule.SUPERVISOR_JOB_IO_DISPATCHER_SCOPE_SINGLETON) val baseCoroutineScope: CoroutineScope, val coroutineExceptionHandler: CoroutineExceptionHandler ) { + inline fun submit( + name: String, + crossinline block: () -> Unit + ): Job { + val scope = baseCoroutineScope + CoroutineName(name) + coroutineExceptionHandler + return scope.launch { + runInterruptible(coroutineContext) { + block() + } + } + } @JvmOverloads inline fun execute( @@ -37,13 +48,16 @@ class CoroutineExecutor @Inject constructor( crossinline block: () -> T ): Job { val scope = baseCoroutineScope + CoroutineName(name) + coroutineExceptionHandler - return scope.launch { if (maxExecutingTimeMinutes == 0) { - block() + runInterruptible(coroutineContext) { + block() + } } else { withTimeoutOrNull(maxExecutingTimeMinutes * 60 * 1000L) { - block() + runInterruptible(coroutineContext) { + block() + } } } } @@ -64,10 +78,14 @@ class CoroutineExecutor @Inject constructor( while ((times == 0 || timesCount < times) && isActive) { delay(delaySec * 1000L) if (maxExecutingTimeMinutes == 0) { - block() + runInterruptible(coroutineContext) { + block() + } } else { withTimeoutOrNull(maxExecutingTimeMinutes * 60 * 1000L) { - block() + runInterruptible(coroutineContext) { + block() + } } } timesCount++ diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/parsers/DnsCryptConfigurationParser.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/parsers/DnsCryptConfigurationParser.java index 633f8dc60..43f722081 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/parsers/DnsCryptConfigurationParser.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/parsers/DnsCryptConfigurationParser.java @@ -38,6 +38,7 @@ import dagger.Lazy; import pan.alexander.tordnscrypt.settings.PathVars; +import pan.alexander.tordnscrypt.settings.dnscrypt_relays.DnsRelay; import pan.alexander.tordnscrypt.settings.dnscrypt_relays.DnsServerRelay; import pan.alexander.tordnscrypt.settings.dnscrypt_servers.DnsCryptResolver; import pan.alexander.tordnscrypt.utils.filemanager.FileManager; @@ -226,6 +227,103 @@ public Set parseDnsCryptResolversMd(List publicResolve return resolvers; } + @WorkerThread + public List getOdohServersMd() { + List servers = new ArrayList<>(); + try { + List lines = FileManager.readTextFileSynchronous( + context, + pathVars.get().getOdohServersPath() + ); + for (String line : lines) { + if (!line.isBlank()) { + servers.add(line); + } + if (Thread.currentThread().isInterrupted()) { + break; + } + } + } catch (Exception e) { + loge("DnsCryptServersParser getOdohServersMd", e); + } + return servers; + } + + @WorkerThread + public List getDnsCryptRelaysMd() { + List servers = new ArrayList<>(); + try { + List lines = FileManager.readTextFileSynchronous( + context, + pathVars.get().getDNSCryptRelaysPath() + ); + for (String line : lines) { + if (!line.isBlank()) { + servers.add(line); + } + if (Thread.currentThread().isInterrupted()) { + break; + } + } + } catch (Exception e) { + loge("DnsCryptServersParser getDnsCryptRelaysMd", e); + } + return servers; + } + + @WorkerThread + public List getOdohRelaysMd() { + List servers = new ArrayList<>(); + try { + List lines = FileManager.readTextFileSynchronous( + context, + pathVars.get().getOdohRelaysPath() + ); + for (String line : lines) { + if (!line.isBlank()) { + servers.add(line); + } + if (Thread.currentThread().isInterrupted()) { + break; + } + } + } catch (Exception e) { + loge("DnsCryptServersParser getOdohRelaysMd", e); + } + return servers; + } + + public Set parseDnsCryptRelaysMd(List relaysMd) { + Set relays = new LinkedHashSet<>(); + try { + String name = ""; + String description = ""; + boolean lockRelay = false; + + for (String line : relaysMd) { + + if (line.startsWith("##")) { + name = line.replace("##", "").trim(); + lockRelay = true; + } else if (lockRelay && line.startsWith("sdns://")) { + lockRelay = false; + } else if (lockRelay) { + description = line.replaceAll("\\s", " ").trim(); + } + + if (!name.isEmpty() && !description.isEmpty() && !lockRelay) { + DnsRelay dnsRelayItem = new DnsRelay(name, description); + relays.add(dnsRelayItem); + name = ""; + description = ""; + } + } + } catch (Exception e) { + loge("DnsCryptServersParser parseDnsCryptRelaysMd", e); + } + return relays; + } + @WorkerThread public void saveOwnResolversMd(List lines) { FileManager.writeToTextFile( diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/preferences/PreferenceKeys.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/preferences/PreferenceKeys.java index 588d50f92..d1fe245e2 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/preferences/PreferenceKeys.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/preferences/PreferenceKeys.java @@ -152,11 +152,16 @@ public interface PreferenceKeys { String STUN_SERVERS = "pref_tor_snowflake_stun"; String TOR_USE_IPV6 = "ClientUseIPv6"; String TOR_FASCIST_FIREWALL = "FascistFirewall"; + String TOR_FASCIST_FIREWALL_LOCK = "FascistFirewallLock"; + + String TOR_ENTRY_NODES = "EntryNodes"; //I2PD Settings + String I2PD_USE_IPV6 = "ipv6"; String I2PD_OUTBOUND_PROXY = "Enable ntcpproxy"; //Firewall Settings + String FIREWALL_NO_BLOCK_NEW_APP = "NewAppsInternetAllowed"; String FIREWALL_SHOWS_ALL_APPS = "FirewallShowsAllApps"; //Logs diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/web/TorRefreshIPsWork.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/web/TorRefreshIPsWork.java index 4eb1cdfdb..8a3292cec 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/web/TorRefreshIPsWork.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/utils/web/TorRefreshIPsWork.java @@ -37,7 +37,7 @@ import pan.alexander.tordnscrypt.domain.dns_resolver.DnsInteractor; import pan.alexander.tordnscrypt.domain.preferences.PreferenceRepository; import pan.alexander.tordnscrypt.modules.ModulesStatus; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import static pan.alexander.tordnscrypt.di.SharedPreferencesModule.DEFAULT_PREFERENCES_NAME; import static pan.alexander.tordnscrypt.utils.Constants.IPv4_REGEX; @@ -71,7 +71,7 @@ public class TorRefreshIPsWork { @Inject public Lazy handler; @Inject - public CachedExecutor cachedExecutor; + public CoroutineExecutor executor; private final Pattern ipv4Pattern = Pattern.compile(IPv4_REGEX); private final Pattern ipv6Pattern = Pattern.compile(IPv6_REGEX); @@ -88,7 +88,7 @@ public TorRefreshIPsWork(Context context, GetIPsJobService getIPsJobService) { } public void refreshIPs() { - cachedExecutor.submit(() -> { + executor.submit("TorRefreshIPsWork refreshIPs", () -> { logi("TorRefreshIPsWork refreshIPs"); @@ -97,7 +97,7 @@ public void refreshIPs() { } catch (Exception e) { loge("TorRefreshIPsWork performBackgroundWork", e, true); } - + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/VpnUtils.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/VpnUtils.java index eae81ef4b..e0bcf9210 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/VpnUtils.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/VpnUtils.java @@ -198,10 +198,11 @@ static boolean isEnabled(PackageInfo info, Context context) { public static void canFilterAsynchronous(ServiceVPN serviceVPN) { - App.getInstance().getDaggerComponent().getCachedExecutor().submit(() -> { + App.getInstance().getDaggerComponent() + .getCoroutineExecutor().submit("VpnUtils canFilterAsynchronous", () -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && serviceVPN != null) { serviceVPN.canFilter = true; - return; + return null; } // https://android-review.googlesource.com/#/c/206710/1/untrusted_app.te @@ -211,7 +212,7 @@ public static void canFilterAsynchronous(ServiceVPN serviceVPN) { try { if (tcp.exists() && tcp.canRead() && serviceVPN != null) serviceVPN.canFilter = true; - return; + return null; } catch (SecurityException ignored) { } @@ -224,6 +225,7 @@ public static void canFilterAsynchronous(ServiceVPN serviceVPN) { serviceVPN.canFilter = false; } } + return null; }); } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java index ae05b93d5..81402fd97 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPN.java @@ -63,9 +63,9 @@ import pan.alexander.tordnscrypt.modules.ModulesServiceNotificationManager; import pan.alexander.tordnscrypt.modules.UsageStatistics; import pan.alexander.tordnscrypt.settings.PathVars; -import pan.alexander.tordnscrypt.utils.executors.CachedExecutor; import pan.alexander.tordnscrypt.utils.Utils; import pan.alexander.tordnscrypt.utils.enums.VPNCommand; +import pan.alexander.tordnscrypt.utils.executors.CoroutineExecutor; import pan.alexander.tordnscrypt.vpn.Allowed; import pan.alexander.tordnscrypt.vpn.Packet; import pan.alexander.tordnscrypt.vpn.ResourceRecord; @@ -136,7 +136,7 @@ public class ServiceVPN extends VpnService implements OnInternetConnectionChecke @Inject public Lazy handler; @Inject - public Lazy cachedExecutor; + public Lazy executor; @Inject public Provider vpnPreferenceHolder; volatile VpnPreferenceHolder vpnPreferences; @@ -617,6 +617,7 @@ public void onCreate() { notificationManager, UsageStatistics.getStartTime() ); + notification.createNotificationChannel(); notification.sendNotification(title, message); } @@ -780,7 +781,7 @@ public void onDestroy() { final long localJniContext = service_jni_context; - cachedExecutor.get().submit(() -> { + executor.get().submit("ServiceVPN onDestroy", () -> { try { if (vpn != null) { @@ -806,7 +807,7 @@ public void onDestroy() { } catch (Throwable ex) { loge("VPN Destroy", ex, true); } - + return null; }); super.onDestroy(); @@ -876,7 +877,7 @@ public ConcurrentHashMap getDnsQueryRawRecords() { } public void clearDnsQueryRawRecords() { - cachedExecutor.get().submit(() -> { + executor.get().submit("ServiceVPN clearDnsQueryRawRecords", () -> { try { lock.writeLock().lockInterruptibly(); @@ -891,6 +892,7 @@ public void clearDnsQueryRawRecords() { lock.writeLock().unlock(); } } + return null; }); } @@ -947,6 +949,13 @@ public void onTaskRemoved(Intent rootIntent) { loge("VPN service task removed " + this.hashCode()); + boolean vpnEnabled = defaultPreferences.get().getBoolean(VPN_SERVICE_ENABLED, false); + if (vpnEnabled) { + Intent starterIntent = new Intent(this, BootCompleteReceiver.class); + starterIntent.setAction(ALWAYS_ON_VPN); + sendBroadcast(starterIntent); + } + super.onTaskRemoved(rootIntent); } } diff --git a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPNHandler.java b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPNHandler.java index db05ffd7e..aaa3e078c 100644 --- a/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPNHandler.java +++ b/tordnscrypt/src/main/java/pan/alexander/tordnscrypt/vpn/service/ServiceVPNHandler.java @@ -167,12 +167,15 @@ private void handleIntent(Intent intent) { if (VpnService.prepare(serviceVPN) == null) { logw("VPN Handler prepared connected=" + serviceVPN.isNetworkAvailable()); if (serviceVPN.isNetworkAvailable() && !(ex instanceof StartFailedException)) { - Toast.makeText(serviceVPN, serviceVPN.getText(R.string.vpn_mode_error), Toast.LENGTH_SHORT).show(); + serviceVPN.handler.get().post(() -> { + Toast.makeText(serviceVPN, serviceVPN.getText(R.string.vpn_mode_error), Toast.LENGTH_SHORT).show(); + }); } // Retried on connectivity change } else { - Toast.makeText(serviceVPN, serviceVPN.getText(R.string.vpn_mode_error), Toast.LENGTH_SHORT).show(); - + serviceVPN.handler.get().post(() -> { + Toast.makeText(serviceVPN, serviceVPN.getText(R.string.vpn_mode_error), Toast.LENGTH_SHORT).show(); + }); // Disable firewall if (!(ex instanceof StartFailedException)) { prefs.edit().putBoolean(VPN_SERVICE_ENABLED, false).apply(); diff --git a/tordnscrypt/src/main/jni/invizible/udp.c b/tordnscrypt/src/main/jni/invizible/udp.c index d083b9b23..4c9ae8329 100644 --- a/tordnscrypt/src/main/jni/invizible/udp.c +++ b/tordnscrypt/src/main/jni/invizible/udp.c @@ -367,8 +367,7 @@ jboolean handle_udp(const struct arguments *args, cur->udp.time = time(NULL); - //handle onion websites - if (ntohs(udphdr->dest) == 53 && tor_dns_port > 0) { + if (ntohs(udphdr->dest) == 53) { struct dns_header *dns = (struct dns_header *) data; int qcount = ntohs(dns->q_count); if (dns->qr == 0 && dns->opcode == 0 && qcount > 0) { @@ -397,9 +396,16 @@ jboolean handle_udp(const struct arguments *args, } } - char *suffix = strrchr(qname, '.'); - if (redirect != NULL && suffix != NULL && strcmp(suffix, ".onion") == 0) { - redirect->rport = tor_dns_port; + //handle onion websites + if (tor_dns_port > 0) { + char *suffix = strrchr(qname, '.'); + if (redirect != NULL && suffix != NULL && strcmp(suffix, ".onion") == 0) { + redirect->rport = tor_dns_port; + } + } + //https://datatracker.ietf.org/doc/html/rfc7050 + if (redirect != NULL && strcmp(qname, "ipv4only.arpa") == 0) { + redirect = NULL; } } } diff --git a/tordnscrypt/src/main/res/layout/agreement_layout.xml b/tordnscrypt/src/main/res/layout/agreement_layout.xml index 79656d6de..5e797713f 100644 --- a/tordnscrypt/src/main/res/layout/agreement_layout.xml +++ b/tordnscrypt/src/main/res/layout/agreement_layout.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:orientation="vertical"> - + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_weight="1"> + + + + + + + + + + + + + diff --git a/tordnscrypt/src/main/res/layout/fragment_preferences_dnscrypt_relays.xml b/tordnscrypt/src/main/res/layout/fragment_preferences_dnscrypt_relays.xml index e074069d6..e5b0ac056 100644 --- a/tordnscrypt/src/main/res/layout/fragment_preferences_dnscrypt_relays.xml +++ b/tordnscrypt/src/main/res/layout/fragment_preferences_dnscrypt_relays.xml @@ -1,13 +1,24 @@ + + - \ No newline at end of file + diff --git a/tordnscrypt/src/main/res/layout/item_dns_relay.xml b/tordnscrypt/src/main/res/layout/item_dns_relay.xml index 7a868e6d2..d35f35b76 100644 --- a/tordnscrypt/src/main/res/layout/item_dns_relay.xml +++ b/tordnscrypt/src/main/res/layout/item_dns_relay.xml @@ -8,7 +8,7 @@ android:focusable="false" android:orientation="vertical"> - - + - \ No newline at end of file + diff --git a/tordnscrypt/src/main/res/layout/item_dns_server.xml b/tordnscrypt/src/main/res/layout/item_dns_server.xml index aa715b622..8b7ff3b3a 100644 --- a/tordnscrypt/src/main/res/layout/item_dns_server.xml +++ b/tordnscrypt/src/main/res/layout/item_dns_server.xml @@ -10,7 +10,7 @@ android:orientation="vertical" android:visibility="visible"> - - + diff --git a/tordnscrypt/src/main/res/layout/item_firewall.xml b/tordnscrypt/src/main/res/layout/item_firewall.xml index db277fc35..c9f1c2eeb 100644 --- a/tordnscrypt/src/main/res/layout/item_firewall.xml +++ b/tordnscrypt/src/main/res/layout/item_firewall.xml @@ -1,105 +1,113 @@ - - + app:cardCornerRadius="5dp" + app:strokeWidth="2dp"> - + - + - + - + - + - + - + - - + + + + + + diff --git a/tordnscrypt/src/main/res/layout/main_fragment.xml b/tordnscrypt/src/main/res/layout/main_fragment.xml index 70d910042..68bba8936 100644 --- a/tordnscrypt/src/main/res/layout/main_fragment.xml +++ b/tordnscrypt/src/main/res/layout/main_fragment.xml @@ -126,8 +126,7 @@ android:layout_marginBottom="4dp" android:layout_weight="1" android:gravity="center" - android:text="@string/tvTorStop" - app:fontFamily="serif" /> + android:text="@string/tvTorStop" /> + android:text="@string/tvDNSStop" /> + android:text="@string/tvITPDStop" /> + + + + + diff --git a/tordnscrypt/src/main/res/values-de/strings.xml b/tordnscrypt/src/main/res/values-de/strings.xml index 2543aa2de..4a995064f 100644 --- a/tordnscrypt/src/main/res/values-de/strings.xml +++ b/tordnscrypt/src/main/res/values-de/strings.xml @@ -58,9 +58,9 @@ "Wähle den Sicherungsordner:" "Einstellungen" "Autostart" - "Starte DNSCrypt beim Booten" - "Starte Tor beim Booten" - "Starte I2P beim Booten" + Starte DNSCrypt beim Booten + Starte Tor beim Booten + Starte I2P beim Booten "Verzögerung" "Verzögerung (Sek.) nur verwenden, wenn der Autostart nicht korrekt funktioniert" "DNSCrypt Server" @@ -69,17 +69,17 @@ "Routing Einstellungen" "Sende jeglichen Datenverkehr durch Tor" "Sende jeglichen Datenverkehr durch InviZible" - "Wähle Webseiten" - "Liste der Webseiten die mit Tor geöffnet werden" - "Wähle Applikationen" + Wähle Webseiten + Liste der Webseiten die mit Tor geöffnet werden + Wähle Applikationen "Liste der Apps die mit Tor geöffnet werden" "Liste der Apps die mit InviZible geöffnet werden" - "Webseiten ausschliessen" - "Webseiten die direkt geöffnet werden" - "Applikationen ausschliessen" + Webseiten ausschliessen + Webseiten die direkt geöffnet werden + Applikationen ausschliessen "Liste der Apps die direkt geöffnet werden" - "Aktualisierungsintervall" - "Zeitraum in Stunden um Webseiten-IPs zu aktualisieren. Für Android 5.1 und höher. Setze auf 0 um die Aktualisierungen zu stoppen." + Aktualisierungsintervall + Zeitraum in Stunden um Webseiten-IPs zu aktualisieren. Für Android 5.1 und höher. Setze auf 0 um die Aktualisierungen zu stoppen. "Bridges" "Benutze diese, falls du nicht zum Tor Netzwerk verbinden kannst" "Bridges nicht benutzen" @@ -97,14 +97,14 @@ "Speichern" "Schliessen" "Falscher Hostname!" - "Theme auswählen" - "Sprache auswählen" + Theme auswählen + Sprache auswählen "HTTP blockieren" "Verbindung zu HTTP Port 80 verweigern" "Update" - "Automatische Updates" - "Prüfe täglich auf Updates von InviZible Pro und Modules" - "Prüfe Update" + Automatische Updates + Prüfe täglich auf Updates von InviZible Pro und Modules + Prüfe Update "Prüfe ob ein neues Update verfügbar ist" "Updates nur durch Tor" "Updateprüfung nur mit Tor und wenn Tor läuft" @@ -114,32 +114,29 @@ "Diverses" "Blockiere HOTSPOT http" "Verbindung zu http Port 80 im HOTSPOT Modus verweigern" - "Zusätzlicher Schutz vor Schliessen der App durch Android mittels Kein Root Modus" + Zusätzlicher Schutz vor Schliessen der App durch Android mittels Kein Root Modus "Aktualisierung der Regeln" "Aktualisiere die Regeln bei jeder Verbindungsänderung" "Zeige Benachrichtigungen" "Verhindere den Sleep Modus" - "Zusätzlicher Schutz vor Schliessen der App durch Android mittels Kein Root Modus. Kann den Batterieverbrauch erhöhen" + Zusätzlicher Schutz vor Schliessen der App durch Android mittels Kein Root Modus. Kann den Batterieverbrauch erhöhen "Hilfe Messages" - "Hilfe Messages immer anzeigen" - Bitte deaktiviere die Batterieoptimierung deines Telefons für InviZible Pro. -\nAndernfalls können DNSCrypt, Tor oder I2P jederzeit durch Android beendet werden. Auf manchen Systemen, wie zB MIUI, können zusätzliche Schritte nötig sein. + Hilfe Messages immer anzeigen + Bitte deaktiviere die Batterieoptimierung deines Telefons für InviZible Pro. Andernfalls können DNSCrypt, Tor oder I2P jederzeit durch Android beendet werden. Auf manchen Systemen, wie zB MIUI, können zusätzliche Schritte nötig sein. "BusyBox auswählen" "HOTSPOT-Experimentell" - "Starte Tethering beim Booten" - "Erlaube Tor Tethering" + Starte Tethering beim Booten + Erlaube Tor Tethering "Sende jeglichen Datenverkehr durch Tor" "Sende jeglichen eingehenden Datenverkehr durch Tor" - "Wähle Webseiten" - "Liste der Webseiten die im HOTSPOT Modus mit Tor geöffnet werden" - "Webseiten ausschliessen" - "Liste der Webseiten die im HOTSPOT Modus direkt geöffnet werden" - "Erlaube I2P Tethering" + Wähle Webseiten + Liste der Webseiten die im HOTSPOT Modus mit Tor geöffnet werden + Webseiten ausschliessen + Liste der Webseiten die im HOTSPOT Modus direkt geöffnet werden + Erlaube I2P Tethering "TTL festlegen" - "TTL wird bei Benutzung des lokalen VPN auf 64 festgelegt. Kernel Unterstützung wird nicht benötigt. -Dies kann nur im \"root mode\" mit deaktivierter \"Run Modules With Root\" Option angewandt werden. -Um TTL festzulegen starte bitte DNSCrypt und/oder Tor." - "Öffne die Tethering Konfiguration" + "TTL wird bei Benutzung des lokalen VPN auf 64 festgelegt. Kernel Unterstützung wird nicht benötigt. Um TTL festzulegen starte bitte DNSCrypt und/oder Tor." + Öffne die Tethering Konfiguration "Bitte starte DNSCrypt neu" "Bitte starte Tor neu" "Bitte starte I2P neu" @@ -160,31 +157,26 @@ Um TTL festzulegen starte bitte DNSCrypt und/oder Tor." "Server darf Useranfragen nicht speichern (deklarativ)." "Server darf keine eigene Blacklist erzwingen (Elterliche Kontrolle, Blockieren von Werbung…)." "Benutze immer TCP um zu Upstream Servern zu verbinden." - "Dies kann nützlich sein, wenn jeglicher Datenverkehr durch Tor geleitet werden soll. -Andernfalls sollte dies nicht aktiviert werden, da die Sicherheit dadurch nicht verbessert, die Latenz jedoch erhöht wird (DNSCrypt-Proxy wird immer alles verschlüsseln, auch wenn UDP verwendet wird)." + "Dies kann nützlich sein, wenn jeglicher Datenverkehr durch Tor geleitet werden soll. Andernfalls sollte dies nicht aktiviert werden, da die Sicherheit dadurch nicht verbessert, die Latenz jedoch erhöht wird (DNSCrypt-Proxy wird immer alles verschlüsseln, auch wenn UDP verwendet wird)." "HTTP / SOCKS Proxy." "Proxy aktivieren" - "Route alle TCP Verbindungen zu einem lokalen Tor Knoten. -Da Tor UDP nicht unterstützt, setze force_tcp ebenfalls auf aktiv." + "Route alle TCP Verbindungen zu einem lokalen Tor Knoten. Da Tor UDP nicht unterstützt, setze force_tcp ebenfalls auf aktiv." "proxy_port" "Andere Einstellungen." - "Bootstrap Resolver. Dies ist ein normaler, nicht verschlüsselter DNS Resolver, der nur für einmalige Anfragen benutzt wird, um die Liste von Eingangsresolvern zu beziehen, und dies nur, wenn die System DNS Konfiguration nicht funktioniert. -Er wird nie benutzt sobald sich Listen im Cache befinden." + "Bootstrap Resolver. Dies ist ein normaler, nicht verschlüsselter DNS Resolver, der nur für einmalige Anfragen benutzt wird, um die Liste von Eingangsresolvern zu beziehen, und dies nur, wenn die System DNS Konfiguration nicht funktioniert. Er wird nie benutzt sobald sich Listen im Cache befinden." "Lasse Dnscrypt-proxy niemals versuchen die DNS Einstellungen des Systems zu verwenden. Verwende den Fallback Resolver.." "FILTER" "Forwarding Regeln" "Route Anfragen für spezifische Domains zu festgelegten Servern weiter." "Cloaking Regeln" - "Cloaking gibt für spezifische Namen eine festgelegte Adresse zurück. -Zusätzlich zur Funktion als HOSTS Datei, kann Cloaking auch die IP Adresse eines unterschiedlichen Namens zurückgeben. CNAME Flattening wird ebenso durchgeführt.." + "Cloaking gibt für spezifische Namen eine festgelegte Adresse zurück. Zusätzlich zur Funktion als HOSTS Datei, kann Cloaking auch die IP Adresse eines unterschiedlichen Namens zurückgeben. CNAME Flattening wird ebenso durchgeführt.." "Logging von Anfragen." "Logge Client-Anfragen in eine Datei." "Aktiviere das Logging von Anfragen" "Folgende Anfragetypen nicht loggen, um die Informationsmenge zu reduzieren. Leerlassen um alles zu loggen." "Öffne das Anfragen Log" "Logging von verdächtigen Anfragen." - "Logge Anfragen für nichtexistente Zonen. -Die Anfragen können das Vorhandensein von Malware, kaputten Applikationen oder Geräten an Dritte melden bzw aufdecken.." + "Logge Anfragen für nichtexistente Zonen. Die Anfragen können das Vorhandensein von Malware, kaputten Applikationen oder Geräten an Dritte melden bzw aufdecken.." "Aktiviere Verdächtiges Logging" "Öffne das Verdächtigen Log" "Schema gestütztes Blocking (Blacklist)." @@ -244,10 +236,10 @@ Die Anfragen können das Vorhandensein von Malware, kaputten Applikationen oder "Apps zur Umgehung InviZible" "Wähle alle" "Entferne Auswahl" - "Allgemeine Einstellungen" - "Erlaube eingehende Verbindungen." - "Port auf dem auf eingehende Verbindungen gelauscht wird." - "Externe IP des Routers für eingehende Verbindungen." + Allgemeine Einstellungen + Erlaube eingehende Verbindungen. + Port auf dem auf eingehende Verbindungen gelauscht wird. + Externe IP des Routers für eingehende Verbindungen. "Aktiviere Kommunikation über IPv4." "Aktiviere Kommunikation über IPv6." "Router akzeptiert keine Transit Tunnels und deaktiviert somit Transit Traffic komplett." @@ -256,7 +248,7 @@ Die Anfragen können das Vorhandensein von Malware, kaputten Applikationen oder "Max % der Bandbreitenbegrenzung für Transit. 0–100." "Aktiviere SSU Transport Protokoll (verwende UDP)." "Aktiviere NTCP2 Transport Protokoll (verwende TCP)." - "Aktiviere ntcpproxy" + Aktiviere ntcpproxy "Spezifiziere Proxy Server für NTCP. Benutze folgende Syntax: http://address:port oder socks://address:port." "HTTP Proxy" "HTTP Proxy" @@ -273,26 +265,22 @@ Die Anfragen können das Vorhandensein von Malware, kaputten Applikationen oder "Kryptographie" "Benutze vorberechnete ElGamal Tabellen." "UPnP aktivieren/deaktivieren." - "ntcp2 aktiv" "Reseeding" - "Verifiziere .su3 Signatur." + "Verifiziere su3 Signatur." "Begrenzungen" "Setze maximale Anzahl von Transit Tunnels ausser Kraft. 2500 Standard." "Begrenze die Anzahl an offenen Dateien (0 - Benutze Systemgrenze)." - "Maximale Grösse der Kerndatei in Kb (0 - Benutze Systemgrenze)." - "Addressbuch" + Maximale Grösse der Kerndatei in Kb (0 - Benutze Systemgrenze). + Addressbuch "Addressbuch Bereitstellungs URL für die Ersteinrichtung." "Addressbuch Bereitstellungs URLs." "Voreinstellung existiert nicht in i2pd.conf!" "Info" - "Es sieht aus, als wäre DNSCrypt vom System beendet worden. -Deine Internetverbindung wurde wiederhergestellt. Bitte überprüfe deine Geräteeinstellungen!" - "Es sieht aus, als wäre Tor vom System beendet worden. -Deine Internetverbindung wurde wiederhergestellt. Bitte überprüfe deine Geräteeinstellungen!" + "Es sieht aus, als wäre DNSCrypt vom System beendet worden. Deine Internetverbindung wurde wiederhergestellt. Bitte überprüfe deine Geräteeinstellungen!" + "Es sieht aus, als wäre Tor vom System beendet worden. Deine Internetverbindung wurde wiederhergestellt. Bitte überprüfe deine Geräteeinstellungen!" "Es sieht aus, als wäre I2P vom System beendet worden. Bitte überprüfe deine Geräteeinstellungen!" "Es sieht aus, als könnte sich DNSCrypt NICHT in das Internet verbinden. Du kannst versuchen einen anderen DNSCrypt Server auszuwählen. Die betreffende Auswahl findest du unter Menü->Schnelleinstellungen->DNSCrypt Server" - "Es sieht aus, als könnte Tor NICHT ins Internet verbinden. -Dein ISP könnte Tor Verbindungen blockieren. Du kannst versuchen, Tor Bridges zu verwenden. Du findest diese in MENÜ -> Schnelleinstellungen -> Bridges" + "Es sieht aus, als könnte Tor NICHT ins Internet verbinden. Dein ISP könnte Tor Verbindungen blockieren. Du kannst versuchen, Tor Bridges zu verwenden. Du findest diese in MENÜ -> Schnelleinstellungen -> Bridges" "Kindersicherung" "Du kannst die Konfiguration dieser App sperren. Bitte gib hierzu ein Passwort ein oder benutze das Bestehende." "Bitte Passwort eingeben." @@ -304,13 +292,11 @@ Dein ISP könnte Tor Verbindungen blockieren. Du kannst versuchen, Tor Bridges z "Pfad für Logs:" "Logs gespeichert. Bitte sende InvizibleLogs.txt an den Entwickler. Du findest die Logs in folgendem Ordner:" "Update" - "Einige InviZible Module sind bereit für ein Update. -Möchtest du die Updates durchführen? Dies wird die Moduleinstellungen überschreiben!" + "Einige InviZible Module sind bereit für ein Update. Möchtest du die Updates durchführen? Dies wird die Moduleinstellungen überschreiben!" "Update" "Später" "Nicht wieder fragen" - "Bitte starte InviZible Pro neu und erlaube die komplette Installation! -Konfiguriere nach der Installation HOTSPOT neu, falls du ihn benutzt!" + "Bitte starte InviZible Pro neu und erlaube die komplette Installation! Konfiguriere nach der Installation HOTSPOT neu, falls du ihn benutzt!" "Datei wird heruntergeladen" "Der Download wurde abgebrochen" "DOWNLOAD ABBRECHEN" @@ -319,12 +305,12 @@ Konfiguriere nach der Installation HOTSPOT neu, falls du ihn benutzt!" "DNSCrypt Update ist verfügbar. Möchtest du es herunterladen und installieren? Die Installation läuft im Hintergrund weiter." "Tor Update ist verfügbar. Möchtest du es herunterladen und installieren? Die Installation läuft im Hintergrund weiter." "Purple I2P Update ist verfügbar. Möchtest du es herunterladen und installieren? Die Installation läuft im Hintergrund weiter." - "Überprüfe auf Updates" - "Bitte warte während auf Updates geprüft wird" + Überprüfe auf Updates + Bitte warte während auf Updates geprüft wird "Der Update Server ist temporär nicht erreichbar. Bitte versuche es später noch einmal." "Der Update Server war nicht erreichbar." "Fehler beim Update." - "Es wurden keine Updates gefunden." + Es wurden keine Updates gefunden. "Letzte Überprüfung:" "Updates wurden gefunden." "Updates wurden installiert." @@ -338,8 +324,7 @@ Konfiguriere nach der Installation HOTSPOT neu, falls du ihn benutzt!" "Besuchen" "Code eingeben" "Code eingeben" - "InviZible Pro Project und sein Entwickler möchten sich für deine Unterstützung bedanken. -Möchtest du den Download und das Upgrade auf PRO durchführen? Die Installation läuft im Hintergrund weiter." + "InviZible Pro Project und sein Entwickler möchten sich für deine Unterstützung bedanken. Möchtest du den Download und das Upgrade auf PRO durchführen? Die Installation läuft im Hintergrund weiter." "Remote Listen von verfügbaren Relays." "VPN Modus ist aktiv" "VPN Modus ist aus" @@ -354,25 +339,15 @@ Möchtest du den Download und das Upgrade auf PRO durchführen? Die Installation InviZible Pro Project braucht deine Unterstützung. Drücke OK um die Premium Features kostenpflichtig zu erwerben. "Es tut mir leid, aber dein Einkauf kann leider nicht bestätigt werden. Eine Rückerstattung erolgt nach 3 tagen." "Leider ist dieses Feature nur in der Premium Version verfügbar." - " -\n \t Vielen Dank, dass du dich für InviZible Pro entschieden hast. Ich hoffe, dass du dich damit gut geschützt und angenehm im Internet bewegen kannst. -\n -\n\tInviZible Pro beinhaltet Tor, DNSCrypt und Purple I2P als Module. -\n -\n\tInviZible Pro kann Root benutzen, falls dein Gerät dies erlaubt, oder alternativ ein lokales VPN anbieten, das Internetverkehr an Tor, DNSCrypt und I2P Netzwerke weiterleitet. -\n -\n\tDieses Produkt wird unabhängig von Tor®, DNSCrypt und Purple I2P Software entwickelt und gibt bezüglich der erwähnten Projekte keinerlei Garantie im Hinblick auf Qualität, Tauglichkeit oder anderes. -\n -\n\tInviZible Pro wird veröffentlicht in der Hoffnung etwas Nützliches zu schaffen, allerdings OHNE JEGLICHE GEWÄHRLEISTUNG; ferner ohne jegliche auch nur implizierte Zusicherung von Verwendbarkeit oder Gebrauchstauglichkeit für spezielle Einsatzzwecke. -\n -\n\tCopyright © 2019-2024 -\n -\n\tGarmatin Oleksandr -\n -\n\tinvizible.soft@gmail.com -\n -\n\tinvizible.net/en/privacy -\n " + + \t Vielen Dank, dass du dich für InviZible Pro entschieden hast. Ich hoffe, dass du dich damit gut geschützt und angenehm im Internet bewegen kannst. + \n\n\tInviZible Pro beinhaltet Tor, DNSCrypt und Purple I2P als Module. + \n\n\tInviZible Pro kann Root benutzen, falls dein Gerät dies erlaubt, oder alternativ ein lokales VPN anbieten, das Internetverkehr an Tor, DNSCrypt und I2P Netzwerke weiterleitet. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + "Ausgehender HTTP Proxy" "Ausgehender HTTP Proxy" "Ausgehender SOCKS Proxy" @@ -391,8 +366,7 @@ Möchtest du den Download und das Upgrade auf PRO durchführen? Die Installation "Importiere eine Forwarding Regeldatei. Du kannst mehrere Dateien auswählen, doppelte Einträge werden entfernt." "Lösche Forwarding Regeln" "Importiere Cloaking Regeln" - "Importiere eine Cloaking Regeldatei. Du kannst mehrere Dateien auswählen, doppelte Einträge werden entfernt. -" + "Importiere eine Cloaking Regeldatei. Du kannst mehrere Dateien auswählen, doppelte Einträge werden entfernt." "Lösche Cloaking Regeln" "Importiere Blacklist" "Importiere eine Liste von Domains oder eine Hosts Datei. Du kannst mehrere Dateien auswählen, doppelte Einträge werden entfernt." @@ -403,8 +377,7 @@ Möchtest du den Download und das Upgrade auf PRO durchführen? Die Installation "Importiere Whitelist" "Importiere eine Domain-Liste. Du kannst mehrere Dateien auswählen, doppelte Einträge werden entfernt." "Lösche Whitelist" - "Beantworte IPv6 bezogene Anfragen umgehend leer. -Dies beschleunigt Abläufe, wenn keine IPv6 Konnektivität vorhanden ist, kann aber gleichzeitig zu Störungen bei manchen Stub Resolvern führen." + "Beantworte IPv6 bezogene Anfragen umgehend leer. Dies beschleunigt Abläufe, wenn keine IPv6 Konnektivität vorhanden ist, kann aber gleichzeitig zu Störungen bei manchen Stub Resolvern führen." "Bitte schalte \"Privater DNS\" in den Android Netzwerkeinstellungen aus. Diese Option beeinträchtigt DNSCrypt." "Importiere Regeln" "Bitte warten... %d Regeln importiert." @@ -417,30 +390,26 @@ Dies beschleunigt Abläufe, wenn keine IPv6 Konnektivität vorhanden ist, kann a "Neue Tor Bridges sind verfügbar. Möchtest du diese aktualisieren?" "MITM Angriffserkennung" "ARP Spoofing Erkennung" - "Erkenne Man-in-the-middle ARP Spoofing sowie bösartige DHCP Angriffe in WLAN Netzen." + Erkenne Man-in-the-middle ARP Spoofing sowie bösartige DHCP Angriffe in WLAN Netzen. "Blockiere die Internetverbindung wenn ein Angriff erkannt wird" "Die Internetverbindung wird während eines Angriffs blockiert" "Proxy" "Benutze SOCKS5 Proxy" "InviZible Pro wird alle Verbindungen durch den SOCKS5 Proxy leiten" "Kompatibilitätsmodus" - "Aktivieren falls du ein Gerät mit Custom-ROM nutzt, bei dem die Verbindung abbricht sobald du den START Knopf drückst" + Aktivieren falls du ein Gerät mit Custom-ROM nutzt, bei dem die Verbindung abbricht sobald du den START Knopf drückst "Aktiviere Skript Kontrolle" - "Nutze den folgenden Befehl um Module zu verwalten: -\"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL - --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\" -1 = Modulstart, 0 = Modulstopp" + "Nutze den folgenden Befehl um Module zu verwalten: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\" 1 = Modulstart, 0 = Modulstopp" "Lokale IP Adresse" "Aktiviere Fix TTL und konfiguriere das LAN Gerät InviZible zu nutzen. Benutze den Standard Gateway: %1$s, DNS Server: %2$s." "Unterstützung für Multi-User" - "Unterstützung für Dual Apps, MIUI, Island, Shelter und Apps mit Arbeitsprofilen" + Unterstützung für Dual Apps, MIUI, Island, Shelter und Apps mit Arbeitsprofilen "Aktiviere SOCKS Ausgabe Proxy" "Tor wird alle OR Verbindungen durch den SOCKS5 Proxy leiten" "Laufende Dienste" "Update Benachrichtigungen" "Root Kommandos Benachrichtigung" - "Ein Absturzbericht wurde vorbereitet. -Möchtest du diesen zum Verbessern von InviZible an den Entwickler senden?" + "Ein Absturzbericht wurde vorbereitet. Möchtest du diesen zum Verbessern von InviZible an den Entwickler senden?" "Neue Tor Identität" "Tor Identität gewechselt" "Proxy Server:" @@ -459,8 +428,7 @@ Möchtest du diesen zum Verbessern von InviZible an den Entwickler senden?""Erfolgreiche Verbindung. Ping %s ms." "ARP Spoofing erkannt!" "Bösartiges DHCP erkannt!" - "Man-in-the-middle Angriff erkannt! Deine Daten können von einem anderen Gerät im lokalen Netzwerk abgefangen werden. -WLAN aus- und kurz darauf wieder anschalten. Die Verwendung des derzeitigen Hotspots kann ebenfalls betroffen sein." + "Man-in-the-middle Angriff erkannt! Deine Daten können von einem anderen Gerät im lokalen Netzwerk abgefangen werden. WLAN aus- und kurz darauf wieder anschalten. Die Verwendung des derzeitigen Hotspots kann ebenfalls betroffen sein." "Erkennung von ARP Spoofing auf deinem Gerät wird leider nicht unterstützt!" "Bitte deaktiviere die Einstiegsknoten in den Tor Einstellungen um Bridges nutzen zu können." "Umgehe LAN Adressen" @@ -515,7 +483,7 @@ WLAN aus- und kurz darauf wieder anschalten. Die Verwendung des derzeitigen Hots "Tor IP wird gewechselt" "Du hast mehr als 3 Kacheln zu den Schnelleinstellungen hinzugefügt. Bitte belasse es bei 3. Das Hinzufügen von mehr als 3 Kacheln kann Probleme verursachen." "Erkennung von bösartigem DHCP" - "Erkenne bösartige Man-in-the-middle DHCP Attacken in Wi-Fi Netzwerken." + Erkenne bösartige Man-in-the-middle DHCP Attacken in Wi-Fi Netzwerken. "Wähle ein Rendezvous" "Versteckt den Domänennamen des Brokers vor dem ISP. Der Broker wird verwendet, um eine Verbindung aufzubauen." "Voreinstellung für App Anzeige" @@ -544,7 +512,7 @@ WLAN aus- und kurz darauf wieder anschalten. Die Verwendung des derzeitigen Hots "Verwendete statische IPv6 Präfixe." "IPv6 bridges" "Achtung" - "InviZible Pro kann %1$s nicht starten! Bitte versuchen Sie, die Einstellungen von %2$s zurückzusetzen. Wenn dies nicht hilft, starten Sie bitte Ihr Gerät neu." + InviZible Pro kann %1$s nicht starten! Bitte versuchen Sie, die Einstellungen von %2$s zurückzusetzen. Wenn dies nicht hilft, starten Sie bitte Ihr Gerät neu. "Zurücksetzen" "SNI vortäuschen" "Tor verfolgt die letzten Verbindungen zu Hosts und versucht, die jeweiligen Exit-Nodes wiederzuverwenden. Diese Option kann dazu beitragen, endlose Captchas zu vermeiden." diff --git a/tordnscrypt/src/main/res/values-el/strings.xml b/tordnscrypt/src/main/res/values-el/strings.xml index 61e384024..c57fc3f46 100644 --- a/tordnscrypt/src/main/res/values-el/strings.xml +++ b/tordnscrypt/src/main/res/values-el/strings.xml @@ -64,9 +64,9 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Επιλογή φακέλου:" "Ρυθμίσεις" "Αυτόματη Εκκίνηση" - "Εκκίνηση DNSCrypt κατά τη φόρτωση" - "Εκκίνηση Tor κατά τη φόρτωση" - "Εναρξη I2P κατά την εκκίνηση" + Εκκίνηση DNSCrypt κατά τη φόρτωση + Εκκίνηση Tor κατά τη φόρτωση + Εναρξη I2P κατά την εκκίνηση "Καθυστέρηση" "Χρησιμοποιήστε την καθυστέρηση (σε δευτερόλεπτα) μόνο εάν η αυτόματη εκκίνηση δεν λειτουργεί σωστά" "Διακομιστές DNSCrypt" @@ -75,17 +75,17 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Ρυθμίσεις Δρομολόγησης" "Δρομολόγηση όλων των δεδομένων μέσω Tor" "Δρομολόγηση όλων των δεδομένων μέσω InviZible" - "Επιλογή Ιστοσελιδών" - "Λίστα ιστοσελιδών για άνοιγμα με Tor. Αυτή η δυνατότητα δεν λειτουργεί για ιστότοπους που βρίσκονται πίσω από το CDN δίκτυο" - "Επιλογή Εφαρμογών" + Επιλογή Ιστοσελιδών + Λίστα ιστοσελιδών για άνοιγμα με Tor. Αυτή η δυνατότητα δεν λειτουργεί για ιστότοπους που βρίσκονται πίσω από το CDN δίκτυο + Επιλογή Εφαρμογών "Λίστα εφαρμογών για χρήση με το Tor" "Λίστα εφαρμογών για χρήση με το InviZible" - "Εξαίρεση Ιστοσελίδων" - "Λίστα ιστοσελιδών για απευθείας άνοιγμα. Αυτή η δυνατότητα δεν λειτουργεί για ιστότοπους που βρίσκονται πίσω από το CDN δίκτυο" - "Εξαίρεση Εφαρμογών" + Εξαίρεση Ιστοσελίδων + Λίστα ιστοσελιδών για απευθείας άνοιγμα. Αυτή η δυνατότητα δεν λειτουργεί για ιστότοπους που βρίσκονται πίσω από το CDN δίκτυο + Εξαίρεση Εφαρμογών "Λίστα εφαρμογών που ανοίγουν απευθείας" - "Διάστημα ανανέωσης" - "Περίοδος σε ώρες για την ανανέωση των IP Ιστοτόπων. Για Android 5.1 και νεότερες εκδόσεις. Βάλτε 0 για να σταματήσει η ανανέωση." + Διάστημα ανανέωσης + Περίοδος σε ώρες για την ανανέωση των IP Ιστοτόπων. Για Android 5.1 και νεότερες εκδόσεις. Βάλτε 0 για να σταματήσει η ανανέωση. "Επικαλύψεις" "Χρησιμοποιήστε το εάν δεν μπορείτε να συνδεθείτε στο δίκτυο Tor" @@ -107,14 +107,14 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Αποθήκευση" "Κλείσιμο" "Λάθος όνομα διακομιστή!" - "Επιλογή Θέματος" - "Επιλογή Γλώσσας" + Επιλογή Θέματος + Επιλογή Γλώσσας "Μπλοκάρισμα http" "Άρνηση σύνδεσης στη θύρα http 80" "Ενημέρωση" - "Αυτόματες Ενημερώσεις" - "Ελέγχετε καθημερινά τις ενημερώσεις του InviZible Pro και των πρόσθετων μονάδων" - "Ελεγχος Ενημέρωσης" + Αυτόματες Ενημερώσεις + Ελέγχετε καθημερινά τις ενημερώσεις του InviZible Pro και των πρόσθετων μονάδων + Ελεγχος Ενημέρωσης "Ελέγξτε εάν είναι διαθέσιμες νέες εκδόσεις τώρα" "Ενημέρωση αυστηρά μέσω Tor" "Ελέγξτε τις ενημερώσεις μόνο με το Tor και όταν το Tor εκτελείται" @@ -124,30 +124,30 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Λοιπά" "Αποκλεισμός HOTSPOT http" "Άρνηση σύνδεσης στη θύρα http 80 για HOTSPOT" - "Προστατέψτε την εφαρμογή με τη λειτουργία No Root για να αποτρέψετε τον ξαφνικό τερματισμό της εφαρμογής από το σύστημα android" + Προστατέψτε την εφαρμογή με τη λειτουργία No Root για να αποτρέψετε τον ξαφνικό τερματισμό της εφαρμογής από το σύστημα android "Ανανέωση κανόνων" "Ενημερώστε τους κανόνες σε κάθε αλλαγή συνδεσιμότητας" "Εμφάνιση ειδοποίησης" "Αποτρέψτε τον ύπνο της συσκευής" - "Πρόσθετη προστασία για τη λειτουργία No Root ώστε αποτρέψετε τον ξαφνικό τερματισμό της εφαρμογής από το σύστημα android. Μπορεί όμως να εξαντλήσει την μπαταρία" + Πρόσθετη προστασία για τη λειτουργία No Root ώστε αποτρέψετε τον ξαφνικό τερματισμό της εφαρμογής από το σύστημα android. Μπορεί όμως να εξαντλήσει την μπαταρία "Βοηθητικά μηνύματα" - "Εμφάνιση πάντα βοηθητικών μηνυμάτων" + Εμφάνιση πάντα βοηθητικών μηνυμάτων Εξαιρέστε το InviZible Pro από τη βελτιστοποίηση μπαταρίας στο Android. Διαφορετικά, το android θα τερματίζει το DNSCrypt, το Tor ή το I2P ανά πάσα στιγμή. Σε ειδικά συστήματα, όπως το MIUI, απαιτούνται ορισμένα πρόσθετα βήματα. "Επιλογή BusyBox" "HOTSPOT-Πειραματικό" - "Ξεκινήστε τη πρόσδεση κατά την εκκίνηση" - "Να επιτρέπεται η πρόσδεση Tor" + Ξεκινήστε τη πρόσδεση κατά την εκκίνηση + Να επιτρέπεται η πρόσδεση Tor "Ανακατεύθυνση όλων μέσω Tor" "Ανακατεύθυνση όλης της εισερχόμενης κίνησης μέσω Tor" - "Επιλέξτε Ιστοσελίδες" - "Λίστα ιστοτόπων για άνοιγμα με Tor για HOTSPOT" - "Εξαίρεση Ιστοσελίδων" - "Λίστα ιστοτόπων για άνοιγμα απευθείας για HOTSPOT" - "Να επιτρέπετται πρόσδεση I2P" + Επιλέξτε Ιστοσελίδες + Λίστα ιστοτόπων για άνοιγμα με Tor για HOTSPOT + Εξαίρεση Ιστοσελίδων + Λίστα ιστοτόπων για άνοιγμα απευθείας για HOTSPOT + Να επιτρέπετται πρόσδεση I2P "Διόρθωση TTL" - "Το TTL θα διορθωθεί σε 64 χρησιμοποιώντας τοπικό VPN. Δεν απαιτείται υποστήριξη πυρήνα. Μπορεί να χρησιμοποιηθεί μόνο σε \"λειτουργία root\" με απενεργοποιημένη την επιλογή \"Εκτέλεση Μονάδων ως Root\". Για να διορθώσετε το TTL, ξεκινήστε το DNSCrypt ή/και το Tor." - "Ανοίξτε ρυθμίσεις της πρόσδεσης" + Το TTL θα διορθωθεί σε 64 χρησιμοποιώντας τοπικό VPN. Δεν απαιτείται υποστήριξη πυρήνα. Μπορεί να χρησιμοποιηθεί μόνο σε \"λειτουργία root\" με απενεργοποιημένη την επιλογή \"Εκτέλεση Μονάδων ως Root\". Για να διορθώσετε το TTL, ξεκινήστε το DNSCrypt ή/και το Tor. + Ανοίξτε ρυθμίσεις της πρόσδεσης "Παρακαλώ επανεκκινήστε το DNSCrypt" "Παρακαλώ επανεκκινήστε το Tor" "Παρακαλώ επανεκκινήστε το I2P" @@ -175,7 +175,7 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Δρομολογήστε όλες τις συνδέσεις TCP σε έναν τοπικό κόμβο Tor. Το Tor δεν υποστηρίζει UDP, οπότε ορίστε και το force_tcp σε ενεργό." "Θύρα διακομιστή" "Λοιπές Ρυθμίσεις." - "Επίλυση με Bootstrap. Αυτή είναι μια κανονική, μη κρυπτογραφημένη λύση επίλυσης DNS, η οποία θα χρησιμοποιηθεί για ερωτήματα μιας μόνο λήψης κατά την ανάκτηση της αρχικής λίστας επιλυτών και μόνο εάν η διαμόρφωση DNS του συστήματος δεν λειτουργεί. Δεν θα χρησιμοποιηθεί ποτέ εάν οι λίστες έχουν ήδη αποθηκευτεί προσωρινά." + Επίλυση με Bootstrap. Αυτή είναι μια κανονική, μη κρυπτογραφημένη λύση επίλυσης DNS, η οποία θα χρησιμοποιηθεί για ερωτήματα μιας μόνο λήψης κατά την ανάκτηση της αρχικής λίστας επιλυτών και μόνο εάν η διαμόρφωση DNS του συστήματος δεν λειτουργεί. Δεν θα χρησιμοποιηθεί ποτέ εάν οι λίστες έχουν ήδη αποθηκευτεί προσωρινά. "Μην αφήνετε ποτέ το dnscrypt-proxy να προσπαθήσει να χρησιμοποιήσει τις ρυθμίσεις DNS του συστήματος. Χρησιμοποιήστε άνευ όρων την εναλλακτική λύση επίλυσης.." "ΦΙΛΤΡΑ" "Κανόνες προώθησης" @@ -188,8 +188,7 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Μην καταγράφετε αυτούς τους τύπους ερωτημάτων, για να μειώσετε το μέγεθος. Διατηρήστε το κενό για να καταγράψετε τα πάντα." "Ανοίξτε το αρχείο καταγραφής ερωτημάτων" "Καταγραφή ύποπτων ερωτημάτων." - "Ερωτήματα καταγραφής για ανύπαρκτες ζώνες. -Αυτά τα ερωτήματα μπορούν να αποκαλύψουν την παρουσία κακόβουλου λογισμικού, κατεστραμμένων/απαρχαιωμένων εφαρμογών και συσκευών που σηματοδοτούν την παρουσία τους σε τρίτους.." + "Ερωτήματα καταγραφής για ανύπαρκτες ζώνες. Αυτά τα ερωτήματα μπορούν να αποκαλύψουν την παρουσία κακόβουλου λογισμικού, κατεστραμμένων/απαρχαιωμένων εφαρμογών και συσκευών που σηματοδοτούν την παρουσία τους σε τρίτους.." "Ενεργοποίηση καταγραφής ύποπτων συμβάντων" "Ανοιγμα αρχείου καταγραφής ύποπτων συμβάντων" "Αποκλεισμός βάσει μοτίβων (μαύρη λίστα)." @@ -250,10 +249,10 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Εφαρμογές για παράκαμψη απο το InviZible" "Επιλογή Ολων" "Ακύρωση Επιλογής" - "Κοινές Ρυθμίσεις" - "Επιτρέψτε τις εισερχόμενες συνδέσεις" - "Θύρα για ακρόαση εισερχόμενων συνδέσεων." - "Εξωτερική IP δρομολογητή για εισερχόμενες συνδέσεις." + Κοινές Ρυθμίσεις + Επιτρέψτε τις εισερχόμενες συνδέσεις + Θύρα για ακρόαση εισερχόμενων συνδέσεων. + Εξωτερική IP δρομολογητή για εισερχόμενες συνδέσεις. "Ενεργοποίηση επικοινωνίας μέσω IPv4." "Ενεργοποίηση επικοινωνίας μέσω IPv6." @@ -263,7 +262,7 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Μέγιστο % του ορίου εύρους ζώνης για μεταφορά. 0–100." "Ενεργοποιήστε το πρωτόκολλο μεταφοράς SSU (χρησιμοποιήστε UDP)." "Ενεργοποιήστε το πρωτόκολλο μεταφοράς NTCP2 (χρησιμοποιήστε TCP)." - "Ενεργοποιήστε το ntcppproxy" + Ενεργοποιήστε το ntcppproxy "Καθορίστε διακομιστή μεσολάβησης για NTCP. Θα πρέπει να είναι http://address:port ή socks://address:port." "Διακομιστής μεσολάβησης HTTP" "Ενεργός διακομιστής μεσολάβησης HTTP" @@ -281,14 +280,13 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Κρυπτογράφηση" "Χρησιμοποιήστε προυπολογισμένους πίνακες ElGamal." "Ενεργοποιήστε ή απενεργοποιήστε το UPnP." - "ntcp2 ενεργό" "επανατροφοδότηση" - "Επαληθεύστε την υπογραφή .su3." + "Επαληθεύστε την υπογραφή su3." "Περιορισμοί" "Παράκαμψη μέγιστου αριθμού καναλιών διέλευσης. 2500 από προεπιλογή." "Όριο αριθμού περιγραφών ανοιχτών αρχείων (0 - χρήση ορίου συστήματος)." - "Μέγιστο μέγεθος βασικού αρχείου σε Kb (0 - χρήση ορίου συστήματος)." - "Βιβλίο διευθύνσεων" + Μέγιστο μέγεθος βασικού αρχείου σε Kb (0 - χρήση ορίου συστήματος). + Βιβλίο διευθύνσεων "URL συνδρομής βιβλίου διευθύνσεων για αρχική ρύθμιση." "URL συνδρομών Βιβλίου Διευθύνσεων." "Δεν έχει οριστεί προτίμηση στο αρχείο i2pd.conf!" @@ -323,12 +321,12 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Υπάρχει ενημέρωση DNSCrypt διαθέσιμη. Θέλετε να τη κατεβάσετε και να ενημερώσετε; Η ενημέρωση θα συνεχιστεί στο παρασκήνιο." "Διαθέσιμη ενημέρωση Tor. Θα επιθυμούσατε να κάνετε λήψη και ενημέρωση; Η ενημέρωση θα συνεχίσει στο παρασκήνιο." "Διαθέσιμη ενημέρωση Purple I2P. Θα επιθυμούσατε να κάνετε λήψη και ενημέρωση; Η ενημέρωση θα συνεχίσει στο παρασκήνιο." - "Ελεγχος Ενημερώσεων" - "Παρακαλούμε περιμένετε καθώς γίνεται έλεγχος για ενημερώσεις." + Ελεγχος Ενημερώσεων + Παρακαλούμε περιμένετε καθώς γίνεται έλεγχος για ενημερώσεις. "Ο διακομιστής ενημερώσεων είναι προσωρινά μη διαθέσιμος. Παρακαλώ δοκιμάστε αργότερα." "Διακομιστής ενημερώσεων μη διαθέσιμος." "Σφάλμα ενημέρωσης." - "Δεν βρέθηκαν διαθέσιμες ενημερώσεις." + Δεν βρέθηκαν διαθέσιμες ενημερώσεις. "Τελευταίος έλεγχος:" "Βρέθηκαν ενημερώσεις." "Οι ενημερώσεις εγκαταστάθηκαν." @@ -358,20 +356,17 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from Το InviZible Pro Project χρειάζεται τη βοήθειά σας. Πατήστε OK για να αγοράσετε λειτουργίες μέσω έκδοσης premium. "Λυπούμαστε, αλλά είναι αδύνατο να επιβεβαιώσετε την αγορά σας. Θα λάβετε επιστροφή χρημάτων μετά από 3 ημέρες." "Δυστυχώς, αυτή η δυνατότητα είναι διαθέσιμη μόνο για την έκδοση premium." - \tΕυχαριστούμε που επιλέξατε το InviZible Pro. Ελπίζω ότι θα είναι χρήσιμο για την ιδιωτικότητά σας και την άνετη χρήση του Διαδικτύου. -\n -\n\tΤο InviZible Pro περιλαμβάνει το Tor, DNSCrypt και Purple I2P ως λειτουργικές μονάδες. -\n -\n\tΤο InviZible Pro μπορεί να χρησιμοποιήσει δικαιώματα root, εάν η συσκευή σας έχει δικαιώματα root, ή χρησιμοποιεί ένα τοπικό VPN για να παρέχει κίνηση Διαδικτύου σε δίκτυα μέσω Tor, DNSCrypt και I2P. -\n -\n\tΠολιτική απορρήτου: -\n\tΤο InviZible Pro δεν συλλέγει ούτε κοινοποιεί προσωπικά ή ευαίσθητα δεδομένα χρήστη. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy -\n + + \tΕυχαριστούμε που επιλέξατε το InviZible Pro. Ελπίζω ότι θα είναι χρήσιμο για την ιδιωτικότητά σας και την άνετη χρήση του Διαδικτύου. + \n\n\tΤο InviZible Pro περιλαμβάνει το Tor, DNSCrypt και Purple I2P ως λειτουργικές μονάδες. + \n\n\tΤο InviZible Pro μπορεί να χρησιμοποιήσει δικαιώματα root, εάν η συσκευή σας έχει δικαιώματα root, ή χρησιμοποιεί ένα τοπικό VPN για να παρέχει κίνηση Διαδικτύου σε δίκτυα μέσω Tor, DNSCrypt και I2P. + \n\n\tΠολιτική απορρήτου: + \n\tΤο InviZible Pro δεν συλλέγει ούτε κοινοποιεί προσωπικά ή ευαίσθητα δεδομένα χρήστη. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + "Μεσολαβητής εξόδου HTTP" "Διεύθυνση μεσολαβητή εξόδου HTTP" "Μεσολαβητής εξόδου SOCKS" @@ -414,7 +409,7 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Νέες προεπιλεγμένες επικαλύψεις Tor είναι διαθέσιμες. Θέλετε να τα ενημερώσετε;" "Ανίχνευση επίθεσης MITM" "Ανίχνευση πλαστογράφησης ARP" - "Ανίχνευση πλαστογράφησης ARP και τύπο Man-in-the-Middle επιθέσεων DHCP σε δίκτυα Wi-Fi." + Ανίχνευση πλαστογράφησης ARP και τύπο Man-in-the-Middle επιθέσεων DHCP σε δίκτυα Wi-Fi. "Αποκλεισμός του διαδικτύου όταν εντοπιστεί επίθεση" "Η σύνδεση στο Διαδίκτυο θα αποκλειστεί κατά τη διάρκεια της επίθεσης" "Μεσολαβητής" @@ -422,13 +417,13 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Το InviZible Pro θα πραγματοποιήσει όλες τις συνδέσεις μέσω του διακομιστή μεσολάβησης SOCKS5" "Λειτουργία συμβατότητας" - "Ενεργοποιήστε το εάν η συσκευή σας είναι με προσαρμοσμένη ROM και η σύνδεση χάνεται όταν πατήσετε το κουμπί START" + Ενεργοποιήστε το εάν η συσκευή σας είναι με προσαρμοσμένη ROM και η σύνδεση χάνεται όταν πατήσετε το κουμπί START "Ενεργοποίηση ελέγχου κώδικα" "Χρησιμοποιήστε την ακόλουθη εντολή για να διαχειριστείτε τις μονάδες της εφαρμογής: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Όπου 1 - ξεκινά, 0 - σταματά τη μονάδα." "Διεύθυνση IP συσκευής LAN" "Ενεργοποιήστε τη διόρθωση TTL και διαμορφώστε τη συσκευή LAN για σύνδεση στο InviZible. Χρησιμοποιήστε την προεπιλεγμένη πύλη: %1$s, και διακομιστή DNS: %2$s." "Υποστήριξη πολλών χρηστών" - "Υποστήριξη για εφαρμογές Dual Apps, MIUI, Island, Shelter και προφίλ Work" + Υποστήριξη για εφαρμογές Dual Apps, MIUI, Island, Shelter και προφίλ Work "Ενεργοποίηση διακομιστή μεσολάβησης εξόδου SOCKS" "Το Tor θα κάνει όλες τις συνδέσεις OR μέσω του διακομιστή μεσολάβησης SOCKS 5." "Ενεργές υπηρεσίες" @@ -508,7 +503,7 @@ Should it be named instead "Βασικές Ρυθμίσεις" (originating from "Tor IP άλλαξε" "Έχετε προσθέσει περισσότερα από 3 εικονίδια στις Γρήγορες ρυθμίσεις. Αφήστε μόνο 3. Η προσθήκη περισσότερων από 3 εικονιδίων μπορεί να προκαλέσει προβλήματα με τον έλεγχο της εφαρμογής." "Ανίχνευση ψεύτικων DHCP" - "Εντοπίστε ψεύτικες DHCP για επιθέσεις τύπου Man-in-the-middle σε δίκτυα Wi-Fi." + Εντοπίστε ψεύτικες DHCP για επιθέσεις τύπου Man-in-the-middle σε δίκτυα Wi-Fi. "Επιλέξτε τύπο snowflake" "Αποκρύπτει το όνομα τομέα του από τον πάροχο Διαδικτύου. Το όνομα χρησιμοποιείται για τη δημιουργία μιας σύνδεσης." "Εμφάνιση όλων των εφαρμογών" diff --git a/tordnscrypt/src/main/res/values-es/strings.xml b/tordnscrypt/src/main/res/values-es/strings.xml index 3b8681710..090b93127 100644 --- a/tordnscrypt/src/main/res/values-es/strings.xml +++ b/tordnscrypt/src/main/res/values-es/strings.xml @@ -58,9 +58,9 @@ "Selecciona carpeta de copia:" "Configuración" "Inicio Automático" - "Arrancar DNSCrypt al inicio del dispositivo" - "Arrancar Tor al inicio del dispositivo" - "Arrancar I2P al inicio del dispositivo" + Inicio automático de DNSCrypt + Inicio automático de Tor + Arrancar I2P al inicio del dispositivo "Retraso" "Establece un retraso en segundos en el caso en que Inicio Automático no funcione." "Servidores DNSCrypt" @@ -69,17 +69,17 @@ "Configuración de rutas" "Redirigir todo el tráfico a través de Tor" "Dirigir todo el tráfico por InviZible" - "Introduzca sitios web" - "Lista de sitios web para abrir con Tor. Éste ajuste no funciona para sitios detrás de una CDN." - "Seleccionar Aplicaciones" + Seleccionar sitios + Lista de páginas web para abrir con Tor. Esta característica no funciona para los sitios detrás de CDN + Seleccionar aplicaciones "Aplicaciones a usar con Tor." "Aplicaciones a usar con InviZible" - "Excluir sitios web" - "Lista de sitios web a excluir de Tor. Éste ajuste no funciona para sitios detras de una CDN." - "Excluir aplicaciones" + Excluir páginas web + Lista de páginas web para abrir directamente. Esta función no funciona para los sitios detrás de CDN + Excluir aplicaciones "Lista de aplicaciones a excluir de Tor." - "Intervalo de actualización" - "Periodo en horas para actualizar IPs de sitios web. Para Android 5.1 en adelante. El valor 0 (cero) lo desactiva." + Intervalo de refresco + Período en horas para actualizar la IP de las páginas. Para Android 5.1 y superior. Ponga 0 para detener el refresco. "Puentes" "Usalos si Tor no conecta." "Sin puentes" @@ -97,14 +97,14 @@ "Guardar" "Cerrar" "¡Nombre de sitio erroneo!" - "Seleccionar Tema" - "Seleccionar Idioma" + Seleccionar un tema + Seleccionar idioma "Bloquear HTTP" "Bloquear conexiones al puerto 80 de HTTP." "Actualizaciones" - "Actualizaciones automáticas" - "Comprobar diariamente actualizaciones para Invizible Pro." - "Comprobar actualizaciones" + Actualizaciones automáticas + Compruebe diariamente las actualizaciones de InviZible Pro y de los módulos + Comprobar actualizaciones "Comprobar si hay una nueva versión disponible" "Actualizar solo a través de Tor" "Comprobar actualizaciones solo a través de Tor." @@ -114,30 +114,30 @@ "Otros" "Bloquear tráfico HTTP al Compartir Internet" "Bloquea conexiones al puerto 80 de HTTP en Compartir Internet." - "Prevenir la parada súbita de la aplicación por Android en modo sin privilegios de superusuario" + Proteger la aplicación para que Android no la elimine "Reaplicar reglas de tráfico" "Reaplicar reglas de tráfico en cambios de conectividad." "Mostrar notificaciones" "Prevenir sueño profundo del dispositivo" - "Añade una protección adicional que previene la parada súbita de la aplicación por Android en modos no Root. Puede gastar batería." + No permita que el dispositivo entre en modo suspensión. Puede ser útil cuando se utiliza HOTSPOT. ¡Drena la batería! "Mensajes de ayuda" - "Muestra siempre los mensajes de ayuda." + Mostrar todos los mensajes que han sido marcados como no permitidos para mostrarse Por favor, excluye InviZible Pro de la optimización de batería de Android para evitar que el sistema termine DNSCrypt, Tor o I2P en cualquier momento. Algunos sistemas especiales, como MIUI, pueden requerir pasos adicionales. "Seleccionar binario BusyBox" "Compartir Internet-En pruebas" - "Arrancar Compartir Internet al inicio del dispositivo" - "Redirigir conexiones compartidas hacia Tor" + Comience a compartir al iniciar + Permitir compartir en Tor "Redirigir todo el tráfico hacia Tor" "Redirigir todo el tráfico entrante hacia Tor." - "Sitios web para abrir con Tor" - "Lista de sitios web para abrir con Tor en Compartir Internet." - "Sitios Web para excluir de Tor" - "Conexión directa a sitios web desde Compartir Internet." - "Compartir tráfico I2P" + Seleccionar páginas + Lista de páginas para abrir con Tor para el HOTSPOT + Excluir páginas + Lista de páginas para abrir directamente para HOTSPOT + Permitir compartir I2P "Establecer TTL" - "Establece el TTL a 64 usando la VPN local. No se necesita compatibilidad en el Kernel. Solo funciona en \"modo root\" con la opción \"Ejecutar Modulos como Root\" desactivada. Para que el valor tome efecto, por favor, arranca DNSCrypt y/o Tor." - "Abrir configuración de Compartir Internet" + El TTL se fijará en 64 utilizando una VPN local. No se requiere soporte de kernel. Para fijar TTL por favor inicie DNSCrypt o/y Tor. + Abrir configuración de anclaje (tethering) "Por favor, reinicie DNSCrypt" "Por favor, reinicie Tor" "Por favor, reinicie I2P" @@ -147,41 +147,39 @@ "Ejecutando comandos Root…" "Por favor, espera…" "Cambios guardados" - "AJUSTES GLOBALES" + Ajustes generales "¡Solo para usuarios avanzados!" "¡Selecciona al menos un servidor!" "Puerto local de escucha." - "Requisitos de los servidores" + Requerir servidores (de fuentes estáticas + remotas) para satisfacer propiedades específicas "Requiere servidores compatibles con el protocolo DNSCrypt" "Requiere servidores compatibles con el protocolo DNS-sobre-HTTPS" - "Requisitos de los servidores" + Requerir servidores definidos por fuentes remotas para satisfacer propiedades específicas "Requiere servidores compatibles con Extensiones de seguridad DNS (DNSSEC)." "Requiere que los servidores no registren las peticiones DNS." "Requiere que los servidores no utilicen ningún tipo de filtro (anuncios, control parental, bloqueos…) para las peticiones DNS." - "Habilitar comunicación TCP para conectar a los servidores" - "Esto es útil para redirigir todo el tráfico hacia Tor. -Si no es lo que desea, por favor, deje éste valor desactivado, ya que no mejorará en ningún aspecto el nivel de seguridad (dnscrypt-proxy siempre utiliza cifrado de extremo a extremo, incluso con UDP). Si lo activa sin verdaderamente necesitarlo únicamente obtendra un incremento en la latencia de resolución de las peticiones DNS, lo que puede derivar en un impacto en el rendimiento de la conexión." - "Proxy SOCKS" - "Activar proxy" - "Redirige todas las conexiones TCP a traves del nodo local de Tor. Tor no soporta UDP, así que active force_tcp también." - "puerto_proxy" - "Otros ajustes" - "Servidor de resolución de último recurso. Éste debe ser un servidor DNS normal, no cifrado, que se utilizará en el arranque inicial para poder resolver los nombres de la lista de servidores de la configuración de dnscrypt-proxy, y solo si la configuración de DNSs del sistema no funciona. No se usará si las listas han sido resueltas anteriormente. Personas residentes en China probablemente tengan que usar el valor 114.114.114.114:53 aquí." - "No usar el DNS obtenido por el sistema Android. Activada, ésta opción obliga siempre a usar primero el servidor de resolución de último recurso." - "FILTROS" + Utilice siempre TCP para conectarse a servidores ascendentes + Utilice TCP en lugar de UDP para conectarse a servidores DNSCrypt. Esta opción debe estar habilitada si está utilizando DNSCrypt sobre Tor. + Proxy SOCKS + Proxy saliente + Redirige todas las conexiones TCP a un proxy Socks5 entrante de Tor local. Tor no soporta UDP, así que configura Force TCP en verdadero también. + Puerto proxy + Otros ajustes + Resolutores de arranque. Este es un solucionador de DNS normal y sin cifrar, que se usa solo para solicitudes únicas para obtener la lista de solucionadores entrantes, y solo cuando la configuración de DNS del sistema no funciona. Nunca se usa una vez que las listas están en el caché. + No permita que DNSCrypt intente utilizar la configuración DNS del sistema. Utilice incondicionalmente los solucionadores Bootstrap. + Filtros "Reglas de reenvío" "Redirige peticiones para dominios específicos a un conjunto determinado de servidores." "Reglas de encubrimiento" - "Las reglas de encubrimiento proveen direcciones predefinidas para un nombre determinado. Además de actuar como un archivo HOSTS, también pueden devolver la dirección IP de un nombre diferente. También realizan tratamientos CNAME especiales…" - "Registro de peticiones" + Enmascaramiento devuelve una dirección predefinida para un nombre específico. Además de actuar como un archivo HOSTS, también puede devolver la dirección IP de un nombre diferente. También hará el aplanamiento CNAME. + Registro de consultas "Registra las peticiones de cliente a fichero." - "Activar el registro de peticiones" + Registro de consultas "Tipos de peticiones a omitir, para reducir ruido, en los registros. Un valor vacío indica registrar todo." "Abrir registro de peticiones" - "Registro de peticiones de dudosa naturaleza." - "Registrar peticiones para zonas inexistentes. -Con estas peticiones se puede descubrir la presencia de malware, aplicaciones defectuosas u obsoletas, y dispositivos revelando señales de presencia a terceros…" - "Activar registro dudoso" + Registro de solicitudes de dudosa naturaleza + Consultas de registro para zonas inexistentes. Estas consultas pueden revelar la presencia de malware, aplicaciones rotas u obsoletas, y dispositivos que señalan su presencia a terceros. + Registro solicitudes dudosas "Abrir registro dudoso" "Bloqueo basado en patrones (Lista de bloqueo)." "Lista de bloqueo" @@ -189,16 +187,16 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Bloqueo basado en patrones de direcciones IP (Lista de bloqueo de IPs)" "Lista de bloqueo de direcciones IP" "Lista de bloqueo de IPs se define por un patrón por línea." - "Permiso basado en patrones (Lista de permitidos)" + Lista blanca basada en patrones (derivación de listas negras) "Lista de permitidos" "La lista de permitidos funciona con los mismos patrones que la lista de bloqueo. Si un nombre coincide con una entrada en la lista, la correspondiente conexión pasará los filtros y/o bloqueos de nombres o IPs." "Servidores" "Fuentes" "Listas remotas de obtención de los servidores disponibles." - "La lista de fuentes se renovará en el periodo que establezca en éste ajuste, en horas." + La lista de servidores se actualizará después de la demora especificada en horas. "Retransmisores" "Fuentes" - "La lista de retransmisores se renovará en el periodo que establezca en éste ajuste, en horas." + La lista de relés se actualizará después del retraso especificado en horas. "Retransmisores DNSCrypt" "¡La preferencia no existe en la configuración de DNSCrypt!" "Borrar log" @@ -220,13 +218,13 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Número de segundos X a considerar cuando construir un nuevo circuito." "Éste valor indica la reutilización de circuitos creados hasta un número X máximo de segundos de vida." "Determina la separación obligatoria, en distintos circuitos, de conexiones hacia destinos que tengan direcciones IP demasiado cerca entre sí. Se considera que dos direcciones IP están demasiado cerca entre sí, si pertenecen al mismo rango de red /16." - "Activar proxy SOCKS5" + Poxy SOCKS "Indica el puerto donde abrir el proxy SOCKS5." - "Activar proxy HTTP" + Túnel HTTP "Indica el puerto del proxy HTTP (el proxy funciona exclusivamente con la directiva HTTP CONNECT)." - "Activar proxy transparente" + Proxy transparente "Indica el puerto donde abrir el proxy transparente." - "Activar puerto DNS" + Resolver DNS "Indica el puerto donde Tor abrirá un servidor de escucha para resolución de nombres (UDP), realizando dichas peticiones de forma anónima." "Determina el uso de IPv4 al conectar al directorio de servidores y nodos de entrada." "Determina el uso de IPv6 al conectar al directorio de servidores y nodos de entrada." @@ -240,10 +238,10 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Apps a excluir de InviZible" "Seleccionar todo" "Deshacer selección" - "Configuración general" - "Permitir conexiones entrantes" - "Puerto de escucha para conexiones entrantes." - "IP externa del router para conexiones entrantes." + Configuración general + Conexiones entrantes + Puerto de escucha para las conexiones entrantes (por defecto: auto (aleatorio)). + IP externa del router para conexiones entrantes (por defecto: auto si SSU2 está activado). "Activa comunicación IPv4." "Activa comunicacion IPv6." "Rechaza crear tuneles transitorios, desactivando totalmente el tráfico transitorio." @@ -252,7 +250,7 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Porcentaje máximo de ancho de banda para tráfico transitorio." "Activa el protocolo de transporte SSU (usa UDP)." "Activa el protocolo de transporte NTCP2 (usa TCP)." - "Activar ntcpproxy" + Proxy de salida "Especifíca el servidor proxy para NTCP. Formato http://dirección:puerto o socks://dirección:puerto." "Proxy HTTP" "Proxy HTTP" @@ -269,14 +267,13 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Criptografía" "Usa tablas preprocesadas ElGamal." "Activa o desactiva el uso de UPnP." - "Activar NTCP2" "Resiembra" - "Verifica firmas .su3." + "Verifica firmas su3." "Límites" "Establece el número máximo de túneles de tránsito. Por defecto, 2500." "Limita el numero de descriptores de archivos abiertos (0 - usa el límite del sistema)." - "Tamaño máximo del archivo principal en Kbs (0 - usa el límite del sistema)." - "Listín de direcciones" + Tamaño máximo del archivo core en Kb (0 - usar límite del sistema). + Agenda "URL de subscripción inicial para el listín." "URLs de subscripción para el listín." "¡El parámetro de configuración no existe en i2pd.conf!" @@ -310,12 +307,12 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Hay disponible una actualización para DNSCrypt. ¿Quieres descargarla y actualizar? La actualización continuará en segundo plano." "Hay disponible una actualización para Tor. ¿Quieres descargarla y actualizar? La actualización continuará en segundo plano." "Hay disponible una actualización para I2P. ¿Quieres descargarla y actualizar? La actualización continuará en segundo plano." - "Comprobando actualizaciones" - "Por favor, espera mientras comprobamos si hay actualizaciones." + Comprobando actualizaciones + Por favor, espera mientras se comprueban las actualizaciones. "El servidor de actualizaciones esta temporalmente fuera de servicio. Por favor, inténtalo de nuevo más tarde." "El servidor de actualizaciones no esta disponible." "Actualización fallida." - "No se encontraron actualizaciones." + No se encontraron actualizaciones. "Última comprobación:" "Se han encontrado actualizaciones." "La actualización se instalo correctamente." @@ -345,19 +342,17 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de El Proyecto InviZible Pro solicita su ayuda. Pulse OK para adquirir funciones premium. "Lo sentimos, pero no hemos podido verificar tu compra. Recibiras un reembolso en los próximos días (3 días, al menos)." "Lo sentimos, pero esa función solo esta disponible en la versión exclusiva." - Muchas gracias por elegir InviZible Pro. Estoy seguro de que mejorará su privacidad y le proporcionará una experiencia en línea sin problemas. -\n -\n\tInviZible Pro incluye Tor, DNSCrypt y Purple I2P como módulos. -\n -\n\tInviZible Pro puede usar root si tu dispositivo está rooteado, o usa una VPN local para entregar el tráfico de internet directamente a las redes Tor, DNSCrypt e I2P. -\n -\n\tPolítica de privacidad: -\n\tInviZible Pro no recopila ni comparte ningún dato personal o sensible del usuario. -\n -\n\tDerechos de autor © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy + + \tMuchas gracias por elegir InviZible Pro. Estoy seguro de que mejorará su privacidad y le proporcionará una experiencia en línea sin problemas. + \n\n\tInviZible Pro incluye Tor, DNSCrypt y Purple I2P como módulos. + \n\n\tInviZible Pro puede usar root si tu dispositivo está rooteado, o usa una VPN local para entregar el tráfico de internet directamente a las redes Tor, DNSCrypt e I2P. + \n\n\tPolítica de privacidad: + \n\tInviZible Pro no recopila ni comparte ningún dato personal o sensible del usuario. + \n\n\tDerechos de autor © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + "Proxy HTTP exterior" "Dirección del proxy HTTP exterior" "Proxy SOCKS exterior" @@ -400,22 +395,21 @@ Con estas peticiones se puede descubrir la presencia de malware, aplicaciones de "Se ha detectado nuevos puentes predeterminados para Tor. ¿Deseas actualizar los valores?" "Ataques de secuestro de la conexión" "Detectar envenenamiento de tablas ARP" - "Detecta si hay un intento de ataque o secuestro de DHCP o de envenenamiento de tablas ARP en una red local por Wi-Fi." + Detectar la suplantación ARP Man-in-the-Middle y los ataques DHCP fraudulentos en redes Wi-Fi. "Bloquear el acceso a Internet cuando se detecte un ataque" "La conexión a Internet se interrumpirá automáticamente mientras dure el ataque." "Proxy" "Usar proxy SOCKS5" "InviZible Pro remitirá todas las conexiones al proxy SOCKS5 indicado" "Modo de compatibilidad" - "Activalo si la conectividad se pierde en tu dispositivo con una ROM personal cuando inicias el programa." + Activalo si la conectividad se pierde en tu dispositivo con una rom personalizada cuando inicias el programa. "Activar control de scripts" - "Utiliza éste comando para controlar los módulos de la aplicación: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". -Donde 1 - arranca el módulo, y 0 - lo para." + "Utiliza éste comando para controlar los módulos de la aplicación: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Donde 1 - arranca el módulo, y 0 - lo para." "Dirección LAN IP del dispositivo" "Activa \"Establecer TTL\" y configura el dispositivo en LAN para que conecte a InviZible. Usa como router por defecto: %1$s, y como servidor DNS: %2$s." "Modo Multi-usuario" - "Busca e identifica apps de otros usuarios como apps duplicadas, duplicación MIUI, o en el perfil de trabajo, como en la app Insular." - "Activar proxy de salida SOCKS" + Soporte para aplicaciones duales, MIUI, Island, refugio y aplicaciones de perfil de trabajo. Puede ser ineficaz en modo VPN + SOCKS proxy de salida "Tor remitirá todas las conexiones OR al proxy SOCKS5 indicado." "Servicios en marcha" "Actualización de notificaciones" @@ -494,7 +488,7 @@ Donde 1 - arranca el módulo, y 0 - lo para." "IP Tor cambiando" "Ha agregado más de 3 mosaicos a la configuración rápida. Por favor, solo deje 3. Agregar más de 3 mosaicos puede causar problemas con el control de la aplicación." "Detección de suplantación DHCP" - "Detecta los intentos de suplantación DHCP en redes Wi-Fi." + Detección de ataques Man-in-the-Middle rogue DHCP en redes Wi-Fi. "Seleccionar punto de servicio de conexión" "El punto de servicio de conexion se utiliza para determinar un proxy descentralizado voluntario, así la resolución para la conexión queda encapsulada para el ISP, utilizando el punto de servicio de conexión como una suerte de servicio de resolución de solicitudes de proxies en la que está basada la tecnología WebRTC." "Ver todas las aplicaciones" @@ -529,10 +523,10 @@ Donde 1 - arranca el módulo, y 0 - lo para." Excluir UDP de Tor ¿Desactivar el ahorro de datos? Conjunto de prefijos IPv6 estáticos utilizados. - Activa esta opción si estás en una red sólo ipv6 y los sitios ipv4 dejan de estar disponibles. De lo contrario, no la actives o no podrás conectarte a nada. + Activa esta opción si estás en una red sólo Ipv6 y los sitios Ipv4 dejan de estar disponibles. De lo contrario, no la actives o no podrás conectarte a nada. Tor entra en un estado inactivo si no ve actividad de clientes durante un tiempo especificado. Debe ser de al menos 10 minutos Tor rastreará conexiones recientes a hosts e intentará reutilizar el mismo nodo de salida para cada una. Esta opción puede ayudar a evitar captchas interminables. - ¡InviZible Pro no puede iniciar %1$s! Intente restablecer la configuración de %2$s. Si esto no ayuda, reinicie el dispositivo. + ¡InviZible Pro no se puede iniciar %1$s! Intenta restablecer la configuración de %2$s. Si esto no ayuda, reinicie el dispositivo. Restablecer Falsificar SNI Las notificaciones son esenciales para mostrar información importante sobre el funcionamiento de la aplicación, el control de la aplicación y los ataques detectados. ¿Desea permitir las notificaciones para InviZible? @@ -541,4 +535,12 @@ Donde 1 - arranca el módulo, y 0 - lo para." No se utilizan relés anónimos. ↓ Tira para actualizar ↓ Mantenga pulsado para editar. + Utilice servidores que admitan el protocolo DNS sobre HTTPS de Oblivious. + ¡Bloquear esta aplicación del sistema puede provocar una conexión a Internet inestable! + Nodos + Ajustes del aislamiento + URL del proxy de salida ascendente del proxy HTTP (como http://false.i2p) + Puerta de acceso a Internet + Dirección del proxy externo (IP o local). Las solicitudes fuera de I2P irán allí. + Para activar esta opción, debe desactivar los puentes o utilizar puentes solo con puertos 80 y 443. diff --git a/tordnscrypt/src/main/res/values-fa/strings.xml b/tordnscrypt/src/main/res/values-fa/strings.xml index cce18232b..8d12a050a 100644 --- a/tordnscrypt/src/main/res/values-fa/strings.xml +++ b/tordnscrypt/src/main/res/values-fa/strings.xml @@ -67,11 +67,11 @@ "تنظیمات" "شروع خودکار" - "فعال‌سازی DNSCrypt هنگام راه‌اندازی" + فعال‌سازی DNSCrypt هنگام راه‌اندازی - "شروع TOR هنگام راه‌اندازی مجدد" + شروع TOR هنگام راه‌اندازی مجدد - "شروع I2P هنگام راه‌اندازی مجدد" + "شروع خودکار I2P" "تأخیر" شروع با تأخیر (چند ثانیه) تنها اگر شروع خودکار به درستی کار نکرد "سرورهای DNSCrypt" @@ -80,18 +80,18 @@ "تنظیمات مسیریابی" "انتقال کل ترافیک از طریق TOR" "انتقال کل ترافیک از طریق InviZible" - "انتخاب وب‌سایت‌ها" - این لیست وب سایتها با TOR باز می شوند. این ویژگی برای سایتهای پشت CDN کار نمی‌کند + انتخاب وب‌سایت‌ها + این لیست وب سایتها با TOR باز می شوند. این ویژگی برای سایت‌های پشت CDN کار نمی‌کند - "برنامه‌ها را انتخاب کنید" + برنامه‌ها را انتخاب کنید "برنامه‌هایی که با TOR می‌توان استفاده کرد" "برنامه‌هایی که با InviZible می‌توان استفاده کرد" - "محدودسازی سایت‌ها" - لیست این وب سایتها به طور مستقیم باز می شوند. این ویژگی برای سایتهای پشت CDN کار نمی‌کند - "محدود‌سازی برنامه‌ها" + محدودسازی سایت‌ها + لیست این وب سایت‌ها به طور مستقیم باز می‌شوند. این ویژگی برای سایت‌های پشت CDN کار نمی‌کند + محدود‌سازی برنامه‌ها "برنامه‌هایی که مستقیم اجرا شوند" - "بازخوانی Interval" - "تعداد دفعات بازخوانی IPهای وب‌سایت‌ها در یک ساعت (فقط اندورید ۵.۱ به بالا). برای توقف بازخوانی عدد صفر را وارد کنید." + بازخوانی Interval + تعداد دفعات بازخوانی IPهای وب‌سایت‌ها در یک ساعت (فقط اندورید ۵.۱ به بالا). برای توقف بازخوانی عدد صفر را وارد کنید. "پل‌ها" "از این مورد تنها اگر نمی‌توانید به TOR متصل شوید استفاده کنید" "عدم استفاده از پل" @@ -109,14 +109,14 @@ "ذخیره" "بستن" "نام HOST اشتباه است!" - "انتخاب قالب" - "انتخاب زبان" + انتخاب قالب + انتخاب زبان "مسدودسازی HTTP" "مسدودسازی ارتباط با HTTP Port 80" "بروزرسانی" - "بروزرسانی خودکار" - "بروزرسانی‌های InviZible Pro و ماژول‌ها را روزانه بررسی کنید" - "بررسی بروزرسانی" + بروزرسانی خودکار + بروزرسانی‌های InviZible Pro و ماژول‌ها را روزانه بررسی کنید + بررسی بروزرسانی "بررسی کنید نسخه‌های جدید اکنون موجود هستند یا خیر" "مؤکداً انجام بروزرسانی‌ها از طریق TOR" "فقط از طریق TOR و هنگام فعال بودن TOR، بروزرسانی‌ها را بررسی کنید" @@ -126,31 +126,31 @@ "دیگر" "مسدود کردن HTTP هات‌اسپات" "مسدودسازی ارتباط به HTTP Port 80 برای هات اسپات" - "محافظت از برنامه‌ها در حالت بدون Root برای جلوگیری از بسته شدن برنامه توسط اندروید" + محافظت از برنامه‌ها در حالت بدون Root برای جلوگیری از بسته شدن برنامه توسط اندروید "تازه کردن قوانین" "بروزرسانی قوانین برای هر تغییر اتصال" "نمایش اعلان‌ها" "جلوگیری از به خواب رفتن دستگاه" حفاظت بیش‌تر بدون حالت Root برای جلوگیری از توقف برنامه توسط اندروید. ممکن است باعث تخلیه زودتر باتری شود "راهنمایی‌ها" - "همیشه پیغام‌های راهنما را نشان بده" + همیشه پیغام‌های راهنما را نشان بده لطفا InviZible Pro را در بهینه‌سازی باتری دستگاه قرار ندهید‌. در غیر این صورت، ممکن است اندروید DNSCrypt و TOR و یا I2P را در هر زمان خاموش کند. در بعضی سیستم عامل‌های استثناء همانند سیستم عامل گوشی‌های شیائومی باید چند گام اضافه. "انتخاب BusyBox" "هات اسپات-آزمایشی" - "شروع Tethering هنگام راه‌اندازی مجدد" - "تور مجاز به Tethering است" + شروع Tethering هنگام راه‌اندازی مجدد + تور مجاز به Tethering است "تعیین مسیر تمام فعالیت‌ها از طریق TOR" "تعیین مسیر تمام ترافیک ورودی از طریق TOR" - "انتخاب وب‌سایت‌ها" - "لیست وب‌سایت‌ها به‌منظور باز شدن همراه با TOR برای هات اسپات" - "محدود‌سازی وب‌سایت‌ها" - "لیست وب‌سایت‌ها به‌منظور باز شدن خودکار برای هات اسپات" - "اجازه دادن به Tethering I2p" + انتخاب وب‌سایت‌ها + لیست وب‌سایت‌ها به‌منظور باز شدن همراه با TOR برای هات اسپات + محدود‌سازی وب‌سایت‌ها + لیست وب‌سایت‌ها به‌منظور باز شدن خودکار برای هات اسپات + اجازه دادن به Tethering I2p "رفع مشکل TTL" - "TTL از طریق VPN محلی بر روی 64 ثابت خواهد شد. به پشتیبانی از Kernel نیاز نیست. -این مورد تنها در \"حالت روت\" همراه با غیرفعال بودن گزینه \"اجزای ماژول‌ها همراه با روت\" می‌تواند استفاده شود. -برای رفع مشکل TTL لطفاً DNSCrypt و یا TOR را راه‌اندازی نمایید." - "باز کردن تنظیمات Tethering" + TTL از طریق VPN محلی بر روی 64 ثابت خواهد شد. به پشتیبانی از Kernel نیاز نیست. +\nاین مورد تنها در \"حالت روت\" همراه با غیرفعال بودن گزینه \"اجزای ماژول‌ها همراه با روت\" می‌تواند استفاده شود. +\nبرای رفع مشکل TTL لطفاً DNSCrypt و یا TOR را راه‌اندازی نمایید. + باز کردن تنظیمات Tethering "لطفاً DNSCrypt را مجدداً راه‌اندازی کنید" "لطفا TOR را مجدداً راه‌اندازی نمایید" "لطفا l2P را مجدداً راه‌اندازی نمایید" @@ -255,11 +255,11 @@ "برنامه‌هایی برای میانبر InviZible" "انتخاب همه" "پاک کردن موارد انتخاب شده" - "تنظیمات عمومی" - "اجازه دادن به اتصالات ورودی" + تنظیمات عمومی + اجازه دادن به اتصالات ورودی - "پورت برای شنود اتصالات ورودی." - "آی پی خارجی روتر برای اتصالات ورودی." + پورت برای شنود اتصالات ورودی. + آی پی خارجی روتر برای اتصالات ورودی. فعال کردن ارتباط از طریق IPv4. فعال کردن ارتباط از طریق IPv6. "روتر تونل‌های ترانزیت را نپذیرفته، و ترافیک ترانزیت را کاملاً غیرفعال کرده است." @@ -268,7 +268,7 @@ "حداکثر ٪ از پهنای باند برای انتقال. 0-100." "فعال کردن پروتکل انتقال SSU (استفاده از UDP)." "فعال کردن پروتکل NTCP2 (استفاده از TCP)." - "فعال کردن ntcpproxy" + فعال کردن ntcpproxy "سرور پروکسی را برای NTCP مشخص کنید. باید http://address:port یا socks://address:port باشد." "پروکسی HTTP" "پروکسی HTTP" @@ -285,14 +285,13 @@ "رمزنگاری" "از جداول از پیش محاسبه شده ElGamal استفاده کنید." "فعال‌کردن یا غیرفعال‌کردن UPnP." - "ntcp2 فعال شد" در حال تحقیق - "امضای su3. را تأیید کنید." + امضای su3. را تأیید کنید. "محدودیت‌ها" "حداکثر تعداد تونل‌های ترانزیت را نادیده بگیرید. 2500 به‌صورت پیش‌فرض." "تعداد توصیف‌کننده‌های فایل باز (صفر - استفاده از محدودیت سیستم) محدود کنید." - "حداکثر اندازه فایل اصلی در واحد Kb (صفر - استفاده از محدودیت سیستم)." + حداکثر اندازه فایل اصلی در واحد Kb (صفر - استفاده از محدودیت سیستم). دفترچه آدرس "URL اشتراک کتابچه آدرس برای تنظیم اولیه." @@ -332,12 +331,12 @@ "آپدیت DNSCrypt در دسترس است. آیا می‌خواهید آن را دانلود و آپدیت نمایید؟ آپدیت در پس‌زمینه ادامه خواهد داشت." "آپدیت TOR در دسترس است. آیا می‌خواهید آن را دانلود و آپدیت نمایید؟ آپدیت در پس‌زمینه ادامه خواهد داشت." "آپدیت Purple I2P در دسترس است. آیا می‌خواهید آن را دانلود و آپدیت نمایید؟ آپدیت در پس‌زمینه ادامه خواهد داشت." - "در حال چک کردن بروزرسانی" - "لطفاً در هنگام بررسی وجود بروزرسانی‌ها صبر نمایید." + در حال چک کردن بروزرسانی + لطفاً در هنگام بررسی وجود بروزرسانی‌ها صبر نمایید. "سرور بروزرسانی موقتاً در دسترس نمی‌باشد. لطفاً بعداً سعی نمایید." "سرور بروزرسانی در دسترس نمی‌باشد." "آپدیت با خطا مواجه شد." - "بروزرسانی یافت نشد." + بروزرسانی یافت نشد. "آخرین بررسی:" "بروزرسانی یافت شد." "بروزرسانی نصب شد." @@ -411,7 +410,7 @@ "پل‌های پیش فرض جدید TOR موجود است. آیا می خواهید آنها را به روز کنید؟" "تشخیص حمله MITM" "تشخیص کلاهبرداری ARP" - "کلاهبرداری ARP در مرکز و حملات ظالمانه DHCP در شبکه های Wi-Fi را شناسایی کنید." + کلاهبرداری ARP در مرکز و حملات ظالمانه DHCP در شبکه های Wi-Fi را شناسایی کنید. "با شناسایی حمله اینترنت را مسدود کنید" "اتصال اینترنت در هنگام حمله مسدود خواهد شد" "پروکسی" @@ -424,7 +423,7 @@ "آدرس IP دستگاه LAN" "مشکل TTL را برطرف کرده و دستگاه LAN را برای اتصال به InviZible پیکربندی کنید. از درگاه پیش فرض استفاده کنید: %2$s، دی‌ان‌اس سرور: %1$s." "پشتیبانی از چند کاربر" - "پشتیبانی از برنامه‌های دوتایی، MIUI، جزیره، پناهگاه و برنامه‌های نمایه‌کاری" + پشتیبانی از برنامه‌های دوتایی، MIUI، جزیره، پناهگاه و برنامه‌های نمایه‌کاری "پراکسی خروجی SOCKS را فعال کنید" "تور تمام ارتباطات OR را از طریق پروکسی SOCKS 5 برقرار می کند." "خدمات در حال اجرا" @@ -516,4 +515,20 @@ \ninvizible.soft@gmail.com \ninvizible.net/en/privacy شما بیش از 3 موزاییک جهت اتصال سریع اضافه کردی، خواهشا سه تاش کن. بیش از 3 تا بندازی باعث اختلال در عملکرد اپ میشه. - \ No newline at end of file + بعدا بپرس + خودکار + بهینه‌سازی مصرف باتری متوقف شود؟ + ذخیره دیتا شبکه غیرفعال شود؟ + استفاده از دستگاه BusyBox + استفاده از برنامه BusyBox + از BusyBox استفاده نکن. + پل IPv6 + مسدود کردن اینترنت زمانی که Tor, DNSCrypt و Purple I2P متوقف هستند. + گزارش لحظه‌ای + مستثنی کردن از Tor + مسیر به Tor + مستثنی کردن UDP از TOR + مستثنی کردن به طور کامل + "لطفا اجازه فعال شدن background data usage و data usage را هنگامی که ذخیره دیتا روشن است بدهید.این مورد برای تجربه کاربری بهتر مورد نیاز است." + نمایش گزارش‌های ارتباط برنامه در تب DNS + diff --git a/tordnscrypt/src/main/res/values-fi/strings.xml b/tordnscrypt/src/main/res/values-fi/strings.xml index d205dfbf9..81a192908 100644 --- a/tordnscrypt/src/main/res/values-fi/strings.xml +++ b/tordnscrypt/src/main/res/values-fi/strings.xml @@ -58,9 +58,9 @@ "Valitse varmuuskopion kansio:" "Asetukset" "Automaattinen käynnistys" - "Käynnistä DNSCrypt boottauksessa" - "Käynnistä Tor boottauksessa" - "Käynnistä I2P boottauksessa" + Käynnistä DNSCrypt boottauksessa + Käynnistä Tor boottauksessa + Käynnistä I2P boottauksessa "Viive" "Käytä viivettä (sekuntina) vain, jos automaattinen käynnistys ei toimi oikein" "DNSCrypt palvelimet" @@ -69,17 +69,17 @@ "Reititys asetukset" "Ohjaa kaikki traffikki Tor:in kautta" "Ohjaa kaikki traffikki InviZiblen kautta" - "Valitse nettisivustot" - "Tor:lla avattava nettisivustolista. Tämä ominaisuus ei toimi CDN:n takana olevissa sivustoissa." - "Valitse sovellukset" + Valitse nettisivustot + Tor:lla avattava nettisivustolista. Tämä ominaisuus ei toimi CDN:n takana olevissa sivustoissa. + Valitse sovellukset "Tor:ia käyttävä sovelluslista." "InviZible:ä käyttävä sovelluslista." - "Hylkää nettisivustot" - "Suoraan avattavat nettisivustot. Tämä ominaisuus ei toimi CDN:n takana olevissa sivustoissa." - "Hylkää sovellukset" + Hylkää nettisivustot + Suoraan avattavat nettisivustot. Tämä ominaisuus ei toimi CDN:n takana olevissa sivustoissa. + Hylkää sovellukset "Suoraan avattava sovelluslista" - "Päivitä intervalli" - "Verkkosivustojen IP:ien päivittämisaika tunteina. Android 5.1 tai uudempi. Laita 0 pysäyttääksesi päivityksen." + Päivitä intervalli + Verkkosivustojen IP:ien päivittämisaika tunteina. Android 5.1 tai uudempi. Laita 0 pysäyttääksesi päivityksen. "Sillat" "Käytä sitä, jos et voi yhdistyä Tor verkkoon." "Älä käytä siltoja" @@ -97,14 +97,14 @@ "Tallenna" "Sulje" "Väärä hostin nimi!" - "Valitse teema" - "Valitse kieli" + Valitse teema + Valitse kieli "Estä http" "Estä yhteys http-porttiin 80" "Päivitä" - "Automaattiset päivitykset" - "Tarkista InviZible Pro:n ja moduulejen päivitykset päivittäin" - "Tarkista päivitys" + Automaattiset päivitykset + Tarkista InviZible Pro:n ja moduulejen päivitykset päivittäin + Tarkista päivitys "Tarkista, jos uusia versioita on saatavilla nyt" "Päivitä pelkästään Tor:in kautta" "Tarkista päivityksiä vain Tor:lla ja kun se on päällä" @@ -114,33 +114,29 @@ "Muut" "Estä HOTSPOT http" "Estä yhteys HOTSPOT http-porttiin 80" - "Suojaa sovellus No Root Modella, jotta android ei sulje sovellusta" + Suojaa sovellus No Root Modella, jotta android ei sulje sovellusta "Päivitä säännöt" "Päivitä säännöt jokaisella yhteyden muutoksella" "Näytä ilmoitus" "Estä laitetta menemästä lepotilaan" - "Lisäsuojaus ilman Root-tilaa, jotta android ei sulje sovellusta. Saattaa tyhjentää akkua" + Lisäsuojaus ilman Root-tilaa, jotta android ei sulje sovellusta. Saattaa tyhjentää akkua "Ohjeviestit" - "Näytä ohjeviestit aina" - "Ota InviZible Pro pois Android-akun optimoinnista. -\n Muuten android sulkee DNSCryptin, Tor:in tai I2P:n milloin tahansa. Erityisissä järjestelmissä, -\n kuten MIUI, vaati joitain lisävaiheita." + Näytä ohjeviestit aina + "Ota InviZible Pro pois Android-akun optimoinnista. Muuten android sulkee DNSCryptin, Tor:in tai I2P:n milloin tahansa. Erityisissä järjestelmissä, kuten MIUI, vaati joitain lisävaiheita." "Valitse BusyBox" "Kokeellinen-HOTSPOT" - "Aloita tethering käynnistyksessä" - "Salli Tor tethering" + Aloita tethering käynnistyksessä + Salli Tor tethering "Ohjaa kaikki Tor:in kautta" "Ohjaa kaikki tuleva traffikki Tor:in kautta" - "Valitse nettisivustot" - "Nettisivustolista, joka avataan Tor HOTSPOTTIIN" - "Hylkää nettisivustot" - "Nettisivustolista, joka avataan suoraan HOTSPOTTIIN" - "Salli I2P tethering" + Valitse nettisivustot + Nettisivustolista, joka avataan Tor HOTSPOTTIIN + Hylkää nettisivustot + Nettisivustolista, joka avataan suoraan HOTSPOTTIIN + Salli I2P tethering "Korjaa TTL" - "TTL tullaan korjaamaan 64:n käyttämällä paikallista VPN:nää. Kernelitukea ei tarvita. - Sitä voidaan käyttää vain \"Root tilassa\", kun \"Suorita moduulit rootilla\" -asetus on poistettu käytöstä. - Korjaa TTL käynnistämällä DNSCrypt tai / ja Tor." - "Avaa tethering config" + "TTL tullaan korjaamaan 64:n käyttämällä paikallista VPN:nää. Kernelitukea ei tarvita. Sitä voidaan käyttää vain \"Root tilassa\", kun \"Suorita moduulit rootilla\" -asetus on poistettu käytöstä. Korjaa TTL käynnistämällä DNSCrypt tai / ja Tor." + Avaa tethering config "Käynnistä DNSCrypt uudelleen" "Käynnistä Tor uudelleen" "Käynnistä I2P uudelleen" @@ -162,36 +158,26 @@ "Palvelin ei saa kirjata käyttäjän kyselyjä (deklaratiivinen)." "Palvelin ei saa valvoa omaa blacklistiä (Vanhempien valvontaa varten, mainosten esto)." "Käytä aina TCP:tä yhteyden muodostamiseen ylävirran (upstream) palvelimiin." - "Tästä voi olla hyötyä, jos joudut reitittämään kaiken Tor:in läpi. - - Muussa tapauksessa jätä tämä vääriksi (False), koska se ei paranna turvallisuutta (DNSCrypt-proxy salaa kaiken jopa UDP:tä käytettäessä), ja se voi vain lisätä viivettä." + "Tästä voi olla hyötyä, jos joudut reitittämään kaiken Tor:in läpi. Muussa tapauksessa jätä tämä vääriksi (False), koska se ei paranna turvallisuutta (DNSCrypt-proxy salaa kaiken jopa UDP:tä käytettäessä), ja se voi vain lisätä viivettä." "HTTP / SOCKS proxy (välityspalvelin)" "Ota proxy käyttöön." - "Reititä kaikki TCP-yhteydet paikalliseen Tor-solmuun. (Tor node) - Tor ei tue UDP:tä, joten laita force_tcp päälle myös." + "Reititä kaikki TCP-yhteydet paikalliseen Tor-solmuun. (Tor node) Tor ei tue UDP:tä, joten laita force_tcp päälle myös." "Proxy_portti" "Muut asetukset" - "Varaehtoinen resolveri. - Tämä on normaali, salaamaton DNS-ratkaisu, jota käytetään vain yhden kuvan kyselyihin (one-shot queries) - noudettaessa alkuperäisiä resolveri-listaa vain, jos järjestelmän DNS-määritykset eivät toimi. - Sitä ei koskaan käytetä, jos luettelot on jo välimuistissa. - Kiinassa asuvien on ehkä käytettävä tätä numeroa 114.114.114.114:53." + "Varaehtoinen resolveri. Tämä on normaali, salaamaton DNS-ratkaisu, jota käytetään vain yhden kuvan kyselyihin (one-shot queries) noudettaessa alkuperäisiä resolveri-listaa vain, jos järjestelmän DNS-määritykset eivät toimi. Sitä ei koskaan käytetä, jos luettelot on jo välimuistissa." "Älä koskaan anna dnscrypt-proxy:n yrittää käyttää järjestelmän DNS-asetuksia. Muuten käytä varaehtoista resolveria..." "SUODATUKSET" "Forwarding rules" "Reititä tiettyjen verkkotunnusten kyselyt omistettuun palvelinjoukkoon." "Cloaking rules" - "Naamiointi palauttaa tietyn nimen ennalta määritetyn osoitteen. - - Sen lisäksi, että se toimii HOSTS-tiedostona, se voi myös palauttaa IP-osoitteen toisella nimellä. Se tekee myös CNAME-tasoitusta" + "Naamiointi palauttaa tietyn nimen ennalta määritetyn osoitteen. Sen lisäksi, että se toimii HOSTS-tiedostona, se voi myös palauttaa IP-osoitteen toisella nimellä. Se tekee myös CNAME-tasoitusta" "Kyselyloki." "Tallenna asiakkaan(clientin) kyselyt tiedostoon." "Ota kyselyloki käyttöön" "Älä kirjaa näitä kyselytyyppejä vähentääksesi verbiittisuutta. Pidä tyhjänä kirjataksesi kaiken lokiin." "Avaa kyselyloki" "Epäilyttävien kysymysten kirjaaminen." - "Tallenna kyselyt puuttuville vyöhykkeille lokiin. - Nämä kyselyt voivat paljastaa haittaohjelmia, rikkoutuneita / vanhentuneita sovelluksia ja laitteita, jotka ilmoittavat niiden olemassaolosta kolmansille osapuolille..." + "Tallenna kyselyt puuttuville vyöhykkeille lokiin. Nämä kyselyt voivat paljastaa haittaohjelmia, rikkoutuneita / vanhentuneita sovelluksia ja laitteita, jotka ilmoittavat niiden olemassaolosta kolmansille osapuolille..." "Ota epäilyttävä kirjaaminen käyttöön" "Avaa epäilyttävä loki" "Kuviopohjainen estäminen (Musta lista)." @@ -251,10 +237,10 @@ "InviZible:n ohittavat sovellukset" "Valitse kaikki" "Poista valinta" - "Yleiset asetukset" - "Salli saapuvat yhteydet" - "Portti kuuntelemaan tulevia yhteyksiä." - "Reitittimen ulkoinen IP tuleville yhteyksille." + Yleiset asetukset + Salli saapuvat yhteydet + Portti kuuntelemaan tulevia yhteyksiä. + Reitittimen ulkoinen IP tuleville yhteyksille. "Ota yhteys IPv4:n kautta." "Ota yhteys IPv6:n kautta." "Reititin ei hyväksy kauttakulkutunneleita, poistamalla kuljetusliikenne kokonaan käytöstä." @@ -263,7 +249,7 @@ "Enimmäis % kaistanleveysrajoituksesta siirtämiseen. 0-100." "Ota SSU-siirtoprotokolla käyttöön (käytä UDP:tä)." "Ota NTCP2-siirtoprotokolla käyttöön (käytä TCP:tä)." - "Ota ntcpproxy käyttöön" + Ota ntcpproxy käyttöön "Määritä proxy NTCP:lle. Pitäisi olla http: // osoite: portti tai socks: // osoite: portti." "HTTP proxy" "HTTP proxy" @@ -280,26 +266,22 @@ "Salaustekniikka" "Käytä ElGamalin esikomputoituja taulukoita." "Ota UPnP käyttöön tai poista se käytöstä." - "ntcp2 käytössä" "Reseeding" - "Varmista .su3-allekirjoitus." + "Varmista su3-allekirjoitus." "Rajat" "Ohita kauttakulun tunnelien enimmäismäärä. 2500 oletuksena." "Rajoita avoimien tiedostokuvausten lukumäärä (0 - käytä järjestelmän rajaa)." - "Ydintiedoston enimmäiskoko (kt) (0 - järjestelmän käyttöraja)." - "Addressbook" + Ydintiedoston enimmäiskoko (kt) (0 - järjestelmän käyttöraja). + Addressbook "Osoitekirjan (AddressBook) tilauksen URL-osoite alkuasetuksia varten." "Osoitekirjatilausten (AddressBook) URL-osoitteet." "Preferenssiä ei ole i2pd.conf!" "Tietoja" - "Näyttää siltä, ​​että android-järjestelmä sulki DNSCryptin. - Internet-yhteytesi palautettiin. Tarkista laitteen asetukset!" - "Näyttää siltä, ​​että android-järjestelmä sulki Tor:in. - Internet-yhteytesi palautettiin. Tarkista laitteen asetukset!" + "Näyttää siltä, ​​että android-järjestelmä sulki DNSCryptin. Internet-yhteytesi palautettiin. Tarkista laitteen asetukset!" + "Näyttää siltä, ​​että android-järjestelmä sulki Tor:in. Internet-yhteytesi palautettiin. Tarkista laitteen asetukset!" "Näyttää siltä, ​​että android-järjestelmä sulki I2P:n. Tarkista laitteen asetukset!" "Näyttää siltä, ​​että DNSCrypt EI voi muodostaa yhteyttä Internetiin." - "Näyttää siltä, ​​että Tor EI voi muodostaa yhteyttä Internetiin. - Internet-palveluntarjoaja voi/saattaa estää Tor-yhteydet. Voit yrittää käyttää torisiltoja. Löydä ne valikosta MENU -> Pika-asetukset -> Sillat" + "Näyttää siltä, ​​että Tor EI voi muodostaa yhteyttä Internetiin. Internet-palveluntarjoaja voi/saattaa estää Tor-yhteydet. Voit yrittää käyttää torisiltoja. Löydä ne valikosta MENU -> Pika-asetukset -> Sillat" "Lapsilukko" "Voit lukita tämän sovelluksen hallinnan. Anna salasana tai käytä edellistä." "Anna salasana." @@ -324,12 +306,12 @@ "DNSCrypt-päivitys on saatavana. Haluatko ladata ja päivittää sen? Päivitys jatkuu taustalla." "Tor-päivitys on saatavana. Haluatko ladata ja päivittää sen? Päivitys jatkuu taustalla." "Purple I2P -päivitys on saatavana. Haluatko ladata ja päivittää sen? Päivitys jatkuu taustalla." - "Tarkistetaan päivityksiä" - "Odota, kun tarkistamme päivityksiä." + Tarkistetaan päivityksiä + Odota, kun tarkistamme päivityksiä. "Päivityspalvelin ei ole väliaikaisesti käytettävissä. Yritä uudelleen myöhemmin." "Päivityspalvelin ei ollut käytettävissä." "Päivitys vika." - "Päivityksiä ei löydetty." + Päivityksiä ei löydetty. "Viimeinen tarkistus:" "Päivityksiä löytyi." "Päivitykset asennettiin." @@ -388,8 +370,7 @@ "Tuo sallittujen luettelo (valkoinen lista)" "Tuo verkkotunnusluettelo. Voit valita useita tiedostoja, kaksoisrivit poistetaan." "Poista sallittujen luettelo (valkoinen lista)" - "Vastaa heti IPv6-kyselyihin tyhjällä vastauksella. - Tämä nopeuttaa asioita, kun IPv6-yhteyttä ei ole, mutta voi myös aiheuttaa luotettavuusongelmia joihinkin tynkäratkaisureihin." + "Vastaa heti IPv6-kyselyihin tyhjällä vastauksella. Tämä nopeuttaa asioita, kun IPv6-yhteyttä ei ole, mutta voi myös aiheuttaa luotettavuusongelmia joihinkin tynkäratkaisureihin." "Poista \"Yksityinen DNS\" käytöstä Android-verkkoasetuksissa. Tämä vaihtoehto häiritsee DNSCryptia." "Tuo sännöt" "Odota ... %d -sääntöä tuotu." @@ -402,22 +383,20 @@ "New default Tor bridges are available. Do you want to update them?" "MITM attack detection" "ARP spoofing detection" - "Detect Man-in-the-middle ARP spoofing and rogue DHCP attacks in Wi-Fi networks." + Detect Man-in-the-middle ARP spoofing and rogue DHCP attacks in Wi-Fi networks. "Block internet when an attack is detected" "Internet connection will be blocked during attack" "Proxy" "Use socks5 proxy" "InviZible Pro will make all connections through the SOCKS5 proxy" "Compatibility mode" - "Enable if your device with a custom ROM and the connection is lost when you press the START button" + Enable if your device with a custom ROM and the connection is lost when you press the START button "Enable script control" - "Use the following command to manage application modules: - \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL - --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module." + "Use the following command to manage application modules: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module." "LAN device IP address" "Enable Fix TTL and configure LAN device to connect to InviZible. Use default gateway: %1$s, DNS server: %2$s." "Multi-user support" - "Support for Dual Apps, MIUI, Island, Shelter and Work profile applications" + Support for Dual Apps, MIUI, Island, Shelter and Work profile applications "Enable SOCKS output proxy" "Tor will make all OR connections through the SOCKS 5 proxy." "Running services" @@ -442,8 +421,7 @@ "Successful connection. Ping %s ms." "ARP spoofing detected!" "Rogue DHCP detected!" - "Man-in-the-middle attack detected! Your data can be intercepted by another device on the local network. - Turn off, wait a few seconds, and turn on Wi-Fi. Using current Wi-Fi hotspot may be unsafe!" + "Man-in-the-middle attack detected! Your data can be intercepted by another device on the local network. Turn off, wait a few seconds, and turn on Wi-Fi. Using current Wi-Fi hotspot may be unsafe!" "ARP spoofing detection is not supported for your device!" "Please disable Entry Nodes in Tor Settings, otherwise you cannot use Bridges." "Bypass LAN addresses" @@ -498,7 +476,7 @@ "Tor IP changing" "You have added more than 3 tiles to Quick Settings. Please leave only 3. Adding more than 3 tiles can cause issues with app control." "Rogue DHCP detection" - "Detect Man-in-the-middle rogue DHCP attacks in Wi-Fi networks." + Detect Man-in-the-middle rogue DHCP attacks in Wi-Fi networks. "Select rendezvous" "Hides the broker's domain name from the Internet provider. The broker is used to establish a connection." "Show all apps" diff --git a/tordnscrypt/src/main/res/values-fr/strings.xml b/tordnscrypt/src/main/res/values-fr/strings.xml index 9a3a4a2f8..74b9903c8 100644 --- a/tordnscrypt/src/main/res/values-fr/strings.xml +++ b/tordnscrypt/src/main/res/values-fr/strings.xml @@ -58,9 +58,9 @@ "Choisissez le dossier de sauvegarde:" "Paramètres" "Démarrage automatique" - "Lancer DNSCrypt au démarrage" - "Lancer Tor au démarrage" - "Lancer I2P au démarrage" + Lancer DNSCrypt au démarrage + Lancer Tor au démarrage + Lancer I2P au démarrage "Délai" "Utiliser un délai (en secondes) uniquement si le démarrage automatique ne fonctionne pas correctement" "Serveurs DNSCrypt" @@ -69,17 +69,17 @@ "Paramètres de Routage" "Acheminer tout le trafic via Tor" "Acheminer tout le trafic via InviZible" - "Sélectionner les sites web" - "Liste des Sites Web à ouvrir avec Tor. Cette fonctionnalité est inutilisable pour les sites situés derrière un CDN" - "Sélectionner les applications" + Sélectionner les sites web + Liste des Sites Web à ouvrir avec Tor. Cette fonctionnalité est inutilisable pour les sites situés derrière un CDN + Sélectionner les applications "Liste des applications à utiliser avec Tor" "Liste des applications à utiliser avec InviZible" - "Exclure des sites Web" - "Liste des sites Web à ouvrir directement" - "Exclure des Applications" + Exclure des sites Web + Liste des sites Web à ouvrir directement + Exclure des Applications "Liste d'applications à ouvrir directement" - "Intervalle de Rafraîchissement" - "Durée en heures entre chaque actualisation des adresses IP des sites Web. Pour Android 5.1 et supérieur. Mettez 0 pour empêcher le rafraîchissement." + Intervalle de Rafraîchissement + Durée en heures entre chaque actualisation des adresses IP des sites Web. Pour Android 5.1 et supérieur. Mettez 0 pour empêcher le rafraîchissement. "Passerelles" "Utilisez-le si vous ne pouvez pas vous connecter au réseau Tor" "Ne pas utiliser de passerelles" @@ -97,14 +97,14 @@ "Sauvegarder" "Fermer" "nom d'hôte erroné!" - "Sélectionner un Thème" - "Sélectionner une Langue" + Sélectionner un Thème + Sélectionner une Langue "Bloquer l'http" "Refuser la connexion au port http 80" "Mise à Jour" - "Mise à Jours automatique" - "Vérifier quotidiennement les versions d'InviZible Pro et de ses modules" - "Vérifier les Mise à Jours" + Mise à Jours automatique + Vérifier quotidiennement les versions d\'InviZible Pro et de ses modules + Vérifier les Mise à Jours "Vérifier immédiatement si de nouvelles versions sont disponibles" "Mettre à jour uniquement via Tor" "Vérifier les mises à jour uniquement via Tor et lorsque Tor est en fonctionnement" @@ -114,33 +114,29 @@ "Autre" "Bloquer l'http sur les POINTS D'ACCÈS" "Refuser la connexion au port http 80 sur les POINTS D'ACCÈS" - "Protéger l'application en fonctionnant sans Privilèges pour éviter que l'application ne soit tuée par Android" + Protéger l\'application en fonctionnant sans Privilèges pour éviter que l\'application ne soit tuée par Android "Rafraîchir les règles" "Mettre à jour les règles à chaque changement de connectivité" "Afficher la notification" "Empêcher la mise en veille de l'appareil" - "Protection additionnel du mode sans Privilèges pour éviter que l'application ne soit tuée par le système. Peut décharger la batterie" + Protection additionnel du mode sans Privilèges pour éviter que l\'application ne soit tuée par le système. Peut décharger la batterie "Messages d'aide" - "Toujours afficher les messages d'aide" - "Veuillez exclure InviZible Pro de l\'optimisation de la batterie d\'Android. -\n Sinon, le système tuera les services DNSCrypt, Tor ou I2P à n\'importe quel moment. Sur les systèmes spécifiques, -\n comme MIUI, cela nécessite quelques mesures supplémentaires" + Toujours afficher les messages d\'aide + "Veuillez exclure InviZible Pro de l\'optimisation de la batterie d\'Android. Sinon, le système tuera les services DNSCrypt, Tor ou I2P à n\'importe quel moment. Sur les systèmes spécifiques, comme MIUI, cela nécessite quelques mesures supplémentaires" "Sélectionnez BusyBox" "POINT D'ACCÈS-Expérimental" - "Commencer le partage de connexion au démarrage" - "Autoriser l'utilisation du partage de connexion par Tor" + Commencer le partage de connexion au démarrage + Autoriser l\'utilisation du partage de connexion par Tor "Acheminer tout via Tor" "Acheminer tout le trafic entrant via Tor" - "Sélectionner les Sites Web" - "Liste des sites web à ouvrir avec Tor via un POINT D'ACCÈS" - "Exclure les Sites Web" - "Liste des sites web à ouvrir directement via un POINT D'ACCÈS" - "Autoriser le partage de connexion I2P" + Sélectionner les Sites Web + Liste des sites web à ouvrir avec Tor via un POINT D\'ACCÈS + Exclure les Sites Web + Liste des sites web à ouvrir directement via un POINT D\'ACCÈS + Autoriser le partage de connexion I2P "Fixer la DDV" - "La DDV sera fixé à 64 en utilisant un VPN local. Le support du noyau n'est pas nécessaire. - Il ne peut être utilisé qu'en \"mode administrateur\" avec l'option \"Exécuter les modules avec les Privilèges Administrateurs\" désactivée. - Pour modifier la DDV, veuillez lancer DNSCrypt et/ou Tor." - "Ouvrir la configuration du Partage de connexion" + "La DDV sera fixé à 64 en utilisant un VPN local. Le support du noyau n'est pas nécessaire. Il ne peut être utilisé qu'en \"mode administrateur\" avec l'option \"Exécuter les modules avec les Privilèges Administrateurs\" désactivée. Pour modifier la DDV, veuillez lancer DNSCrypt et/ou Tor." + Ouvrir la configuration du Partage de connexion "Veuillez redémarrer DNSCrypt" "Veuillez redémarrer Tor" "Veuillez redémarrer I2P" @@ -162,34 +158,26 @@ "Le serveur ne doit pas enregistrer les requêtes des utilisateurs (déclaratif)." "Le serveur ne doit pas appliquer sa propre liste noire (pour le contrôle parental, le blocage des publicités...)." "Utilisez toujours le protocole TCP pour vous connecter aux serveurs en amont." - " Cela peut être utile si vous avez besoin de tout faire passer par Tor. - Sinon, laissez cela sur faux (false), car cela n'améliore pas la sécurité (dnscrypt-proxy chiffrera toujours tout, même en utilisant l'UDP), et ne peut qu'augmenter la latence." + " Cela peut être utile si vous avez besoin de tout faire passer par Tor. Sinon, laissez cela sur faux (false), car cela n'améliore pas la sécurité (dnscrypt-proxy chiffrera toujours tout, même en utilisant l'UDP), et ne peut qu'augmenter la latence." "Mandataire SOCKS." "Activer le mandataire" - "Router toutes les connexions TCP vers un noeud Tor local. - Tor ne supporte pas l'UDP, donc réglez force_tcp sur vrai (true) également." + "Router toutes les connexions TCP vers un noeud Tor local. Tor ne supporte pas l'UDP, donc réglez force_tcp sur vrai (true) également." "port_proxy" "Autres Réglages." - "Résolveur de secours. - Il s'agit d'un résolveur DNS normal, non chiffré, qui ne sera utilisé que pour des requêtes ponctuelles - lors de la récupération de la liste initiale des résolveurs, et seulement si la configuration DNS du système ne fonctionne pas. - Il ne sera jamais utilisé si les listes ont déjà été mises en cache. - Les personnes en Chine peuvent avoir besoin d'utiliser 114.114.114.114:53 ici." + "Résolveur de secours. Il s'agit d'un résolveur DNS normal, non chiffré, qui ne sera utilisé que pour des requêtes ponctuelles lors de la récupération de la liste initiale des résolveurs, et seulement si la configuration DNS du système ne fonctionne pas. Il ne sera jamais utilisé si les listes ont déjà été mises en cache." "Ne laissez jamais dnscrypt-proxy essayer d'utiliser les paramètres DNS du système. Utilisez sans condition le résolveur de secours.." "FILTRES" "Règles de Réacheminement" "Acheminez les requêtes de domaines spécifiques vers un ensemble de serveurs dédié." "Règles de Masquage" - "Le masquage (cloaking) renvoie une adresse prédéfinie pour un nom spécifique. - En plus d'agir comme un fichier HOSTS, il peut également renvoyer l'adresse IP d'un nom différent. Il fera également l'aplatissement CNAME.." + "Le masquage (cloaking) renvoie une adresse prédéfinie pour un nom spécifique. En plus d'agir comme un fichier HOSTS, il peut également renvoyer l'adresse IP d'un nom différent. Il fera également l'aplatissement CNAME.." "Journalisation des requêtes." "Enregistrer les requêtes des clients dans un fichier." "Activer la journalisation des requêtes" "Ne pas enregistrez ces types de requêtes afin de réduire la verbosité. Gardez les champs vides pour tout enregistrer." "Ouvrir le Journal des Requêtes" "Journalisation des requêtes suspectes." - "Journaliser les requêtes pour les zones inexistantes. - Ces requêtes peuvent révéler la présence de logiciels malveillants, d'applications endommagées/obsolètes et d'appareils signalant leur présence à des tiers." + "Journaliser les requêtes pour les zones inexistantes. Ces requêtes peuvent révéler la présence de logiciels malveillants, d'applications endommagées/obsolètes et d'appareils signalant leur présence à des tiers." "Activer la journalisation de donnée suspecte" "Ouvrir le journal de suspicion" "Blocage basé sur un modèle (liste noire)." @@ -249,10 +237,10 @@ "Apps contournant InviZible" "Tout Sélectionner" "Supprimer la Sélection" - "Paramètres Communs" - "Autoriser les connexions entrantes" - "Port pour l'écoute des connexions entrantes." - "IP externe du routeur pour les connexions entrantes." + Paramètres Communs + Autoriser les connexions entrantes + Port pour l\'écoute des connexions entrantes. + IP externe du routeur pour les connexions entrantes. "Activez la communication via l'IPv4." "Activez la communication via l'IPv6." "Le routeur n'acceptera pas les tunnels de transit, ce qui désactivera complètement le trafic de transit." @@ -261,7 +249,7 @@ "Limite en % le maximum de la bande passante pour le transit. 0–100." "Activer le protocole de transport SSU (utiliser l'UDP)." "Activer le protocole de transport NTCP2 (utiliser TCP)." - "Activer ntcpproxy" + Activer ntcpproxy "Spécifiez le serveur mandataire pour NTCP. Doit être http://adresse:port ou socks://adresse:port." "Mandataire HTTP" "Mandataire HTTP" @@ -278,26 +266,22 @@ "Cryptographie" "Utiliser les tables précalculées d'ElGamal." "Activer ou désactiver l'UPnP." - "ntcp2 activé" "Réensemencement" - "Vérifiez la signature .su3." + "Vérifiez la signature su3." "Limites" "Ne pas tenir compte du nombre maximum de tunnels de transit. 2500 par défaut." "Limiter le nombre de descripteurs de fichiers ouverts (0 - utiliser la limite système)." - "Taille maximale du fichier core en Kb (0 - utiliser la limite système)." - "Carnet d'adresses" + Taille maximale du fichier core en Kb (0 - utiliser la limite système). + Carnet d\'adresses "URL d'abonnement au carnet d'adresses pour la configuration initiale." "URL d'abonnements au carnet d'adresses." "La préférence n'existe pas dans i2pd.conf!" "Info" - "On dirait que DNSCrypt a été tué par le système Android. - Votre connexion Internet a été rétablie. Vérifiez les paramètres de l'appareil!" - "On dirait que Tor a été tué par le système Android. - Votre connexion Internet a été rétablie. Vérifiez les paramètres de l'appareil!" + "On dirait que DNSCrypt a été tué par le système Android. Votre connexion Internet a été rétablie. Vérifiez les paramètres de l'appareil!" + "On dirait que Tor a été tué par le système Android. Votre connexion Internet a été rétablie. Vérifiez les paramètres de l'appareil!" "On dirait qu'I2P a été tué par le système Android. Vérifiez les paramètres de l'appareil!" "On dirait qu'DNSCrypt NE PEUT PAS se connecter à INTERNET." - "On dirait que Tor NE PEUT PAS se connecter à INTERNET. - Le FAI peut bloquer les connexions Tor. Vous pouvez essayer d'utiliser les Ponts tor. Veuillez les trouver dans MENU -> Paramètres Rapides -> Ponts" + "On dirait que Tor NE PEUT PAS se connecter à INTERNET. Le FAI peut bloquer les connexions Tor. Vous pouvez essayer d'utiliser les Ponts tor. Veuillez les trouver dans MENU -> Paramètres Rapides -> Ponts" "Sécurité Enfant" "Vous pouvez verrouiller le contrôle de cette application. Veuillez entrer le mot de passe ou utiliser le précédent." "Veuillez entrer le mot de passe." @@ -322,12 +306,12 @@ "Une mise à jour de DNSCrypt est disponible. Voulez-vous la télécharger et l'effectuer? La mise à jour se poursuivra en arrière-plan." "Une mise à jour de Tor est disponible. Voulez-vous la télécharger et l'effectuer? La mise à jour se poursuivra en arrière-plan." "Une mise à jour de Purple I2P est disponible. Voulez-vous la télécharger et l'effectuer? La mise à jour se poursuivra en arrière-plan." - "Vérification des Mises à Jour" - "Veuillez patienter pendant la vérification des mises à jour." + Vérification des Mises à Jour + Veuillez patienter pendant la vérification des mises à jour. "Le serveur de mise à jour est temporairement indisponible. Veuillez réessayer ultérieurement." "Le serveur de mise à jour est indisponible." "Erreur de mise à jour." - "Aucune Mise à Jour n'a été Trouvée." + Aucune Mise à Jour n\'a été Trouvée. "Dernière vérification:" "Des mises à jour ont été trouvées." "Des mises à jour ont été installées." @@ -358,19 +342,17 @@ "Le Projet InviZible Pro a besoin de votre aide. Appuyez sur OK pour acheter les fonctionnalités premium." "Désolé, mais il est impossible de confirmer votre achat. Vous serez remboursé au bout de 3 jours." "Malheureusement, cette fonctionnalité n'est disponible que dans la version premium." - " merci d\'avoir choisi InviZible Pro. J\'espère qu\'il vous sera utile pour le respect de votre vie privée et une utilisation confortable d\'Internet. -\n -\n\tInviZible Pro inclut Tor, DNSCrypt et Purple I2P comme modules. -\n -\n\tInviZible Pro peut utiliser root, si votre appareil possède des privilèges root, ou utiliser un RPV local pour acheminer le trafic Internet vers les réseaux Tor, DNSCrypt et I2P. -\n -\n\tPolitique de confidentialité : -\n\tInviZible Pro ne collecte ni ne partage aucune donnée personnelle ou sensible des utilisateurs. -\n -\n\tCopyright © 2019-2024 -\n\tOleksandr Garmatin -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy" + + \tMerci d\'avoir choisi InviZible Pro. J\'espère qu\'il vous sera utile pour le respect de votre vie privée et une utilisation confortable d\'Internet. + \n\n\tInviZible Pro inclut Tor, DNSCrypt et Purple I2P comme modules. + \n\n\tInviZible Pro peut utiliser root, si votre appareil possède des privilèges root, ou utiliser un RPV local pour acheminer le trafic Internet vers les réseaux Tor, DNSCrypt et I2P. + \n\n\tPolitique de confidentialité: + \n\tInviZible Pro ne collecte ni ne partage aucune donnée personnelle ou sensible des utilisateurs. + \n\tCopyright © 2019-2024 + \n\tOleksandr Garmatin + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + "Mandataire HTTP sortant" "Adresse du mandataire HTTP sortant" "Mandataire SOCKS sortant" @@ -400,8 +382,7 @@ "Importer la liste blanche" "Importer une liste de domaines. Vous pouvez sélectionner plusieurs fichiers, les lignes en double seront supprimées." "Effacer la liste blanche" - "Répondre immédiatement aux requêtes liées à l'IPv6 par une réponse vide. - Cela accélère les choses en l'absence de connectivité IPv6, mais peut également entraîner des problèmes de fiabilité avec certains résolveurs minimum (stub)." + "Répondre immédiatement aux requêtes liées à l'IPv6 par une réponse vide. Cela accélère les choses en l'absence de connectivité IPv6, mais peut également entraîner des problèmes de fiabilité avec certains résolveurs minimum (stub)." "Veuillez désactiver \"DNS privé\" dans les paramètres réseau d'Android. Cette option interfère avec DNSCrypt." "Règles d'importation" "Veuillez patienter…%d Règles importées." @@ -414,22 +395,20 @@ "De nouvelles passerelles Tor par défaut sont disponibles. Voulez-vous les mettre à jour ?" "Détection d'attaque HDM (MITM)" "Détection d'usurpation ARP" - "Détectez l'usurpation ARP par l'Homme-Du-Millieu et les attaques DHCP malveillantes dans les réseaux Wi-Fi." + Détectez l\'usurpation ARP par l\'Homme-Du-Millieu et les attaques DHCP malveillantes dans les réseaux Wi-Fi. "Bloquer Internet lorsqu'une attaque est détectée" "La connexion Internet sera bloquée pendant une attaque" "Mandataire (Proxy)" "Utiliser un mandataire socks5" "InviZible Pro établira toutes les connexions via le mandataire SOCKS5" "Mode compatibilité" - "Activer si votre appareil utilisant une ROM personnalisée perd sa connexion lorsque vous appuyez sur le bouton DÉMARRER" + Activer si votre appareil utilisant une ROM personnalisée perd sa connexion lorsque vous appuyez sur le bouton DÉMARRER "Activer le contrôle de script" - "Utiliser la commande suivante pour gérer les modules d'application: - \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL - --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Où 1 - démarre, 0 - arrête le module." + "Utiliser la commande suivante pour gérer les modules d'application: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Où 1 - démarre, 0 - arrête le module." "Adresse IP du périphérique LAN" "Activez Fixer la DDV et configurez le périphérique LAN pour qu'il se connecte à InviZible. Utilisez la passerelle par défaut: %1$s, serveur DNS: %2$s." "Support multi-utilisateurs" - "Soutien des applications doubles, MIUI, Island, Shelter et utilisant le Profil Professionnel" + Soutien des applications doubles, MIUI, Island, Shelter et utilisant le Profil Professionnel "Activer le mandataire SOCKS de sortie" "Tor établira toutes les connexions OR via le mandataire SOCKS 5." "Services en cours d'exécution" @@ -454,8 +433,7 @@ "Connexion réussie. Ping de %s ms." "Usurpation ARP détectée!" "DHCP malveillant détecté!" - "Une attaque de l'Homme Du Milieu est détectée! Vos données peuvent être interceptées par un autre appareil sur le réseau local. - Éteignez, attendez quelques secondes et activez le Wi-Fi. L'utilisation du point d'accès Wi-Fi actuel peut être dangereuse!" + "Une attaque de l'Homme Du Milieu est détectée! Vos données peuvent être interceptées par un autre appareil sur le réseau local. Éteignez, attendez quelques secondes et activez le Wi-Fi. L'utilisation du point d'accès Wi-Fi actuel peut être dangereuse!" "La détection d'usurpation ARP n'est pas prise en charge pour votre appareil!" "Veuillez désactiver les nœuds d'entrée dans les paramètres Tor, sinon vous ne pouvez pas utiliser de Passerelles." "Contourner les adresses LAN" @@ -510,7 +488,7 @@ "Changement d'IP de Tor" "Vous avez ajouté plus de 3 tuiles aux Paramètres rapides. Veuillez n'en laisser que 3. L'ajout de plus de 3 tuiles peut entraîner des problèmes de contrôle de l'application." "Découverte DHCP non autorisée" - "Détecter les attaques DHCP de type Homme du milieu (Man-in-the-middle) dans les réseaux Wi-Fi." + Détecter les attaques DHCP de type Homme du milieu (Man-in-the-middle) dans les réseaux Wi-Fi. "Choisir le rendez-vous" "Cache le nom de domaine de l'intermédiaire (broker) au fournisseur d'accès Internet. L'intermédiaire est utilisé pour établir une connexion." "Afficher toutes les applications" diff --git a/tordnscrypt/src/main/res/values-in/strings.xml b/tordnscrypt/src/main/res/values-in/strings.xml index 1c87eebf8..fb2fe83c9 100644 --- a/tordnscrypt/src/main/res/values-in/strings.xml +++ b/tordnscrypt/src/main/res/values-in/strings.xml @@ -59,9 +59,9 @@ Pilih folder pencadangan: "Setelan" "Mulai otomatis" - "Mulai DNSCrypt saat boot" - "Mulai Tor saat Boot" - "Mulai I2P saat Boot" + Mulai DNSCrypt saat boot + Mulai Tor saat Boot + Mulai I2P saat Boot "Tunda" Masukkan nilai penundaan (dalam detik) jika fitur mulai otomatis tidak bekerja dengan semestinya "Server DNSCrypt" @@ -72,18 +72,18 @@ "Alihkan semua lalu lintas data melalui Tor" "Alihkan semua lalu lintas data melalui InviZible" - "Pilih website" - "Daftar website dibuka dengan Tor" - "Pilih Aplikasi" + Pilih website + Daftar website dibuka dengan Tor + Pilih Aplikasi "Daftar aplikasi menggunakan Tor" "Daftar aplikasi menggunakan InviZible" - "Kecualikan website" - "Daftar WebSites untuk membuka secara langsung" - "Kecualikan aplikasi" + Kecualikan website + Daftar WebSites untuk membuka secara langsung + Kecualikan aplikasi "Daftar aplikasi untuk dibuka langsung" - "Segarkan Interval" - "Masukkan nilai (dalam jam) untuk menyegarkan alamat IP laman. Khusus versi Android 5.1 keatas, masukkan nilai nol untuk menghentikan penyegaran." + Segarkan Interval + Masukkan nilai (dalam jam) untuk menyegarkan alamat IP laman. Khusus versi Android 5.1 keatas, masukkan nilai nol untuk menghentikan penyegaran. "Bridge" "Pakai bridge jika anda tidak dapat terhubung ke jaringan Tor" "Jangan pakai Bridge" @@ -101,16 +101,16 @@ "Simpan" "Tutup" "Nama host salah!" - "Pilih Tema" - "Pilih bahasa" + Pilih Tema + Pilih bahasa "Blokir http" "Tolak koneksi ke http dengan porta 80" "Pembaruan" - "Perbarui Otomatis" - "Cek InviZible Pro dan perbarui modul setiap hari" - "Periksa Pembaruan" + Perbarui Otomatis + Cek InviZible Pro dan perbarui modul setiap hari + Periksa Pembaruan "Periksa jika versi baru sudah tersedia" "Perbarui secara ketat melalui Tor" "Cek pembaruan versi hanya berjalan dengan sambungan Tor" @@ -120,30 +120,30 @@ "Lainnya" "Blokir HOTSPOT http" "Tolak koneksi http dengan porta 80 untuk HOTSPOT" - "Lindungi aplikasi dengan Modus tanpa Root agar tidak dimatikan sistem Android" + Lindungi aplikasi dengan Modus tanpa Root agar tidak dimatikan sistem Android "Segaran aturan" "Perbarui aturan disetiap perubahan sambungan" "Tampilkan pemberitahuan" "Cegah perangkat tidur" - "Perlindungan tambahan untuk modus tanpa Root agar aplikasi tidak dimatikan sistem Android. Fitur ini akan menguras daya baterai" + Perlindungan tambahan untuk modus tanpa Root agar aplikasi tidak dimatikan sistem Android. Fitur ini akan menguras daya baterai "Pesan bantuan" - "Selalu Tampilkan pesan Bantuan" + Selalu Tampilkan pesan Bantuan Silahkan pilih InviZible Pro dari daftar pengoptimalan baterai Android. Jika tidak, Sistem Android akan mematikan DNSCrypt, Tor, atau I2P kapanpun. Sistem Operasi seperti MIUI membutuhkan langkah khusus. "Pilih BusyBox" "Experimental-HOTSPOT" - "Memulai Penambatan saat Boot" - "Ijinkan Penambatan Tor" + Memulai Penambatan saat Boot + Ijinkan Penambatan Tor "Alihkan semua lalu lintas melalui Tor" "Alihkan lalu lintas data yang masuk melalui Tor" - "Pilih Situs" - "Daftar laman yang akan dialihkan ke TOR untuk sambungan HOTSPOT" - "Kecualikan Website" + Pilih Situs + Daftar laman yang akan dialihkan ke TOR untuk sambungan HOTSPOT + Kecualikan Website Daftar situs yang bisa dibuka tanpa enkripsi untuk sambungan HOTSPOT - "Ijinkan penambatan I2P" + Ijinkan penambatan I2P "Perbaiki TTL" Nilai TTL akan diset jadi 64 menggunakan VPN lokal, tidak perlu dukungan kernel. Fitur bisa digunakan pada \"modus root\" dan opsi \"Menjalankan Modul dengan Root\" sudah dimatikan. Untuk memperbaiki TTL silahkan mulai DNSCrypt atau/dan Tor. - "Buka konfigurasi Penambatan" + Buka konfigurasi Penambatan "Silahkan mulai ulang DNSCrypt" "Silahkan mulai ulang Tor" "Silahkan mulai ulang I2P" @@ -165,8 +165,7 @@ "Server tidak boleh mencatat permintaan pengguna (deklaratif)." "Server tidak boleh menerapkan daftar hitamnya sendiri (untuk kontrol orang tua, pemblokiran iklan ...)." "Selalu gunakan TCP untuk terhubung ke server upstream." - Hal ini akan berguna jika anda ingin mengalihkan semua lalu lintas data melalui Tor. -\nAtau anda bisa mengabaikan fitur tersebut, karena tak serta-merta meningkatkan keamanan (dnscrypt-proxy akan mengenkripsi apapun, bahkan UDP sekalipun), yang ada malah menambah latensi. + Hal ini akan berguna jika anda ingin mengalihkan semua lalu lintas data melalui Tor. Atau anda bisa mengabaikan fitur tersebut, karena tak serta-merta meningkatkan keamanan (dnscrypt-proxy akan mengenkripsi apapun, bahkan UDP sekalipun), yang ada malah menambah latensi. "Proxy HTTP / SOCKS." "Aktifkan proxy" Mengalihkan semua koneksi TCP ke node Tor lokal. Tor tidak mendukung UDP, jadi setel force_tcp ke true juga. @@ -178,16 +177,14 @@ Aturan pemindahan Merutekan query untuk domain tertentu ke dedicated server khusus. Aturan paksa - Cloaking mengembalikan alamat yang telah ditentukan untuk nama tertentu. -\n Selain bertindak sebagai file HOSTS, ia juga dapat mengembalikan alamat IP dari nama yang berbeda. Ini juga akan melakukan perataan CNAME.. + Cloaking mengembalikan alamat yang telah ditentukan untuk nama tertentu. Selain bertindak sebagai file HOSTS, ia juga dapat mengembalikan alamat IP dari nama yang berbeda. Ini juga akan melakukan perataan CNAME.. "Pencatatan kueri." "Catat permintaan klien ke file." "Aktifkan Pencatatan kueri" Jangan catat jenis kueri berikut. Kosongi bidang ini agar semua pesan log tercatat. "Buka Log Kueri" "Pencatatan kueri yang mencurigakan." - Catatan kueri untuk zona yang tidak ada. -\nKueri ini dapat mengungkapkan keberadaan malware, aplikasi yang rusak / usang, dan perangkat yang memberi sinyal keberadaannya kepada pihak ketiga. + Catatan kueri untuk zona yang tidak ada. Kueri ini dapat mengungkapkan keberadaan malware, aplikasi yang rusak / usang, dan perangkat yang memberi sinyal keberadaannya kepada pihak ketiga. "Aktifkan Pencatatan yang Mencurigakan" "Buka Log Mencurigakan" "Pemblokiran berbasis pola (daftar hitam)." @@ -247,10 +244,10 @@ "Aplikasi untuk jalan pintas InviZible" "Pilih Semua" "Hapus Pilihan" - "Pengaturan umum" - "Izinkan koneksi masuk" - "Port untuk mendengarkan koneksi yang masuk." - "Router eksternal IP untuk koneksi masuk." + Pengaturan umum + Izinkan koneksi masuk + Port untuk mendengarkan koneksi yang masuk. + Router eksternal IP untuk koneksi masuk. "Aktifkan komunikasi melalui IPv4." "Aktifkan komunikasi melalui IPv6." "Router tidak akan menerima terowongan transit, menonaktifkan lalu lintas transit sepenuhnya." @@ -260,7 +257,7 @@ "Aktifkan protokol transport SSU (gunakan UDP)." "Aktifkan protokol transport NTCP2 (gunakan TCP)." - "Aktifkan ntcpproxy" + Aktifkan ntcpproxy Atur proxy NTCP. Contoh pola alamat http://alamat:porta atau socks://alamat:porta. "Proxy HTTP" "Proxy HTTP" @@ -277,13 +274,12 @@ "Kriptografi" "Gunakan tabel prakomputasi ElGamal." "Hidupkan atau matikan UPnP." - "ntcp2 diaktifkan" Mengirim ulang - "Verifikasi tanda tangan .su3." + "Verifikasi tanda tangan su3." "Batas" "Timpa jumlah maksimum terowongan transit. 2500 secara default." "Batasi jumlah deskriptor file terbuka (0 - gunakan batas sistem)." - "Ukuran maksimum corefile dalam Kb (0 - gunakan batas sistem)." + Ukuran maksimum corefile dalam Kb (0 - gunakan batas sistem). Buku alamat "URL berlangganan AddressBook untuk pengaturan awal." "URL langganan AddressBook." @@ -293,8 +289,7 @@ Sepertinya Tor dimatikan Sistem Android. Koneksi internet anda dipulihkan. Periksa pengaturan perangkat! Sepertinya I2P dimatikan Sistem Android. Koneksi internet anda dipulihkan. Periksa pengaturan perangkat! "Sepertinya DNSCrypt TIDAK BISA terhubung ke INTERNET." - "Sepertinya Tor TIDAK BISA terhubung ke INTERNET. -        Penyedia jasa Internet anda mungkin memblokir koneksi Tor. Aktifkan fitur Bridge di Tor dengan cara tekan Menu -> Pengaturan Cepat -> Bridge" + "Sepertinya Tor TIDAK BISA terhubung ke INTERNET. Penyedia jasa Internet anda mungkin memblokir koneksi Tor. Aktifkan fitur Bridge di Tor dengan cara tekan Menu -> Pengaturan Cepat -> Bridge" Kunci dini Anda dapat mengunci kontrol aplikasi ini. Silakan masukkan kata sandi. "Silakan masukkan kata sandi." @@ -319,12 +314,12 @@ "Pembaruan DNSCrypt tersedia. Apakah Anda ingin mengunduh dan memperbaruinya? Pembaruan akan berlanjut di latar belakang." "Pembaruan Tor tersedia. Apakah Anda ingin mengunduh dan memperbaruinya? Pembaruan akan berlanjut di latar belakang." "Pembaruan Purple I2P tersedia. Apakah Anda ingin mengunduh dan memperbaruinya? Pembaruan akan berlanjut di latar belakang." - "Memeriksa Pembaruan" - "Harap tunggu sementara Pembaruan sedang memeriksa." + Memeriksa Pembaruan + Harap tunggu sementara Pembaruan sedang memeriksa. "Server pembaruan tidak tersedia untuk sementara. Silakan coba lagi nanti." "Server pembaruan tidak tersedia." "Perbarui kesalahan." - "Tidak Ada Pembaruan Ditemukan." + Tidak Ada Pembaruan Ditemukan. "Cek terakhir:" "Pembaruan ditemukan." "Pembaruan telah diinstal." @@ -403,13 +398,13 @@ "Pakai proxy socks5" "Invizible Pro akan mengalihkan semua koneksi melalui proxy SOCKS5" "Modus kompabilitas" - "Hidupkan fitur ini jika perangkat anda terpasang ROM kustom dan koneksi hilang ketika menekan tombol START" + Hidupkan fitur ini jika perangkat anda terpasang ROM kustom dan koneksi hilang ketika menekan tombol START "Hidupkan skrip kontrol" Jalankan perintah berikut untuk mengatur modul aplikasi: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module. "Alamat IP perangkat LAN" "Hidupkan fitur perbaikan TTL dan atur LAN agar dapat terhubung ke InviZibleUse default gateway: %1$s, DNS server: %2$s." "Dukungan multi-pengguna" - "Cocok untuk aplikasi profil kerja, misal MIUI, Island, Shelter, dsb" + Cocok untuk aplikasi profil kerja, misal MIUI, Island, Shelter, dsb "Hidupkan Proxy keluaran SOCKS" Tor akan mengalihkan semua koneksi melalui Proxy SOCKS5. "Layanan yang berjalan" @@ -434,8 +429,7 @@ "Koneksi berhasil. Ping %s ms." "spoofing ARP terdeteksi!" "DHCP Rogue terdeteksi!" - "Serangan MITM terdeteksi! Data anda dapat disadap oleh perangkat lain di jaringan yang sama dengan anda. -Matikan dan hidupkan wifi beberapa saat, hotspot Wi-Fi yang anda akses saat ini mungkin tidak aman!" + "Serangan MITM terdeteksi! Data anda dapat disadap oleh perangkat lain di jaringan yang sama dengan anda. Matikan dan hidupkan wifi beberapa saat, hotspot Wi-Fi yang anda akses saat ini mungkin tidak aman!" "Deteksi ARP spoofing tidak didukung di perangkat anda!" "Mohon matikan Noda masuk di Pengaturan Tor atau fitur bridge tidak berfungsi." "Bypass alamat LAN" @@ -489,17 +483,15 @@ Matikan dan hidupkan wifi beberapa saat, hotspot Wi-Fi yang anda akses saat ini Coba gunakan akselerasi perangkat keras kripto bawaan jika tersedia. Mengganti IP Tor Kamu sudah menambahkan lebih dari 3 ubin ke Pengaturan Cepat. Disarankan hanya menambahkan 3. Menambahkan lebih dari 3 ubin dapat menyebabkan masalah dengan kontrol aplikasi. - \\\tTerima kasih sudah memilih InviZible Pro. Saya harap ini dapat berguna untuk privasi dan kenyamanan berinternet anda. -\n -\n\tInviZible Pro menggunakan Tor, DNSCrypt dan Purple I2P sebagai modulnya -\n -\n\tInviZible Pro bisa menggunakanroot, juka penrangkat mu memeliki izin root, atau menggunakan VPN lokal untuk Tor, DNSCrypt dan I2P. -\n -\n\tKebijakan privasi: -\n\tInviZible Pro tidak mengumpulkan dan membagikan data sensitif pengguna. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy - \ No newline at end of file + + \tTerima kasih sudah memilih InviZible Pro. Saya harap ini dapat berguna untuk privasi dan kenyamanan berinternet anda. + \n\n\tInviZible Pro menggunakan Tor, DNSCrypt dan Purple I2P sebagai modulnya + \n\n\tInviZible Pro bisa menggunakanroot, juka penrangkat mu memeliki izin root, atau menggunakan VPN lokal untuk Tor, DNSCrypt dan I2P. + \n\n\tKebijakan privasi: + \n\tInviZible Pro tidak mengumpulkan dan membagikan data sensitif pengguna. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + + diff --git a/tordnscrypt/src/main/res/values-it/strings.xml b/tordnscrypt/src/main/res/values-it/strings.xml index 216804668..6dfe16a54 100644 --- a/tordnscrypt/src/main/res/values-it/strings.xml +++ b/tordnscrypt/src/main/res/values-it/strings.xml @@ -58,9 +58,9 @@ "Scegli cartella di backup:" "Impostazioni" "Avvio automatico" - "Esegui DNSCrypt All'Avvio" - "Esegui Tor All'Avvio" - "Esegui I2P All'Avvio" + Esegui DNSCrypt All\'Avvio + Esegui Tor All\'Avvio + Esegui I2P All\'Avvio "Ritardo" "Usa ritardo (in sec) solo se l'avvio automatico non funziona correttamente" "Servers DNSCrypt" @@ -69,17 +69,17 @@ "Impostazioni di instradamento" "Instrada Tutto il traffico attraverso Tor" "Instrada Tutto il traffico attraverso InviZible" - "Seleziona Siti Web" - "Lista di Siti Web da aprire con Tor. Questa caratteristica non funziona per i siti dietro una CDN" - "Seleziona Applicazioni" + Seleziona Siti Web + Lista di Siti Web da aprire con Tor. Questa caratteristica non funziona per i siti dietro una CDN + Seleziona Applicazioni "Lista di applicazioni da usare con Tor" "Lista di applicazioni da usare con InviZible" - "Escludi Siti Web" - "Lista di Siti Web da aprire direttamente. Questa caratteristica non funziona per i siti dietro una CDN" - "Escludi Applicazioni" + Escludi Siti Web + Lista di Siti Web da aprire direttamente. Questa caratteristica non funziona per i siti dietro una CDN + Escludi Applicazioni "Lista di applicazioni da aprire direttamente" - "Intervallo di Aggiornamento" - "Periodo in ore per aggiornare gli IP dei Siti Web. Per Android 5.1 e versioni successive. Inserire 0 per fermare l'aggiornamento." + Intervallo di Aggiornamento + Periodo in ore per aggiornare gli IP dei Siti Web. Per Android 5.1 e versioni successive. Inserire 0 per fermare l\'aggiornamento. Bridges "Usalo se non riesci a connetterti alla rete Tor" "Non Usare i Bridges" @@ -97,14 +97,14 @@ "Salva" "Chiudi" "Nome host errato!" - "Seleziona Tema" - "Seleziona Lingua" + Seleziona Tema + Seleziona Lingua "Blocca http" "Nega connessione http sulla porta 80" "Aggiornamento" - "Aggiornamento automatici" - "Controlla gli aggiornamenti di InviZible Pro e dei moduli ogni giorno" - "Controlla aggiornamento" + Aggiornamento automatici + Controlla gli aggiornamenti di InviZible Pro e dei moduli ogni giorno + Controlla aggiornamento "Controlla ora se sono disponibili nuove versioni" "Aggiorna rigorosamente solo tramite Tor" "Controlla aggiornamenti solo con Tor e quando Tor è in esecuzione" @@ -114,29 +114,29 @@ "Altro" "Blocca HOTSPOT http" "Nega connessione http sulla porta 80 per HOTSPOT" - "Proteggi l'applicazione senza la modalità root per evitare che l'app venga chiusa da Android" + Proteggi l\'applicazione senza la modalità root per evitare che l\'app venga chiusa da Android "Aggiorna regole" "Aggiorna regole ad ogni cambiamento di connessione" "Mostra notifica" "Impedisci la sospensione del dispositivo" - "Protezione aggiuntiva per la modalità non-root per evitare che l'app venga chiusa da Android. Può scaricare la batteria" + Protezione aggiuntiva per la modalità non-root per evitare che l\'app venga chiusa da Android. Può scaricare la batteria "Messaggi di aiuto" - "Mostra Sempre messaggi di Aiuto" + Mostra Sempre messaggi di Aiuto Escludi InviZible Pro dall\'ottimizzazione batteria di Android. Diversamente Android potrebbe chiudere DNSCrypt, Tor o I2P in qualsiasi momento. Su ROM speciali, come MIUI, sono necessari alcuni passaggi aggiuntivi. "Seleziona BusyBox" "HOTSPOT-Sperimentale" - "Avvia il tethering all'avvio" - "Consenti Tethering Tor" + Avvia il tethering all\'avvio + Consenti Tethering Tor "Instrada Tutto attraverso Tor" "Instrada Tutto il traffico in entrata attraverso Tor" - "Seleziona Siti Web" - "Lista di Siti Web da aprire con Tor per l'HOTSPOT" - "Escludi Siti Web" - "Lista di Siti Web da aprire direttamente per l'HOTSPOT" - "Consenti Tethering I2P" + Seleziona Siti Web + Lista di Siti Web da aprire con Tor per l\'HOTSPOT + Escludi Siti Web + Lista di Siti Web da aprire direttamente per l\'HOTSPOT + Consenti Tethering I2P "Correggi TTL" - "TTL verrà fissato a 64 utilizzando una VPN locale. Il supporto del kernel non è richiesto. Può essere utilizzato solo in \"modalità root\" con l'opzione \"Esegui moduli con root\" disabilitata. Per correggere TTL, avvia DNSCrypt o/e Tor." - "Apri configurazione Tethering" + TTL verrà fissato a 64 utilizzando una VPN locale. Il supporto del kernel non è richiesto. Può essere utilizzato solo in \"modalità root\" con l\'opzione \"Esegui moduli con root\" disabilitata. Per correggere TTL, avvia DNSCrypt o/e Tor. + Apri configurazione Tethering "Riavvia DNSCrypt" "Riavvia Tor" "Riavvia I2P" @@ -158,29 +158,26 @@ "Il server non deve registrare le query dell'utente (dichiarativo)." "Il server non deve imporre la propria lista nera (per il controllo parentale, il blocco degli annunci...)." "Usa sempre TCP per connetterti ai server upstream." - Questo può essere utile se hai bisogno di instradare tutto il traffico attraverso Tor. -\n Altrimenti, lascialo su false, poiché non migliora la sicurezza (dnscrypt-proxy crittograferà sempre tutto anche usando UDP) e può solo aumentare la latenza. + Questo può essere utile se hai bisogno di instradare tutto il traffico attraverso Tor. Altrimenti, lascialo su false, poiché non migliora la sicurezza (dnscrypt-proxy crittograferà sempre tutto anche usando UDP) e può solo aumentare la latenza. "Proxy SOCKS." "Abilita proxy" "Instrada tutte le connessioni TCP a un nodo Tor locale. Tor non supporta UDP, quindi imposta anche force_tcp su true." "porta_proxy" "Altre Impostazioni." - "Risolutore di fallback. Questo è un normale risolutore DNS non crittografato, che verrà utilizzato solo per query one-shot quando si recupera l'elenco iniziale dei risolutori e solo se la configurazione DNS del sistema non funziona. Non verrà mai utilizzato se le liste sono già state memorizzate nella cache." + Risolutore di fallback. Questo è un normale risolutore DNS non crittografato, che verrà utilizzato solo per query one-shot quando si recupera l\'elenco iniziale dei risolutori e solo se la configurazione DNS del sistema non funziona. Non verrà mai utilizzato se le liste sono già state memorizzate nella cache. "Non permettere mai a dnscrypt-proxy di provare a utilizzare le impostazioni DNS di sistema. Usa incondizionatamente il risolutore di fallback.." "FILTRI" "Regole di inoltro" "Instrada le query per domini specifici a un set di server dedicato." "Regole di cloaking" - Il cloaking restituisce un indirizzo predefinito per un nome specifico. -\n Oltre a fungere da file HOSTS, può anche restituire l\'indirizzo IP con un nome diverso. Farà anche l\'appiattimento CNAME.. + Il cloaking restituisce un indirizzo predefinito per un nome specifico. Oltre a fungere da file HOSTS, può anche restituire l\'indirizzo IP con un nome diverso. Farà anche l\'appiattimento CNAME.. "Registrazione delle query." "Registra le query del client in un file." "Abilita registrazione Query" "Non registrare questi tipi di query per ridurre la verbosità. Mantieni vuoto per registrare tutto." "Apri registro query" "Registrazione delle query sospette." - Registra le query per le zone inesistenti. -\n Queste query possono rivelare la presenza di malware, applicazioni danneggiate/obsolete e dispositivi che segnalano la loro presenza a terze parti.. + Registra le query per le zone inesistenti. Queste query possono rivelare la presenza di malware, applicazioni danneggiate/obsolete e dispositivi che segnalano la loro presenza a terze parti.. "Abilita registrazione Sospetta" "Apri Registrazione Sospetta" "Blocco basato su pattern (lista nera)." @@ -240,10 +237,10 @@ "App da bypassare con InviZible" "Seleziona tutto" "Rimuovi Selezione" - "Impostazioni comuni" - "Consenti connessioni in entrata" - "Porta per le connessioni in entrata." - "IP esterno del router per le connessioni in entrata." + Impostazioni comuni + Consenti connessioni in entrata + Porta per le connessioni in entrata. + IP esterno del router per le connessioni in entrata. Abilita comunicazione attraverso IPv4. Abilita comunicazione attraverso IPv6. "Il router non accetterà tunnel di transito, e disabiliterà il traffico in transito completamente." @@ -252,7 +249,7 @@ "Limite massimo % larghezza di banda per il transito. 0-100." "Abilita protocollo di trasporto SSU (usa UDP)." "Abilita protocollo di trasporto NTCP2 (usa TCP)." - "Abilita ntcpproxy" + Abilita ntcpproxy "Specifica il server proxy per NTCP. Deve essere http://indirizzo:porta o socks://indirizzo:porta." "Proxy HTTP" "Proxy HTTP" @@ -269,13 +266,12 @@ "Criptografia" "Usa tavole precalcolate EIGamal." "Abilita o disabilita UPnP." - "ntcp2 abilitato" Reseeding - Verifica firma .su3. + Verifica firma su3. "Limiti" "Ignora numero massimo dei tunnel di transito. Default 2500." "Limita il numero dei descrittori apertura file (0 - usa limite di sistema)." - "Dimensione massima del corefile in Kb (0 - usa limite di sistema)." + Dimensione massima del corefile in Kb (0 - usa limite di sistema). Addressbook "URL sottoscrizione AddressBook per setup iniziale." "Indirizzi URL per sottoscrizione AddressBook." @@ -310,12 +306,12 @@ "E' disponibile un aggiornamento per DNSCrypt. Vuoi scaricarlo e aggiornarlo? L'aggiornamento continuerà in background." "E' disponibile un aggiornamento per Tor. Vuoi scaricarlo e aggiornarlo? L'aggiornamento continuerà in background." "E' disponibile un aggiornamento per Purple I2P. Vuoi scaricarlo e aggiornarlo? L'aggiornamento continuerà in background." - "Controllo Aggiornamenti" - "Aspetta mentre controllo gli Aggiornamenti." + Controllo Aggiornamenti + Aspetta mentre controllo gli Aggiornamenti. "Il server è temporaneamente irraggiungibile. Riprova più tardi." "Il server per gli aggiornamenti non era disponibile." "Errore aggiornamento." - "Nessun Aggiornamento Trovato." + Nessun Aggiornamento Trovato. "Ultimo controllo:" "Aggiornamenti disponibili." "Gli aggiornamenti sono stati installati." @@ -345,19 +341,17 @@ InviZible Pro Project ha bisogno del tuo supporto. Scegli OK per acquistare le caratteristiche premium. "Spiacente, è impossibile confermare il tuo acquisto. Riceverai un rimborso fra 3 giorni." "Sfortunatamente questa funzione è disponibile solo nella versione premium." - \tGrazie per aver scelto InviZible Pro. Spero che ti aiuterà a preservare la tua privacy e a rendere più comodo l\'utilizzo di Internet. -\n -\n\tInviZible Pro include i moduli Tor, DNSCrypt e Purple I2P. -\n -\n\tInviZible Pro può funzionare in modalità root, se il tuo dispositivo ha i privilegi di root, o utilizzare una VPN locale per reindirizzare il traffico Internet a Tor, DNSCrypt e alla rete I2P. -\n -\n\tPolitica della Privacy: -\n\tInviZible Pro non raccoglie o condivide nessun dato utente personale o sensibile. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy + + \tGrazie per aver scelto InviZible Pro. Spero che ti aiuterà a preservare la tua privacy e a rendere più comodo l\'utilizzo di Internet. + \n\n\tInviZible Pro include i moduli Tor, DNSCrypt e Purple I2P. + \n\n\tInviZible Pro può funzionare in modalità root, se il tuo dispositivo ha i privilegi di root, o utilizzare una VPN locale per reindirizzare il traffico Internet a Tor, DNSCrypt e alla rete I2P. + \n\n\tPolitica della Privacy: + \n\tInviZible Pro non raccoglie o condivide nessun dato utente personale o sensibile. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + HTTP outproxy "Indirizzo HTTP outproxy" SOCKS outproxy @@ -400,20 +394,20 @@ "Sono disponibili nuovi bridge Tor di default. Vuoi aggiornarli?" "Rilevamento attacco MITM" "Rilevamento spoofing ARP" - "Rileva attacchi Man-in-the-middle, spoofing ARP e rogue DHCP nelle reti Wi-Fi." + Rileva attacchi Man-in-the-middle, spoofing ARP e rogue DHCP nelle reti Wi-Fi. "Blocca connessione internet quando viene rilevato un attacco" "La connessione internet verrà bloccata durante un attacco" Proxy "Utilizza proxy socks5" "InviZible Pro stabilirà tutte le connessioni attraverso il proxy SOCKS5" "Modalità compatibilità" - "Abilita se il tuo dispositivo usa una ROM custom e la connessione non funziona quando si preme il pulsante START" + Abilita se il tuo dispositivo usa una ROM custom e la connessione non funziona quando si preme il pulsante START "Abilita controllo script" "Utilizza i seguenti comandi per gestire i moduli dell'applicazione: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module." "Indirizzo IP LAN del dispositivo" "Abilita Fix TTL e configura il dispositivo LAN per connettersi a InviZible. Utilizza il gateway di default: %1$s, server DNS: %2$s." "Supporto multi-utente" - "Supporto per applicazioni Dual Apps, MIUI, Island, Shelter e profilo Lavoro" + Supporto per applicazioni Dual Apps, MIUI, Island, Shelter e profilo Lavoro "Abilita SOCKS output proxy" "Tor stabilirà tutte le connessioni OR attraverso il proxy SOCKS 5." "Servizi in esecuzione" @@ -493,8 +487,7 @@ "Sto cambiando IP Tor" "Hai aggiunto più di 3 opzioni delle Impostazioni Rapide. Per favore scegline solo 3. Aggiungerne più di 3 può creare problemi con il controllo dell'app." "Rilevamento Rogue DHCP" - "Rileva attacchi Man-in-the-middle e rogue DHCP nelle reti Wi-Fi. -" + Rileva attacchi Man-in-the-middle e rogue DHCP nelle reti Wi-Fi. "Seleziona rendezvous" "Nascondi il nome dominio del broker al provider internet. Il broker è utilizzato per stabilire una connessione." "Mostra tutte le app" @@ -517,4 +510,4 @@ "Mostra i registri di connettività delle app nella scheda DNS" "Abilita supporto per HTTP/3 (DoH3, HTTP over QUIC). Nota che, come DNSCrypt ma in modo diverso da altre versioni HTTP, questa opzione usa UDP e (solitamente) la porta 443 invece del TCP." "Abilita protocollo di trasporto SSU2 (utilizza UPD)." - \ No newline at end of file + diff --git a/tordnscrypt/src/main/res/values-ja/strings.xml b/tordnscrypt/src/main/res/values-ja/strings.xml index 541832b89..f6baab320 100644 --- a/tordnscrypt/src/main/res/values-ja/strings.xml +++ b/tordnscrypt/src/main/res/values-ja/strings.xml @@ -58,9 +58,9 @@ "バックアップフォルダーを選択:" "設定" "自動起動" - "端末起動時にDNSCryptを起動" - "端末起動時にTorを起動" - "端末起動時にI2Pを起動" + 端末起動時にDNSCryptを起動 + 端末起動時にTorを起動 + 端末起動時にI2Pを起動 "遅延" "もし自動起動うまく動作しない場合は、遅延(秒)を設定してください" "DNSCrypt サーバー" @@ -69,17 +69,17 @@ "ルート設定" "すべてのトラフィックをTorに経由" "すべてのトラフィックをInviZibleに経由" - "ウェブサイトを選択" - "Torで開くウェブサイトを選択します。この機能はCDNを利用するサイトで動作しません" - "アプリを選択" + ウェブサイトを選択 + Torで開くウェブサイトを選択します。この機能はCDNを利用するサイトで動作しません + アプリを選択 "Torを使用するアプリを選択します" "InviZibleを使用するアプリを選択します" - "ウェブサイトを除外" - "直接開くウェブサイトを選択します。この機能はCDNを利用するサイトで動作しません" - "アプリを除外" + ウェブサイトを除外 + 直接開くウェブサイトを選択します。この機能はCDNを利用するサイトで動作しません + アプリを除外 "直接接続するアプリを選択します" - "更新頻度" - "Period in hours to refresh WebSites IPs. For Android 5.1 and higher. Put 0 to stop refresh." + 更新頻度 + Period in hours to refresh WebSites IPs. For Android 5.1 and higher. Put 0 to stop refresh. "ブリッジ" "もしTorネットワークに接続できない場合に使用します" "ブリッジを使用しない" @@ -97,14 +97,14 @@ "保存" "閉じる" "ホスト名が間違っています!" - "テーマを選択" - "言語を選択" + テーマを選択 + 言語を選択 "http接続をブロック" "http接続(ポート80)を拒否する" "アップデート" - "自動アップデート" - "毎日InviZible Proとモジュールの更新をチェックする" - "アップデートの確認" + 自動アップデート + 毎日InviZible Proとモジュールの更新をチェックする + アップデートの確認 "新しいバージョンがあるか確認する" "アップデートにTor接続を強制する" "Torが有効のときのみアップデートをチェックする" @@ -114,29 +114,29 @@ "その他" "ホットスポット(公衆Wi-Fi)でhttpをブロックする" "ホットスポットでhttp接続(ポート80)を拒否する" - "非Rootモードでandroidによってアプリのプロセスがキルされるのを防止する" + 非Rootモードでandroidによってアプリのプロセスがキルされるのを防止する "ルールを更新" "接続状態が変化した度にルールを反映する" "通知を表示する" "端末がスリープ状態になるのを防止する" - "非Rootモードでアプリのプロセスがandroidによってキルされるのを防止します。バッテリー消費が増加します。" + 非Rootモードでアプリのプロセスがandroidによってキルされるのを防止します。バッテリー消費が増加します。 "ヘルプメッセージ" - "常にヘルプメッセージを表示する" + 常にヘルプメッセージを表示する "Invizible Proをandroidのバッテリー最適化設定から除外してください。そうしなければモジュールが自動的に停止してしまう可能性があります。MIUIなどの特別なカスタマイズが施されたシステムの場合、追加の工程が必要な場合があります。" "Busyboxを選択" "ホットスポット(実験的)" - "起動時にテザリングを開始する" - "Tor経由のテザリングを許可する" + 起動時にテザリングを開始する + Tor経由のテザリングを許可する "全ての通信でTorを経由する" "すべての着信トラフィックでTorを経由する" - "ウェブサイトを選択" - "ホットスポット(公衆Wi-Fi)でTorを経由して接続するウェブサイト" - "除外するウェブサイト" + ウェブサイトを選択 + ホットスポット(公衆Wi-Fi)でTorを経由して接続するウェブサイト + 除外するウェブサイト "ホットスポット(公衆Wi-Fi)で直接接続するウェブサイト " - "I2P経由のテザリングを許可する" + I2P経由のテザリングを許可する "TTLを防止する" - "TTL will be fixed to 64 using a local VPN. Kernel support is not required. It can only be used in \"root mode\" with the \"Run Modules With Root\" option disabled. To fix TTL please start DNSCrypt or/and Tor." - "テザリング設定を開く" + TTL will be fixed to 64 using a local VPN. Kernel support is not required. It can only be used in \"root mode\" with the \"Run Modules With Root\" option disabled. To fix TTL please start DNSCrypt or/and Tor. + テザリング設定を開く "DNSCryptを再起動してください" "Torを再起動してください" "I2Pを再起動してください" @@ -158,29 +158,26 @@ "使用するサーバーにログなしポリシーを要求する(自己申告)" "サーバーが自身のブラックリストを強制しないようにします(ペアレンタルコントロール、広告ブロックなど)" "アップストリームのサーバーへの接続に常にTCPを使用する" - "This can be can be useful if you need to route everything through Tor. -Otherwise, leave this to false, as it doesn't improve security (dnscrypt-proxy will always encrypt everything even using UDP), and can only increase latency." + "This can be can be useful if you need to route everything through Tor. Otherwise, leave this to false, as it doesn't improve security (dnscrypt-proxy will always encrypt everything even using UDP), and can only increase latency." "Socksプロキシ" "プロキシを有効化" "Route all TCP connections to a local Tor node. Tor doesn't support UDP, so set force_tcp to true as well." "proxy_port" "その他の設定" - "Fallback resolver. This is a normal, non-encrypted DNS resolver, that will be only used for one-shot queries when retrieving the initial resolvers list, and only if the system DNS configuration doesn't work. It will never be used if lists have already been cached. People in China may need to use 114.114.114.114:53 here." + Fallback resolver. This is a normal, non-encrypted DNS resolver, that will be only used for one-shot queries when retrieving the initial resolvers list, and only if the system DNS configuration doesn\'t work. It will never be used if lists have already been cached. People in China may need to use 114.114.114.114:53 here. "Never let dnscrypt-proxy try to use the system DNS settings. Unconditionally use the fallback resolver.." "フィルタ" "Forwarding rules" "Route queries for specific domains to a dedicated set of servers." "Cloaking rules" - "Cloaking returns a predefined address for a specific name. -In addition to acting as a HOSTS file, it can also return the IP address of a different name. It will also do CNAME flattening.." + "Cloaking returns a predefined address for a specific name. In addition to acting as a HOSTS file, it can also return the IP address of a different name. It will also do CNAME flattening.." "ログの記録" "ファイルにログを書き出す" "ログ記録を有効化" "Do not log these query types, to reduce verbosity. Keep empty to log everything." "ログ記録を開く" "疑わしいログ" - "Log queries for nonexistent zones. -These queries can reveal the presence of malware, broken/obsolete applications, and devices signaling their presence to 3rd parties.." + "Log queries for nonexistent zones. These queries can reveal the presence of malware, broken/obsolete applications, and devices signaling their presence to 3rd parties.." "疑わしいログの記録を有効化" "疑わしいログを確認" "パターンベースブロッキング(ブラックリスト)" @@ -240,10 +237,10 @@ These queries can reveal the presence of malware, broken/obsolete applications, "Invizibleを利用しないアプリ" "全て選択" "選択を解除" - "一般的な設定" - "着信通信を許可" - "着信通信を待ち受けるためにこのポートを使用します。" - "着信通信のためのルーターの外部IP" + 一般的な設定 + 着信通信を許可 + 着信通信を待ち受けるためにこのポートを使用します。 + 着信通信のためのルーターの外部IP "IPv4経由の通信を有効化" "IPv6を利用して接続する" "Router will not accept transit tunnels, disabling transit traffic completely." @@ -252,7 +249,7 @@ These queries can reveal the presence of malware, broken/obsolete applications, "Max % of bandwidth limit for transit. 0–100." "SSU転送プロトコルを有効化(TCP)" "NTCP2転送プロトコルを有効化(TCP)" - "ntcpproxyを有効化" + ntcpproxyを有効化 "NTCP用のプロキシサーバーを指定してください。http://[アドレス]:[ポート] または socks://[アドレス]:[ポート] " "HTTPプロキシ" "HTTPプロキシ" @@ -269,14 +266,13 @@ These queries can reveal the presence of malware, broken/obsolete applications, "暗号方式" "Use ElGamal precomputated tables." "UPnPを有効化または無効します。" - "ntcp2は有効です。" "Reseeding" - ".su3署名を検証する" + "su3署名を検証する" "制限" "Override maximum number of transit tunnels. 2500 by default." "Limit number of open file descriptors (0 - use system limit)." - "コアファイルの最大サイズ(KB、0で無制限)" - "アドレスブック" + コアファイルの最大サイズ(KB、0で無制限) + アドレスブック "AddressBook subscription URL for initial setup." "アドレスブック購読URL" "設定ファイルi2pd.confが見つかりません!" @@ -310,12 +306,12 @@ These queries can reveal the presence of malware, broken/obsolete applications, "DNSCryptのアップデートが見つかりました。ダウンロードして更新しますか?アップデートはバックグラウンドで行われます。" "Torのアップデートが見つかりました。ダウンロードして更新しますか?このアップデートはバックグラウンドで行われます。" "Purple I2Pのアップデートが見つかりました。ダウンロードして更新しますか?このアップデートはバックグラウンドで行われます。" - "アップデートを確認中" - "アップデートを確認しています。しばらくお待ちください。" + アップデートを確認中 + アップデートを確認しています。しばらくお待ちください。 "アップデートサーバーは一時的に利用できません。後でお試しください。" "アップデートサーバーが利用できません。" "アップデートに失敗しました。" - "アップデートは見つかりませんでした。" + アップデートは見つかりませんでした。 "最終確認:" "アップデートが見つかりました。" "アップデートがインストールされました。" @@ -387,20 +383,20 @@ These queries can reveal the presence of malware, broken/obsolete applications, "New default Tor bridges are available. Do you want to update them?" "MITM攻撃を検出" "ARP偽装検出" - "APP偽装中間者攻撃やWi-FiネットワークのDHCP偽装攻撃を検出します。" + APP偽装中間者攻撃やWi-FiネットワークのDHCP偽装攻撃を検出します。 "攻撃が検出されたときインターネット接続をブロックする" "攻撃を受けている間インターネットに接続しないようにします。" "プロキシ" "Socks5プロキシを利用する" "Invizible Proが全ての通信でSocks5プロキシを経由するようにします。" "互換モード" - "カスタムロムを使用していて、スタートボタンを押したときインターネット接続が失われる場合はこのオプションを有効にしてください。" + カスタムロムを使用していて、スタートボタンを押したときインターネット接続が失われる場合はこのオプションを有効にしてください。 "スクリプトコントロールを有効化" "Use the following command to manage application modules: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module." "LAN内デバイスのIPアドレス" "TTLを防止し、LAN内デバイスがInvizibleに接続するように設定します。デフォルトゲートウェイ: %1$s DNSサーバー: %2$s" "マルチユーザーサポート" - "Island、ShelterやMIUIのデュアルアプリ機能などで仕事用プロファイル内で利用できるようにします。" + Island、ShelterやMIUIのデュアルアプリ機能などで仕事用プロファイル内で利用できるようにします。 "Socks出力プロキシを有効化" "Tor will make all OR connections through the SOCKS 5 proxy." "サービスを実行中" @@ -480,7 +476,7 @@ These queries can reveal the presence of malware, broken/obsolete applications, "Tor IP changing" "You have added more than 3 tiles to Quick Settings. Please leave only 3. Adding more than 3 tiles can cause issues with app control." "Rogue DHCP detection" - "Detect Man-in-the-middle rogue DHCP attacks in Wi-Fi networks." + Detect Man-in-the-middle rogue DHCP attacks in Wi-Fi networks. "Select rendezvous" "Hides the broker's domain name from the Internet provider. The broker is used to establish a connection." "Show all apps" diff --git a/tordnscrypt/src/main/res/values-nb-rNO/strings.xml b/tordnscrypt/src/main/res/values-nb-rNO/strings.xml index c23bddc67..4f3f70ea9 100644 --- a/tordnscrypt/src/main/res/values-nb-rNO/strings.xml +++ b/tordnscrypt/src/main/res/values-nb-rNO/strings.xml @@ -159,7 +159,6 @@ Port for SAM-bro. Forhåndsutregnede ElGamal-tabeller. Skru på eller av UPnP. - NTCP2 påskrudd Info Kun for Pro-versjon Skriv inn kode @@ -219,7 +218,7 @@ Doner Legg til egendefinert tjener Skru på SSU-transportprotokoll (bruker UDP). - Bekreft .su3-signatur + Bekreft su3-signatur Grenser Skriv inn kode Beskytt DNS med DNSCrypt diff --git a/tordnscrypt/src/main/res/values-pl/strings.xml b/tordnscrypt/src/main/res/values-pl/strings.xml index 15edc7345..59aefb1a6 100644 --- a/tordnscrypt/src/main/res/values-pl/strings.xml +++ b/tordnscrypt/src/main/res/values-pl/strings.xml @@ -58,9 +58,9 @@ "Wybierz folder kopii zapasowej:" "Ustawienia" "Uruchomienie automatyczne" - "Uruchom DNSCrypt przy starcie systemu" - "Uruchom Tor przy starcie systemu" - "Uruchom I2P przy starcie systemu" + Uruchom DNSCrypt przy starcie systemu + Uruchom Tor przy starcie systemu + Uruchom I2P przy starcie systemu "Opoznij" "Użyj opóźnienia (w sekundach) tylko wtedy, gdy Autostart nie działa prawidłowo" "Serwery DNSCrypt" @@ -69,17 +69,17 @@ "Ustawienia routingu" "Przekieruj caly ruch przez Tor" "Przekieruj caly ruch przez InviZible" - "Wybierz strony web" - "Lista stron web do otwierania przez Tor" - "Wybierz aplikacje" + Wybierz strony web + Lista stron web do otwierania przez Tor + Wybierz aplikacje "Lista aplikacji laczacych sie przez Tor" "Lista aplikacji laczacych sie przez InviZible" - "Wyklucz stony web" - "Lista stron web laczacych sie bezposrednio" - "Wyklucz aplikacje" + Wyklucz stony web + Lista stron web laczacych sie bezposrednio + Wyklucz aplikacje "Lista aplikacji laczacych sie bezposrednio" - "Czestotliwosc odswiezania" - "Czestotliwosc odswiezania IP stron w godzinach. Dla Androida 5.1 i wyzej. 0 blokuje odswiezanie." + Czestotliwosc odswiezania + Czestotliwosc odswiezania IP stron w godzinach. Dla Androida 5.1 i wyzej. 0 blokuje odswiezanie. "Mostki" "Zastosuj jesli nie mozesz polaczyc sie z siecia Tor" "Nie uzywaj mostkow" @@ -97,14 +97,14 @@ "Zapisz" "Zamknij" "Bledna nazwa hosta!" - "Wybierz schemat" - "Wybierz jezyk" + Wybierz schemat + Wybierz jezyk "Zablokuj ruch http" "Zablokuj polaczenia z portem http 80" "Aktualizacja" - "Aktualizacja automatyczna" - "Sprawdzaj aktualizacje InviZible Pro i modulow codziennie" - "Sprawdz aktualizacje" + Aktualizacja automatyczna + Sprawdzaj aktualizacje InviZible Pro i modulow codziennie + Sprawdz aktualizacje "Sprawdz czy sa dostepne nowe wersje" "Aktualizuj tylko przez Tor" "Sprawdzaj aktualizacje tylko przez Tor" @@ -114,29 +114,29 @@ "Inne" "Zablokuj Punkt Dostepu po http" "Odmow polaczenia na port http 80 dla Punktu Dostepu" - "Zapobiega zamknieciu aplikacji uruchomionej bez praw roota przez system" + Zapobiega zamknieciu aplikacji uruchomionej bez praw roota przez system "Odswiez reguly" "Zaktualizuj reguly przy kazdej zmianie lacznosci" "Pokaz powiadomienia" "Zapobiegaj uspieniu urzadzenia" - "Dodatkowa ochrona bez trybu rootowania, aby zapobiec uspieniu aplikacji przez Androida. Moze wyczeprac baterie" + Dodatkowa ochrona bez trybu rootowania, aby zapobiec uspieniu aplikacji przez Androida. Moze wyczeprac baterie "Podpowiedzi" - "Zawsze pokazuj podpowiedzi" + Zawsze pokazuj podpowiedzi Wyklucz InviZible Pro z optymalizacji baterii Androida, aby uniemożliwić systemowi zakończenie DNSCrypt, Tor lub I2P w dowolnym momencie. Niektóre specjalne systemy, takie jak MIUI, mogą wymagać dodatkowych kroków. "Wybierz BusyBox" "Punkt dostepu - eksperymentalnie" - "Autostart udostepniania polaczenia przy starcie systemu" - "Zezwol na udostepnianie polaczenia" + Autostart udostepniania polaczenia przy starcie systemu + Zezwol na udostepnianie polaczenia "Przekieruj caly ruch przez Tor" "Kieruj caly ruch przychodzacy przez Tor" - "Wybierz strony web" - "Strony otwierane w trybie Punktu Dostepu przez Tor" - "Wyklucz strony" - "Stony otwierane bezposrednio przez Punkt Dostepu" - "Zezwol na udostepnianie I2P" + Wybierz strony web + Strony otwierane w trybie Punktu Dostepu przez Tor + Wyklucz strony + Stony otwierane bezposrednio przez Punkt Dostepu + Zezwol na udostepnianie I2P "Naprawić TTL" - "TTL zostanie ustawione na 64 przy uzyciu lokalnej sieci VPN. Obsluga jadra nie jest wymagana. Mozna go uzywac tylko w \"root mode\" z wyłączoną opcją \"Run Modules With Root\". Aby naprawic TTL, uruchom DNSCrypt lub / i Tor." - "Otworz ustawienia Punktu Dostepu" + TTL zostanie ustawione na 64 przy uzyciu lokalnej sieci VPN. Obsluga jadra nie jest wymagana. Mozna go uzywac tylko w \"root mode\" z wyłączoną opcją \"Run Modules With Root\". Aby naprawic TTL, uruchom DNSCrypt lub / i Tor. + Otworz ustawienia Punktu Dostepu "Prosze zrestartowac DNSCrypt" "Prosze zrestartowac Tor" "Prosze zrestartowac I2P" @@ -158,29 +158,26 @@ "Serwer nie moze logowac zapytan (deklarajca serwera!)." "Serwer nie moze stosowac wlasnej blacklisty (kontrola rodzicielska, blok reklam…)." "Zawsze stosuj TCP do polaczenia z serwerem." - "Moze byc przydatne jesli przekierowujesz caly ruch przez Tor. -W innym przypadku zostaw odznaczone, i tak nie zwieksza ochrony prywatnosci (proksy dnscrypt i tak zaszyfruje wszytko nawet po UDP), i moze tylko zwiekszyc lagi." + "Moze byc przydatne jesli przekierowujesz caly ruch przez Tor. W innym przypadku zostaw odznaczone, i tak nie zwieksza ochrony prywatnosci (proksy dnscrypt i tak zaszyfruje wszytko nawet po UDP), i moze tylko zwiekszyc lagi." "Proxy SOCKS" "Uruchom proxy" "Przekieruj calosc ruchu TCP do Tora. Tor nie wspiera UDP - nalezy ustawic rowniez force_tcp." "port_proxy" "Inne ustawienia." - "Serwer zapasowy. To jest normalny, nieszyfroway serwer DNS, ktory bedzie wykorzystwany tylko dla jednorazowych zapytan przy pobieraniu listy serwerow TYLKO jesli systemowy DNS nie bedzie dostepny. Nie zostanie uzyty jesli bedzie istniala kopia listy serwerow." + Serwer zapasowy. To jest normalny, nieszyfroway serwer DNS, ktory bedzie wykorzystwany tylko dla jednorazowych zapytan przy pobieraniu listy serwerow TYLKO jesli systemowy DNS nie bedzie dostepny. Nie zostanie uzyty jesli bedzie istniala kopia listy serwerow. "Nie zezwalaj proxy dnscrypt uzywac systemowego DNS. Bezwarunkowo stosuj serwer zapasowy." "FILTRY" "Reguly przekierowan" "Przekierowuj zapytania do wybranych domen przez wybrana grupe serwerow." "Reguly maskujace" - "Maskowanie zwraca predefiniowany adres dla specyficznych nazw. -Pracuje jak plik HOSTS, a takze zwraca adres IP innej nazwy. Wykonuje tez flattening CNAME." + "Maskowanie zwraca predefiniowany adres dla specyficznych nazw. Pracuje jak plik HOSTS, a takze zwraca adres IP innej nazwy. Wykonuje tez flattening CNAME." "Logowanie zapytan." "Zapisuj log zapytan klientow do pliku." "Uruchom logowanie zapytan" "Nie zapisuj zapytan tego typu by zredukowac nadmiarowe dane. Zostaw puste by logowac wszystko." "Otworz log zapytan" "Logowanie podejrzanych zapytan." - "Logowanie zapytan do nieistniejacych stref. -Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych aplikacji, oraz raportowanie obecnosci przez urzadzenie do innych podmiotow." + "Logowanie zapytan do nieistniejacych stref. Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych aplikacji, oraz raportowanie obecnosci przez urzadzenie do innych podmiotow." "Wlacz logowanie podejrzanych" "Otworz log podejrzanych zapytan" "Lista blokowania (blacklista)." @@ -240,10 +237,10 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Aplikacje pomijajace InviZible" "Zaznacz wszystko" "Usun zaznaczenie" - "Ustawienia wspolne" - "Zezwol na polaczenia przychodzace" - "Port nasluchu polaczen przychodzacych." - "Zewnetrzne IP dla polaczen przychodzacych." + Ustawienia wspolne + Zezwol na polaczenia przychodzace + Port nasluchu polaczen przychodzacych. + Zewnetrzne IP dla polaczen przychodzacych. "Umozliw komunikacje po IPv4." "Umozliw komunikacje po IPv6." "Router nie bedzie akceptowac ruchu tunelowego, calkowicie go blokujac." @@ -252,7 +249,7 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Max % pasma na ruch tranzytowy. 0–100." "Uruchom protokol transferu SSU (uzyj UDP)." "Uruchom protokol transferu NTCP2 (uzyj TCP)." - "Uruchom ntcpproxy" + Uruchom ntcpproxy "Okresl serwer proxy dla NTCP. Albo http://address:port albo socks://address:port." "proxy HTTP" "proxy HTTP" @@ -269,14 +266,13 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Kryptografia" "Uzyj predefiniowanych tablic ElGamal." "Udostepnij lub zablokuj UPnP." - "ntcp2 udostepnione" "Reseeding" - "Zweryfikuj podpis .su3." + "Zweryfikuj podpis su3." "Ograniczenia" "Zmien maksymalna ilosc tuneli tranzytowych. Domyslnie 2500." "Ogranicz ilosc deskryptorow plikow (0 - zastosuj ograniczenie systemowe)." - "Maksymalna wielkosc corefile w Kb (0 - zastosuj ograniczenie systemowe)." - "Ksiazka adresowa" + Maksymalna wielkosc corefile w Kb (0 - zastosuj ograniczenie systemowe). + Ksiazka adresowa "Subskrybcja URL ksiazki adresowej dla ustawien poczatkowych." "URL subskrybcji ksiaki adresowej." "Ustawienie nie istnieje w i2pd.conf!" @@ -310,12 +306,12 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Jest dostepna aktualizacja DNSCrypt. Czy chcesz ja sciagnac i wykonac aktualizacje? Aktualizacja będzie kontynuowana w tle." "Jest dostepna aktualizacja Tora. Czy chcesz ja sciagnac i wykonac aktualizacje? Aktualizacja będzie kontynuowana w tle." "Jest dostepna aktualizacja Purple I2P. Czy chcesz ja sciagnac i wykonac aktualizacje? Aktualizacja będzie kontynuowana w tle." - "Sprawdzam aktualizacje" - "Prosze czekac, sprawdzam aktualizacje." + Sprawdzam aktualizacje + Prosze czekac, sprawdzam aktualizacje. "Serwer aktualizacji jest czasowo niedostepny. Prosze sprobowac  pozniej." "Serwer aktualizacji jest niedostepny." "Blad aktualizacji." - "Brak dostepnych aktualizacji." + Brak dostepnych aktualizacji. "Ostatnio sprawdzono:" "Znaleziono aktualizacje." "Aktualizacje zostaly zainstalowane." @@ -386,20 +382,20 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Sa dostepne nowe domyslne mostki Tor. Czy chcesz wykonac aktualizacje?" "Wykrywanie ataku MITM" "Wykrywanie ARP spoofing" - "Wykrywanie atakow MITM, ARP spofing oraz atakow rogue DHCP w sieciach WiFi" + Wykrywanie atakow MITM, ARP spofing oraz atakow rogue DHCP w sieciach WiFi "W przypadku wykrycia ataku, blokuj polaczenie z siecia" "Polaczenie z internetem bedzie zablokowane podczas ataku." "Proxy" "Uzyj proxy socks5" "InviZible przekieruje wszystkie polaczenia przez proxy SOCKS5" "Tryb zgodnosci" - "Aktywuj jesli masz urzadzenie z modyfikowanym ROMem oraz jesli przycisniecie Start powoduje zerwanie polaczenia" + Aktywuj jesli masz urzadzenie z modyfikowanym ROMem oraz jesli przycisniecie Start powoduje zerwanie polaczenia "Aktywuj skrypt kontrolny" "Aby zarzadzac modulami, uzyj nastepujacej komendy: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Gdzie 1 - uruchamia, 0 - zatrzymuje modul." "Adres IP urzadzenia LAN" "Aktywuj Fix TTL i skonfiguruj urzadzenie LAN dla polaczenia InviZible. Uzyj domyslnie: gateway: %1$s, Serwer DNS: %2$s" "Wsparcie trybu multi-user" - "Wsparcie Dual Apps, MIUI, profili Island, Shelter i Work" + Wsparcie Dual Apps, MIUI, profili Island, Shelter i Work "Aktywuj proxy wychozace SOCKS" "Tor przekieruje wszystkie polaczenia OR przez proxy SOCKS 5" "Uruchomione uslugi" @@ -508,23 +504,21 @@ Takie zapytania moga wskazywac na obecnosc malware, uszkodzonych/przestarzalych "Zestaw uzytych prefixow IPv6." "Mostki IPv6" "Uwaga" - "Blad uruchomienia InviZible Pro %1$s! Zmien ustawienia %2$s . Jesli nie pomoze - uruchom urzadzenie ponownie." + Blad uruchomienia InviZible Pro %1$s! Zmien ustawienia %2$s . Jesli nie pomoze - uruchom urzadzenie ponownie. "Reset" "Uruchom spoofing SNI" "Tor zapamieta i zapisze niedawne polaczenia do hsotow i sprobuje uzyc tych samych exit node dla kazdego z nich. To moze pomoc uniknac petli captcha." - \\ Dziękujemy za wybranie InviZible Pro. Jestem pewien, że zwiększy to Twoją prywatność i zapewni płynne korzystanie z Internetu. -\n -\n\tInviZible Pro zawiera moduły Tor, DNSCrypt i Purple I2P. -\n -\n\tInviZible Pro może korzystać z roota, jeśli Twoje urządzenie jest zrootowane lub korzysta z lokalnej sieci VPN, aby dostarczać ruch internetowy bezpośrednio do sieci Tor, DNSCrypt i I2P. -\n -\n\tPolityka prywatności: -\n\tInviZible Pro nie gromadzi ani nie udostępnia żadnych osobistych lub wrażliwych danych użytkownika. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy + + \tDziękujemy za wybranie InviZible Pro. Jestem pewien, że zwiększy to Twoją prywatność i zapewni płynne korzystanie z Internetu. + \n\n\tInviZible Pro zawiera moduły Tor, DNSCrypt i Purple I2P. + \n\n\tInviZible Pro może korzystać z roota, jeśli Twoje urządzenie jest zrootowane lub korzysta z lokalnej sieci VPN, aby dostarczać ruch internetowy bezpośrednio do sieci Tor, DNSCrypt i I2P. + \n\n\tPolityka prywatności: + \n\tInviZible Pro nie gromadzi ani nie udostępnia żadnych osobistych lub wrażliwych danych użytkownika. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + Naciśnij, aby dodać. Zaprzestać optymalizacji zużycia baterii? Wyklucz z sieci Tor diff --git a/tordnscrypt/src/main/res/values-pt-rBR/strings.xml b/tordnscrypt/src/main/res/values-pt-rBR/strings.xml index ec76af66b..63286054e 100644 --- a/tordnscrypt/src/main/res/values-pt-rBR/strings.xml +++ b/tordnscrypt/src/main/res/values-pt-rBR/strings.xml @@ -60,9 +60,9 @@ "Escolha uma pasta de backup:" "Configurações" "Iniciar automaticamente" - "Iniciar o DNSCrypt durante o boot" - "Iniciar o Tor durante o boot" - "Iniciar o I2p durante o boot" + Iniciar o DNSCrypt durante o boot + Iniciar o Tor durante o boot + Iniciar o I2p durante o boot "Atraso" Utilize o delay (em segundos) somente se a inicialização automática não funcionar corretamente "Servidores DNSCrypt" @@ -71,17 +71,17 @@ "Configurações de roteamento" "Rotear todo o tráfego através do Tor" "Rotear todo o tráfego através do InviZible" - "Selecionar websites" - "Lista de websites para abrir com o Tor" - "Selecionar aplicativos" + Selecionar websites + Lista de websites para abrir com o Tor + Selecionar aplicativos "Lista de aplicativos para utilizar com o Tor" "Lista de aplicativos para usar com o InviZible" - "Websites ignorados" - "Lista de websites para abrir diretamente" - "Ignorar aplicativos" + Websites ignorados + Lista de websites para abrir diretamente + Ignorar aplicativos "Lista de aplicativos para abrir diretamente" - "Intervalo de atualização" - "Período, em horas, para atualizar os IPs dos websites; Para o Android 5.1 e superior. Coloque 0 para parar a atualização." + Intervalo de atualização + Período, em horas, para atualizar os IPs dos websites; Para o Android 5.1 e superior. Coloque 0 para parar a atualização. "Pontes" "Use isso se você não conseguir se conectar a rede Tor" "Não usar Pontes" @@ -99,14 +99,14 @@ "Salvar" "Fechar" "Hostname inválido!" - "Selecionar tema" - "Selecionar idioma" + Selecionar tema + Selecionar idioma "Bloquear http" "Negar conexões para o http porta 80" "Atualizações" - "Atualização automática" - "Verificar por atualizações do InviZible Pro e de seus módulos diariamente" - "Verificar atualizações" + Atualização automática + Verificar por atualizações do InviZible Pro e de seus módulos diariamente + Verificar atualizações "Verificar se alguma nova versão está disponível agora" "Atualizar estritamente através do Tor" "Verificar atualizações somente com e quando o Tor estiver em execução" @@ -116,34 +116,34 @@ "Outro" "Bloquear HOTSPOT hhtp" "Negar conexão para o http na porta 80 para o HOTSPOT" - "Proteger o aplicativo no modo sem Root para prevenir que o Android mate o processo" + Proteger o aplicativo no modo sem Root para prevenir que o Android mate o processo "Atualizar regras" "Atualizar regras toda vez que a conexão mudar" "Mostrar notificação" "Impedir que o dispositivo durma" - "Proteção adicional no modo sem Root para prevenir que o aplicativo seja morto pelo Android. Pode drenar bateria" + Proteção adicional no modo sem Root para prevenir que o aplicativo seja morto pelo Android. Pode drenar bateria "Mensagens de ajuda" - "Sempre mostrar mensagens de ajuda" + Sempre mostrar mensagens de ajuda Por favor, exclua o InviZible Pro da otimização de bateria do Android. Caso contrário, o android parará o DNSCrypt, Tor ou I2P em qualquer momento. Em sistemas especiais, como o MIUI, são necessários alguns passos adicionais. "Selecionar BusyBox" "HOTSPOT-Experimental" - "Iniciar Tethering durante o Boot" + Iniciar Tethering durante o Boot - "Permir Tor Tethering" + Permir Tor Tethering "Rotear tudo através do Tor" "Rotear todo tráfego de entrada através do Tor" - "Selecionar websites" + Selecionar websites - "Lista de websites para abrir com o Tor pelo HOTSPOT" - "Excluir websites" + Lista de websites para abrir com o Tor pelo HOTSPOT + Excluir websites - "Lista de websites para abrir diretamente pelo HOTSPOT" - "Permitir I2P Tethering" + Lista de websites para abrir diretamente pelo HOTSPOT + Permitir I2P Tethering "Corrigir TTL" - "O TTL será fixado em 64 usando uma VPN local. O suporte ao kernel não é necessário. Ele só pode ser usado no \"modo Root\" com a opção \"Executar módulos com Root\" desabilitada. Para corrigir o TTL, inicie DNSCrypt ou / e Tor." - "Abrir configurações do Tethering" + O TTL será fixado em 64 usando uma VPN local. O suporte ao kernel não é necessário. Ele só pode ser usado no \"modo Root\" com a opção \"Executar módulos com Root\" desabilitada. Para corrigir o TTL, inicie DNSCrypt ou / e Tor. + Abrir configurações do Tethering "Por favor, reinicie o DNSCrypt" "Por favor, reinicie o Tor" "Por favor, reinicie o I2P" @@ -166,8 +166,7 @@ O servidor não deve forçar sua própria lista negra (para controle parental, bloqueio de propaganda…). "Sempre usar TCP para conectar com os servidores upstream." - Isso pode ser útil se você precisar rotear tudo através do Tor.. -\n Caso contrário, deixe como falso, pois isso não melhora a segurança (dnscrypt-proxy sempre criptografará tudo, mesmo usando UDP) e só aumentará a latência. + Isso pode ser útil se você precisar rotear tudo através do Tor.. Caso contrário, deixe como falso, pois isso não melhora a segurança (dnscrypt-proxy sempre criptografará tudo, mesmo usando UDP) e só aumentará a latência. SOCKS Proxy. "Ativar proxy" "Roteie todas as conexões TCP para um nó Tor local. Tor não suporta UDP, então defina force_tcp como true também." @@ -181,8 +180,7 @@ Regras de encaminhamento "Roteie as consultas de domínios específicos para um conjunto dedicado de servidores." Regras de camuflagem - Cloaking retorna um endereço predefinido para um nome específico. -\n Além de atuar como um arquivo HOSTS, ele também pode retornar o endereço IP de um nome diferente. Ele também fará o nivelamento de CNAME. + Cloaking retorna um endereço predefinido para um nome específico. Além de atuar como um arquivo HOSTS, ele também pode retornar o endereço IP de um nome diferente. Ele também fará o nivelamento de CNAME. "Log de consulta." Salvar logs das queries do cliente para um arquivo. @@ -192,8 +190,7 @@ "Abrir log de consulta" "Log de consultas suspeitas." - "Log de consultas para zonas inexistentes. -Essas consultas podem revelar a presença de malware, aplicativos quebrados / obsoletos e dispositivos sinalizando sua presença para terceiros." + "Log de consultas para zonas inexistentes. Essas consultas podem revelar a presença de malware, aplicativos quebrados / obsoletos e dispositivos sinalizando sua presença para terceiros." "Ativar log de consultas suspeitas" "Abrir log de consultas suspeitas" @@ -258,10 +255,10 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob "Apps para contornar InviZible" "Selecionar todos" "Remover Seleção" - "Configurações padrão" - "Permitir conexões de entrada" - "Porta para escutar conexões de entrada." - "IP externo do roteador para conexões de entrada." + Configurações padrão + Permitir conexões de entrada + Porta para escutar conexões de entrada. + IP externo do roteador para conexões de entrada. "Ative a comunicação por meio de IPv4." "Ative a comunicação por meio de IPv6." "O roteador não aceitará túneis de trânsito, desativando completamente o tráfego de trânsito." @@ -270,7 +267,7 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob Máx % limite de largura de banda para trânsito. 0–100. "Habilite protocolo de transporte SSU (use UDP)." "Habilite protocolo de transporte NTCP2 (use TCP)." - "Habilite ntcpproxy" + Habilite ntcpproxy "Especifique o servidor proxy para NTCP. Deve ser http://endereço:porta ou socks://endereço:porta." "HTTP proxy" "HTTP proxy" @@ -287,14 +284,13 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob "Criptografia" "Use tabelas pré-computadas ElGamal." Habilite ou desabilite o UPnP. - "Habilite ntcp2" "Reseeding" - "Verifique a assinatura .su3." + "Verifique a assinatura su3." "Limites" Substitua o número máximo de túneis de trânsito. 2500 por padrão. "Limite o número de descritores de arquivos abertos (0 - uso limite do sistema)." - "Tamanho máximo do corefile em Kb (0 - limite do sistema de uso)." - "Addressbook" + Tamanho máximo do corefile em Kb (0 - limite do sistema de uso). + Addressbook "URL de assinatura do AddressBook para configuração inicial." "URLs de assinaturas do AdressBook." "Não existe preferencia no arquivo i2pd.conf!" @@ -328,12 +324,12 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob "A atualização do DNSCrypt Pro está disponível. Quer fazer o download e atualizá-lo? A atualização continuará em segundo plano." "A atualização do Tor está disponível. Quer fazer o download e atualizá-lo? A atualização continuará em segundo plano." "A atualização do I2P está disponível. Quer fazer o download e atualizá-lo? A atualização continuará em segundo plano." - "Verificar Atualizações" - "Aguarde enquanto as atualizações estão sendo verificadas." + Verificar Atualizações + Aguarde enquanto as atualizações estão sendo verificadas. "O servidor de atualização está temporariamente indisponível. Por favor, tente novamente mais tarde." "O servidor de atualização não estava disponível." "Falha de atualização." - "Nenhuma atualização foi encontrada." + Nenhuma atualização foi encontrada. "Última verificação:" "Atualizações foram encontradas." "Atualizações foram instaladas." @@ -405,20 +401,20 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob Novas pontes Tor padrão estão disponíveis. Você deseja atualizá-las\? "Detecção de ataque MITM" "Detecção de spoofing de ARP" - "Detecte spoofing de ARP man-in-the-middle e ataques DHCP desonestos em redes Wi-Fi." + Detecte spoofing de ARP man-in-the-middle e ataques DHCP desonestos em redes Wi-Fi. "Bloquear internet quando um ataque for detectado" "A conexão com a Internet será bloqueada durante o ataque" "Proxy" Usar proxy socks5 "InviZible Pro fará todas as conexões através do proxy SOCKS5" "Modo de compatibilidade" - "Ative se o seu dispositivo com uma ROM personalizada e a conexão for perdida quando você pressiona o botão INICIAR" + Ative se o seu dispositivo com uma ROM personalizada e a conexão for perdida quando você pressiona o botão INICIAR "Habilitar controle de script" "Use o seguinte comando para gerenciar os módulos do aplicativo: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Onde 1 - inicia, 0 - para o módulo." "Endereço IP do dispositivo LAN" "Habilite Fix TTL e configure o dispositivo LAN para se conectar ao InviZible. Use o gateway padrão: %1$s, servidor DNS: %2$s." "Suporte multiusuário" - "Suporte para aplicativos duplos, MIUI, Island, Shelter e aplicativos de perfil de trabalho" + Suporte para aplicativos duplos, MIUI, Island, Shelter e aplicativos de perfil de trabalho "Habilitar proxy de saída SOCKS" "O Tor fará todas as conexões OR por meio do proxy SOCKS 5." "Serviços Rodando" @@ -498,7 +494,7 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob "Alterando IP Tor" Você adicionou mais de 3 blocos às Configurações Rápidas. Por favor, deixe apenas 3. Adicionar mais de 3 blocos pode causar problemas com o controle de aplicativos. "Detecção de DHCP desonesto" - "Detectar os ataques Man-in-the-middle de falso DHCP em redes Wi-Fi." + Detectar os ataques Man-in-the-middle de falso DHCP em redes Wi-Fi. "Select rendezvous" "Oculta o nome de domínio do broker do provedor de Internet. O broker é usado para estabelecer uma conexão." "Mostrar todos os aplicativos" @@ -519,17 +515,15 @@ Essas consultas podem revelar a presença de malware, aplicativos quebrados / ob "Internet connectivity check" "Real-time logs" "Show application connection logs in the DNS tab" - \\\tObrigado porescolher o InviZible Pro. Espero que seja útil para a sua privacidade e conforto no uso da Internet. -\n -\n\tInviZible Pro inclui Tor, DNSCrypt e Purple I2P como módulos. -\n -\n\tO InviZible Pro pode usar root, se seu dispositivo tiver privilégios de root, ou usa uma VPN local para transmitir tráfego de Internet para redes Tor, DNSCrypt e I2P. -\n -\n\tPolítica de Privacidade: -\n\tO InviZible Pro não coleta ou compartilha nenhum dado pessoal ou sensível do usuário. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy - \ No newline at end of file + + \tObrigado porescolher o InviZible Pro. Espero que seja útil para a sua privacidade e conforto no uso da Internet. + \n\n\tInviZible Pro inclui Tor, DNSCrypt e Purple I2P como módulos. + \n\n\tO InviZible Pro pode usar root, se seu dispositivo tiver privilégios de root, ou usa uma VPN local para transmitir tráfego de Internet para redes Tor, DNSCrypt e I2P. + \n\n\tPolítica de Privacidade: + \n\tO InviZible Pro não coleta ou compartilha nenhum dado pessoal ou sensível do usuário. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + + diff --git a/tordnscrypt/src/main/res/values-pt/strings.xml b/tordnscrypt/src/main/res/values-pt/strings.xml index 575b28d2a..b593699a8 100644 --- a/tordnscrypt/src/main/res/values-pt/strings.xml +++ b/tordnscrypt/src/main/res/values-pt/strings.xml @@ -331,8 +331,7 @@ Criptografia Use tabelas pré-computadas ElGamal. Ative ou desative o UPnP. - Ative ntcp2 - Verifique a assinatura .su3. + Verifique a assinatura su3. Limites Substitua a quantidade máxima de túneis de trânsito. 2500 por padrão. Limite a quantidade de descritores de ficheiros abertos (0 - uso limite do sistema). @@ -401,19 +400,17 @@ O Projeto InviZible Pro precisa da sua ajuda. Pressione OK para adquirir recursos premium. Desculpe, mas é impossível confirmar a sua compra. Receberá um reembolso após 3 dias. Infelizmente, esse recurso está disponível apenas para a versão premium. - \\\tObrigado porescolher o InviZible Pro. Espero que seja útil para a sua privacidade e conforto no uso da Internet. -\n -\n\tInviZible Pro inclui Tor, DNSCrypt e Purple I2P como módulos. -\n -\n\tO InviZible Pro pode usar root, se o seu aparelho tiver privilégios de root, ou usa uma VPN local para transmitir tráfego de Internet para redes Tor, DNSCrypt e I2P. -\n -\n\tPolítica de Privacidade: -\n\tO InviZible Pro não coleta ou compartilha nenhum dado pessoal ou sensível do utilizador. -\n -\n\tCopyright © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy + + \tObrigado porescolher o InviZible Pro. Espero que seja útil para a sua privacidade e conforto no uso da Internet. + \n\n\tInviZible Pro inclui Tor, DNSCrypt e Purple I2P como módulos. + \n\n\tO InviZible Pro pode usar root, se o seu aparelho tiver privilégios de root, ou usa uma VPN local para transmitir tráfego de Internet para redes Tor, DNSCrypt e I2P. + \n\n\tPolítica de Privacidade: + \n\tO InviZible Pro não coleta ou compartilha nenhum dado pessoal ou sensível do utilizador. + \n\n\tCopyright © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + Quer gravar as alterações\? Ele pode quebrar o InviZible Pro. Serviços A executar Notificações de atualização @@ -470,15 +467,12 @@ Novas pontes padrão de Tor estão disponíveis. Deseja atualizá-las\? Usar proxy socks5 HOTSPOT-Experimental - Isto pode ser útil se precisar de rotear tudo através do Tor. -\n Caso contrário, deixe-o em falso, pois não melhora a segurança (o dnscrypt-proxy sempre criptografará tudo, mesmo usando UDP) e só pode aumentar a latência. + Isto pode ser útil se precisar de rotear tudo através do Tor. Caso contrário, deixe-o em falso, pois não melhora a segurança (o dnscrypt-proxy sempre criptografará tudo, mesmo usando UDP) e só pode aumentar a latência. Proxy SOCKS. Regras de encaminhamento Regras de camuflagem - A cmulfagem retorna um endereço predefinido para um nome específico. -\n Além de atuar como um ficheiro HOSTS, também pode retornar o endereço IP de um nome diferente. Também fará o achatamento do CNAME.. - Registar consultas para regiões inexistentes. -\n Essts consultas podem revelar a presença de malware, aplicações quebradas/obsoletas e aparelhos sinalizando a presença deles a terceiros. + A cmulfagem retorna um endereço predefinido para um nome específico. Além de atuar como um ficheiro HOSTS, também pode retornar o endereço IP de um nome diferente. Também fará o achatamento do CNAME.. + Registar consultas para regiões inexistentes. Essts consultas podem revelar a presença de malware, aplicações quebradas/obsoletas e aparelhos sinalizando a presença deles a terceiros. Lista de permissões Uma lista de códigos de país a usar como nó de saída - ou seja, um nó que entrega tráfego para si para fora da rede Tor. Abra esta porta para escutar conexões de aplicações que falam SOCKS. @@ -492,4 +486,4 @@ Adicionou mais que 3 blocos às Configurações Rápidas. Por favor, deixe apenas 3. Adicionar mais de 3 blocos pode causar problemas com o controlo de apps. Contactos Reseeding - \ No newline at end of file + diff --git a/tordnscrypt/src/main/res/values-ru/strings.xml b/tordnscrypt/src/main/res/values-ru/strings.xml index 0c1386f87..29c418f72 100644 --- a/tordnscrypt/src/main/res/values-ru/strings.xml +++ b/tordnscrypt/src/main/res/values-ru/strings.xml @@ -96,13 +96,12 @@ Выбрать язык Использовать Root привилегии Запуск модулей с Root - Использовать Root привилегии для модулей DNSCrypt, Tor и I2P. - Включение этой функции оставляет модули неуправляемыми, и может вызвать проблемы с подключением! + Использовать Root привилегии для модулей DNSCrypt, Tor и I2P. Включение этой функции оставляет модули неуправляемыми, и может вызвать проблемы с подключением! Другие - Защитите приложение в Безрутовом Режиме, чтоб андроид не завершил его + Защитите приложение, чтоб андроид не завершил его Показывать уведомление Показывать справку - Всегда показывать справочные сообщения + Показывать все сообщения, ранее отмеченные как неразрешенные к показу Выключить оптимизацию батареи? Пожалуйста, исключите InviZible Pro из списка оптимизации энергопотребления. Иначе андроид может завершить DNSCrypt, Tor или I2P в любой момент. Для некоторых оболочек, например MIUI, могут потребоваться дополнительные настройки. Отключить экономию трафика? @@ -123,9 +122,7 @@ Список сайтов, которые открываются в обход Tor, для точки доступа Разрешить раздачу I2P Зафиксировать TTL - TTL будет зафиксирован на 64 с помощью локального VPN. Поддержка ядра не требуется. - Можно использовать только в \"root mode\" и с выключенной опцией \"Запуск модулей с Root\". - Чтобы зафиксировать TTL запустите DNSCrypt и/или Tor. + TTL будет зафиксирован на 64 с помощью локального VPN. Поддержка ядра не требуется. Чтобы зафиксировать TTL запустите DNSCrypt и/или Tor. Открыть настройки точки доступа Пожалуйста, перезапустите Tor Пожалуйста, перезапустите I2P @@ -139,54 +136,52 @@ Выполнение Рут команд… Пожалуйста подождите… Настройки сохранены - ОБЩИЕ НАСТРОЙКИ + Общие настройки Только для опытных пользователей! Выберите хотя бы один сервер! Номер порта. - Фильтровать сервера по параметрам. + Фильтровать сервера по параметрам Использовать сервера, которые поддерживают протокол DNSCrypt. Использовать сервера, которые поддерживают протокол DNS-over-HTTPS. - Фильтровать сервера по параметрам. + Использовать сервера, которые поддерживают протокол Oblivious DNS-over-HTTPS. + Фильтровать сервера по параметрам Использовать сервера, которые поддерживают безопасное расширение DNS - (DNSSEC). - Использовать сервера, которые не логируют запросы (обещают:)). + Использовать сервера, которые не логируют запросы (декларативно). Сервера не должны использовать черный список (для родительского контроля, блокировки рекламы…). - Всегда использовать TCP протокол, для соединения с серверами. - Это может быть полезным, когда вы перенаправляете весь трафик через Tor. - Иначе не активируйте, так как это не улучшит безопасность. DNSCrypt и так шифрует все запросы, даже через UDP. А задержки могут увеличиться. - SOCKS прокси. - Включить прокси - Перенаправить все TCP соединения на Tor. Он не поддерживает UDP, поэтому обязательно активируйте force_tcp. - Прокси порт - Другие настройки. - Не позволять dnscrypt-proxy использовать системные настройки DNS. Использовать сервер для восстановления.. + Всегда использовать TCP протокол, для соединения с серверами + Использовать TCP вместо UDP для подключения к серверам DNSCrypt. Этот параметр должен быть включен, если вы используете DNSCrypt через Tor. + SOCKS прокси + Исходящий прокси + Перенаправить все TCP соединения на входящий Socks5 прокси Tor. Tor не поддерживает UDP, поэтому обязательно активируйте Force TCP. + Порт прокси + Другие настройки + Не позволять DNSCrypt использовать системные настройки DNS. Использовать Сервер для начальной загрузки. Сервер для начальной загрузки. Это обычный сервер, который не поддерживает шифрование. Используется только для скачивания списка серверов, которые поддерживают шифрование, если системный DNS сервер не работает. Он никогда не используется, если загружен список серверов, которые поддерживают шифрование. - ФИЛЬТРЫ + Фильтры Перенаправить запросы к выбранным сайтам на определенные сервера. - Cloaking возвращает предопределенные адреса для выбранных сайтов. -\n Работает как дополнительный HOSTS файл. - Логировать запросы. + Cloaking возвращает предопределенные адреса для выбранных сайтов. Работает как дополнительный HOSTS файл. + Логировать запросы Записывать лог в файл. - Включить лог + Лог запросов Не логировать эти типы запросов. Оставьте пустым, чтоб логировать все. Открыть лог запросов - Логировать подозрительные запросы. - Логировать запросы к несуществующим зонам. -\n Эти запросы могут показать наличие вредоносов или неправильных приложений. А также передачу информации о их наличии третьей стороне.. - Включить лог + Логировать подозрительные запросы + Логировать запросы к несуществующим зонам. Эти запросы могут показать наличие вредоносов или неправильных приложений. А также передачу информации о их наличии третьей стороне. + Лог подозрительных запросов Открыть лог запросов - Черный список сайтов. + Черный список сайтов Черный список Черный список формируется одним сайтом в строчке. - Черный список IP. + Черный список IP Черный список IP Черный список формируется одним IP в строчке. - Белый список (обход черного списка). + Белый список (обход черного списка) Белый список Если имя сайта совпадает с записью в списке, к нему доступ будет осуществляться в обход черных списков. Сервера Источники Список серверов. - Список серверов будет обновлен после refresh_delay в часах. + Список серверов будет обновлен после указанной задержки в часах. Настройка не существует в dnscrypt-proxy.toml! Удалить лог Лог запросов DNS @@ -196,28 +191,27 @@ Немедленно отвечать на запросы к локальным зонам вместо их утечки резолверам, что всегда приводит к ошибкам и лагам. Необходимо, чтоб Tor назначил неиспользованный виртуальный диаппазон адресов, для доступа к сайтам в зоне .onion. Попытаться уменьшить частоту записи на диск. - Эта опция указывает Tor использовать padding, для - предотвращения некоторых форм анализа трафика. Выключите, чтоб уменьшить траффик. - Если активированно, Tor не будет слишком - долго удерживать соединение. Включите, чтоб уменьшить траффик. + Эта опция указывает Tor использовать padding, для предотвращения некоторых форм анализа трафика. Выключите, чтоб уменьшить траффик. + Если активированно, Tor не будет слишком долго удерживать соединение. Включите, чтоб уменьшить траффик. + Ноды + Настройки изолирования Список стран, которые НЕ будут использоваться для ВЫХОДНОГО сервера. Список стран, которые будут использоваться для ВЫХОДНОГО сервера. Список стран, которые НЕ будут использоваться для построения цепочки в сети Tor. Список стран, которые будут использоваться как ВХОДНЫЕ сервера. - Если активированно, Tor будет строго следовать правилам - ExcludeNodes, даже если будет невозможно установить соединение. + Если активированно, Tor будет строго следовать правилам ExcludeNodes, даже если будет невозможно установить соединение. Если активированно, Tor будет создавать исходящие соединения только на разрешенных портах (80 и 443 по умолчанию). + Чтобы активировать эту опцию, необходимо отключить мосты, или использовать мосты только с 80 и 443 портами. Количество секунд перед построением новой цепочки. - Свободно переиспользовать цепочку через заданное - количество секунд, но никогда не присоединяться к цепочке, если она слишком старая. + Свободно переиспользовать цепочку через заданное количество секунд, но никогда не присоединяться к цепочке, если она слишком старая. Если активированно, Tor никогда не будет выбирать два сервера, чьи IP адреса слишком близко, для одной и той же цепочки. На данный момент IP серверов считается слишком близкими, если они находятся в одном /16 диаппазоне. - Включить SOCKS прокси + SOCKS прокси Открыть этот порт для приложений, поддерживающих SOCKS проксификацию. - Активировать HTTPTunnel + HTTP Tunnel Открыть этот порт для приложений, поддерживающих HTTP CONNECT проксификацию, вместо SOCKS. - Активировать Прозрачный прокси + Прозрачный прокси Открыть этот порт для Прозрачного прокси. - Включить DNS + Разрешать DNS Открыть этот порт для UDP DNS запросов, и анонимного ответа. Если ВЫКЛЮЧИТЬ, Tor будет избегать соединений с входными серверами, использующими IPv4. Если ВКЛЮЧИТЬ, Tor может пытаться соединиться с входными серверами, использующими IPv6. @@ -232,12 +226,12 @@ Tor переходит в режим ожидания, если не видит активности клиента в течении заданного времени. Должно быть не менее 10 минут. Активировать все Деактивировать все - Общие Настройки - Разрешить входящие соединения - Порт для входных подключений. - Внешний IP для входящих соединений. - Включить соединение через IPv4. - Включить соединение через IPv6. + Общие настройки + Входящие соединения + Порт для входных подключений (по умолчанию: auto (random)). + Внешний IP для входящих соединений (по умолчанию: auto если включен SSU2). + Разрешить соединение через IPv4. + Разрешить соединение через IPv6. Не разрешать транзитные туннели. Отключает транзит полностью. Устройство будет \"ненасытным\". Ограничение полосы пропускания в KBps. @@ -245,7 +239,7 @@ Включить SSU протокол (использовать UDP). Включить SSU2 протокол (использовать UDP). Включить NTCP2 протокол (использовать TCP). - Включить ntcpproxy + Выходной прокси Выбрать прокси сервер для NTCP. Должно быть http://address:port или socks://address:port. HTTP proxy порт HTTP прокси @@ -262,8 +256,7 @@ Криптография Использовать таблицы ElGamal. Включить или выключить UPnP. - ntcp2 включено - Проверить .su3 подпись. + Проверждать su3 подпись. Ограничения Максимальное количество транзитных тунелей. 2500 по умолчанию. Ограничить количество открытых файловых дескрипторов (0 - использовать системное ограничение). @@ -273,14 +266,11 @@ Каталог адресов. Настройка не существует в i2pd.conf! Инфо - Похоже андроид закрыл модуль DNSCrypt. Ваше интернет - соединение восстановлено. Проверьте настройки устройства! - Похоже андроид закрыл модуль Tor. Ваше интернет - соединение восстановлено. Проверьте настройки устройства! + Похоже андроид закрыл модуль DNSCrypt. Ваше интернет соединение восстановлено. Проверьте настройки устройства! + Похоже андроид закрыл модуль Tor. Ваше интернет соединение восстановлено. Проверьте настройки устройства! Похоже андроид закрыл модуль I2P. Проверьте настройки устройства! Похоже DNSCrypt не может подключиться к интернету. Можете попробовать выбрать другие сервера DNSCrypt. Вы сможете найти их в МЕНЮ -> Быстрые настройки -> Выбрать сервера DNSCrypt - Похоже Tor не може подключиться к интернету. - Интернет провайдер может блокировать Tor. Попробуйте использовать мосты Tor. Вы сможете найти их в МЕНЮ -> Быстрые настройки -> Мосты + Похоже Tor не може подключиться к интернету. Интернет провайдер может блокировать Tor. Попробуйте использовать мосты Tor. Вы сможете найти их в МЕНЮ -> Быстрые настройки -> Мосты Детский замок Вы можете заблокировать интерфейс этого приложения. Пожалуйста, введите пароль или используйте предыдущий. Пожалуйста, введите пароль. @@ -340,20 +330,18 @@ Похоже Вы уже активировали 3 копии InviZible Pro этим кодом. Если это не так, свяжитесь с разработчиком. Похоже Ваш PRO код неверный. Пожалуйста, свяжитесь с разработчиком. Запретить сон устройства - Дополнительная защита в Безрутовом Режиме, чтоб андроид не закрыл приложение. Может привести к повышенному разряду батареи - Вы можете использовать - InviZible Pro в режиме локального VPN или совместно с приложениями с функцией прокси или собственным локальным VPN. - Вы можете использовать - InviZible Pro совместно с приложениями с функцией прокси или собственным локальным VPN. + Не позволять устройству переходить в режим сна. Может быть полезно при использовании точки доступа. Разряжает батарею! + Вы можете использовать InviZible Pro в режиме локального VPN или совместно с приложениями с функцией прокси или собственным локальным VPN. + Вы можете использовать InviZible Pro совместно с приложениями с функцией прокси или собственным локальным VPN. Источники - Список реле будет обновлен после refresh_delay в часах. + Список ретрансляторов будет обновлен после указанной задержки в часах. Реле Список реле. Реле DNSCrypt Режим VPN активирован Режим VPN выключен Ошибка VPN! - Пожалуйста, настройте использование прокси-сервера в настройках подключенного устройства. Настройки по умолчанию: IP:10.1.10.1 Порт:8118 + Пожалуйста, настройте использование прокси в настройках подключенного устройства. Настройки по умолчанию: IP:10.1.10.1 Порт:8118 Приложения, открывающиеся через InviZible Настройки маршрутизации Весь интернет через InviZible @@ -364,8 +352,7 @@ Доступ к сети I2P с помощью Purple I2P Подключение Внимание - InviZible Pro не может запустить %1$s! Пожалуйста, попробуйте сбросить настройки %2$s. - Если это не помогает, перезагрузите ваше устройство. + InviZible Pro не может запустить %1$s! Пожалуйста, попробуйте сбросить настройки %2$s. Если это не помогает, перезагрузите ваше устройство. Сбросить Добавить сервер Неправильная конфигурация сервера. Пожалуйста, проверьте поле SDNS. @@ -392,8 +379,11 @@ Обновлять правила при изменении подключения Обновлять правила HTTP outproxy + Шлюз в обычный интернет. HTTP outproxy адрес + URL адрес исходящего HTTP прокси (например http://false.i2p) SOCKS outproxy + Адрес прокси (IP или локальный). Туда будут поступать запросы, которые идут за пределы сети I2P. SOCKS outproxy адрес SOCKS outproxy порт Редактировать dnscrypt-proxy.toml @@ -428,15 +418,11 @@ Слишком много правил для отображения. Показана только первая 1000. Использовать IPv4 сервера Использовать IPv6 сервера - Немедленно отвечать на IPv6 запросы пустым ответом. - Это ускоряет работу при отсутствии подключения по протоколу IPv6, но иногда может вызывать проблемы. + Немедленно отвечать на IPv6 запросы пустым ответом. Это ускоряет работу при отсутствии подключения по протоколу IPv6, но иногда может вызывать проблемы. IP адрес устройства в LAN - Включите Зафиксировать TTL и настройте устройство в LAN, чтобы подключиться к InviZible. - Используйте шлюз: %1$s, DNS сервер: %2$s. + Включите Зафиксировать TTL и настройте устройство в LAN, чтобы подключиться к InviZible. Используйте шлюз: %1$s, DNS сервер: %2$s. Включить управление скриптами - Используйте следующую команду для управления модулями: - \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL - --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Где 1 - запустить, 0 - остановить модуль. + Используйте следующую команду для управления модулями: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Где 1 - запустить, 0 - остановить модуль Запущенные сервисы Обновление Команды Рут @@ -447,7 +433,7 @@ Обнаружен отчет аварийного завершения приложения. Хотите его отправить разработчику, чтобы сделать InviZible лучше? Новая цепочка Tor Сервер Tor изменился - Включить выходной SOCKS прокси + Выходной SOCKS прокси Tor будет выполнять все соединения через SOCKS5 прокси. Прокси Использовать socks5 прокси @@ -467,7 +453,7 @@ Не удается подключиться к прокси: %s Успешное соединение. Ping %s ms. Многопользовательская поддержка - Поддержка двойных приложений, MIUI, Island, Shelter и приложений рабочего профиля + Поддержка двойных приложений, MIUI, Island, Shelter и приложений рабочего профиля. Может быть неэффективным в режиме VPN Доступны новые мосты Tor по-умолчанию. Вы хотите их обновить? Обнаружение MITM атак Обнаружение ARP-спуфинга @@ -476,8 +462,7 @@ Интернет соединение будет заблокировано во время атаки Обнаружена атака ARP-спуфинг! Обнаружен мошеннический DHCP! - Обнаружена атака «человек посередине»! Ваши данные могут быть перехвачены другим устройством в локальной сети. - Выключите, подождите несколько секунд и включите Wi-Fi. Использование текущей Wi-Fi точки доступа может быть небезопасным! + Обнаружена атака «человек посередине»! Ваши данные могут быть перехвачены другим устройством в локальной сети. Выключите, подождите несколько секунд и включите Wi-Fi. Использование текущей Wi-Fi точки доступа может быть небезопасным! Обнаружение ARP-спуфинг атак не поддерживается на вашем устройстве! Пожалуйста, выключите Entry Nodes в настройках Tor, иначе Вы не сможете использовать мосты. Выключите мосты Tor, если хотите выбрать Entry Nodes. @@ -519,8 +504,7 @@ Ожидание сети… Изменить Tor IP Смена Tor IP - Вы добавили более 3-х ярлыков в быстрые настройки. - Оставьте только 3. Добавление более 3-х ярлыков может вызвать проблемы с управлением приложением. + Вы добавили более 3-х ярлыков в быстрые настройки. Оставьте только 3. Добавление более 3-х ярлыков может вызвать проблемы с управлением приложением. Обнаружение мошеннических DHCP Обнаружение мошеннических DHCP в Wi-Fi сетях. Выбрать точку рандеву @@ -541,7 +525,7 @@ Включить поддержку HTTP/3 (DoH3, HTTP over QUIC). Обратите внимание, что, как и DNSCrypt, но в отличие от других версий HTTP, здесь используется UDP и (обычно) порт 443 вместо TCP. Уведомления необходимы для отображения важной информации о работе приложения, управлении приложением, и обнаруженных атаках. Разрешить уведомления для InviZible? Спросить позже - Активируйте эту опцию, если вы находитесь в сети, поддерживающей только ipv6, и сайты ipv4 становятся недоступными. В противном случае не включайте ее, иначе вы вообще не сможете ни к чему подключиться. + Активируйте эту опцию, если вы находитесь в сети, поддерживающей только IPv6, и сайты IPv4 становятся недоступными. В противном случае не включайте ее, иначе вы вообще не сможете ни к чему подключиться. Набор используемых статических префиксов IPv6. IPv6 мосты Подделать SNI @@ -555,7 +539,7 @@ Исключить из Tor Использовать с Tor Исключить UDP из Tor - Исключить приложение + Исключить полностью \u2193 Потяните, чтобы обновить \u2193 Блокировка этого системного приложения может привести к нестабильному интернет-соединению! diff --git a/tordnscrypt/src/main/res/values-tr/strings.xml b/tordnscrypt/src/main/res/values-tr/strings.xml index 39f4eebdb..668747a2a 100644 --- a/tordnscrypt/src/main/res/values-tr/strings.xml +++ b/tordnscrypt/src/main/res/values-tr/strings.xml @@ -12,7 +12,7 @@ Önyüklemede Başlat Root kullanılabilirliği denetleniyor… Lütfen bekleyin… - Tekrar gösterme + Gösterme DNSCrypt Durduruldu DNSCrypt Kuruldu DNSCrypt Kuruluyor @@ -66,9 +66,9 @@ Yedekleme geri yüklendi Ayarlar Otomatik Başlat - Önyüklemede DNSCrypt\'i Başlat - Önyüklemede Tor\'u Başlat - Önyüklemede I2P\'yi Başlat + DNSCrypt\'i Otomatik Başlat + Tor\'u Otomatik Başlat + I2P\'yi Otomatik Başlat Gecikme Yalnızca otomatik başlatma düzgün çalışmazsa bir gecikme (sn) kullan DNSCrypt sunucuları @@ -80,14 +80,14 @@ Lütfen I2P\'yi yeniden başlatın Çoklu kullanıcı desteği UDP DNS isteklerini dinlemek ve bunları anonim olarak çözümlemek için bu bağlantı noktasını açın. - Web Sitelerini Seç - Tor ile açılacak web siteleri listesi. Bu özellik, CDN arkasındaki sitelerde çalışmaz - Uygulamaları Seç + Siteleri Seç + Tor ile açılacak sitelerin listesi. Bu özellik, CDN arkasındaki sitelerde çalışmaz + Uygulamaları seç Tor ile kullanılacak uygulamalar listesi InviZible ile kullanılacak uygulamalar listesi - Web Sitelerini Hariç Tut - Doğrudan açılacak web siteleri listesi. Bu özellik, CDN arkasındaki sitelerde çalışmaz - Uygulamaları Hariç Tut + Siteleri hariç tut + Doğrudan açılacak sitelerin listesi. Bu özellik, CDN arkasındaki sitelerde çalışmaz + Uygulamaları hariç tut Doğrudan açılacak uygulamalar listesi Yenileme Aralığı Web sitelerinin IP\'lerini yenilemek için saat cinsinden süre. Android 5.1 ve üstü için. Yenilemeyi durdurmak için 0 yazın. @@ -197,8 +197,7 @@ Sunucu, kullanıcı sorgularını günlüğe kaydetmemelidir (bildirime dayalı). Sunucu kendi kara listesini zorlamamalıdır (ebeveyn denetimi, reklam engelleme… için). Yukarı akış sunucularına bağlanmak için her zaman TCP kullan. - Her şeyi Tor üzerinden yönlendirmeniz gerekiyorsa bu yararlı olabilir. -\n Aksi takdirde, güvenliği artırmadığından (dnscrypt-proxy, UDP kullanırken bile her şeyi şifreleyecektir) ve yalnızca gecikmeyi artırabileceğinden bunu devre dışı olarak bırakın. + Her şeyi Tor üzerinden yönlendirmeniz gerekiyorsa bu yararlı olabilir. Aksi takdirde, güvenliği artırmadığından (dnscrypt-proxy, UDP kullanırken bile her şeyi şifreleyecektir) ve yalnızca gecikmeyi artırabileceğinden bunu devre dışı olarak bırakın. SOCKS vekili. Vekili etkinleştir Tüm TCP bağlantılarını yerel bir Tor düğümüne yönlendirin. Tor, UDP\'yi desteklemez, bu nedenle force_tcp\'yi de etkin olarak ayarlayın. @@ -213,8 +212,7 @@ Yönlendirme kuralları dosyasını içe aktarın. Birden fazla dosya seçebilirsiniz, yinelenen satırlar kaldırılacaktır. Yönlendirme kurallarını sil Gizleme kuralları - Gizleme, belirli bir ad için önceden tanımlanan bir adres döndürür. -\n HOSTS dosyası olarak işlev görmenin yanı sıra, farklı bir adın IP adresini de döndürebilir. Ayrıca CNAME düzleştirme yapacaktır.. + Gizleme, belirli bir ad için önceden tanımlanan bir adres döndürür. HOSTS dosyası olarak işlev görmenin yanı sıra, farklı bir adın IP adresini de döndürebilir. Ayrıca CNAME düzleştirme yapacaktır.. Gizleme kurallarını içe aktar Gizleme kuralları dosyasını içe aktarın. Birden fazla dosya seçebilirsiniz, yinelenen satırlar kaldırılacaktır. Gizleme kurallarını sil @@ -224,8 +222,7 @@ Ayrıntıyı azaltmak için bu sorgu türlerini günlüğe kaydetme. Her şeyi günlüğe kaydetmek için boş bırakın. Sorgu Günlüğünü Aç Şüpheli sorgular günlüğü. - Var olmayan bölgeler için sorguları günlüğe kaydet. -\n Bu sorgular, kötü amaçlı yazılımların, bozuk/eski uygulamaların ve varlıklarını 3. taraflara bildiren aygıtların varlığını ortaya çıkarabilir. + Var olmayan bölgeler için sorguları günlüğe kaydet. Bu sorgular, kötü amaçlı yazılımların, bozuk/eski uygulamaların ve varlıklarını 3. taraflara bildiren aygıtların varlığını ortaya çıkarabilir. Şüpheli günlüğünü etkinleştir Şüpheli Günlüğünü Aç Kalıp tabanlı engelleme (kara liste). @@ -345,9 +342,8 @@ Şifreleme Önceden hesaplanan ElGamal tabloları kullan. UPnP\'yi etkinleştir veya devre dışı bırak. - ntcp2 etkin Yeniden tohumlama - .su3 imzasını doğrula. + su3 imzasını doğrula. Sınırlar Azami geçiş tüneli sayısını geçersiz kıl. Öntanımlı olarak 2500. Açık dosya tanımlayıcılarının sayısını sınırla (0 - sistem sınırını kullan). @@ -424,19 +420,17 @@ InviZible Pro projesinin yardımınıza ihtiyacı var. Ücretli özellikleri satın almak için Tamam düğmesine basın. Üzgünüm, ancak satın alma işleminiz onaylanamıyor. 3 gün sonra geri ödeme alacaksınız. Ne yazık ki, bu özellik yalnızca ücretli sürümde kullanılabilir. - InviZible Pro\'yu seçtiğiniz için teşekkürler. Umarım gizliliğiniz ve internetin rahat kullanımı için faydalı olur -\n -\n\tInviZible Pro, modül olarak Tor, DNSCrypt ve Purple I2P\'yi içerir. -\n -\n\tInviZible Pro, aygıtınız root ayrıcalıklarına sahipse root kullanabilir veya İnternet trafiğini Tor, DNSCrypt ve I2P ağlarına iletmek için yerel bir VPN kullanır. -\n -\n\tGizlilik Politikası: -\n\tInviZible Pro, kişisel veya hassas kullanıcı verilerini toplamaz veya paylaşmaz. -\n -\n\tTelif Hakkı © 2019-2024 -\n\tGarmatin Oleksandr -\n\tinvizible.soft@gmail.com -\n\tinvizible.net/en/privacy + + \tInviZible Pro\'yu seçtiğiniz için teşekkürler. Umarım gizliliğiniz ve internetin rahat kullanımı için faydalı olur + \n\n\tInviZible Pro, modül olarak Tor, DNSCrypt ve Purple I2P\'yi içerir. + \n\n\tInviZible Pro, aygıtınız root ayrıcalıklarına sahipse root kullanabilir veya İnternet trafiğini Tor, DNSCrypt ve I2P ağlarına iletmek için yerel bir VPN kullanır. + \n\n\tGizlilik Politikası: + \n\tInviZible Pro, kişisel veya hassas kullanıcı verilerini toplamaz veya paylaşmaz. + \n\n\tTelif Hakkı © 2019-2024 + \n\tGarmatin Oleksandr + \n\tinvizible.soft@gmail.com + \n\tinvizible.net/en/privacy + Değişiklikleri kaydetmek istiyor musunuz\? Bu, InviZible Pro\'yu bozabilir. Çalışan hizmetler Güncelleme bildirimleri @@ -492,4 +486,5 @@ Tor IP\'sini değiştir Tor IP\'si değiştiriliyor Hızlı Ayarlar\'a 3\'ten fazla kutucuk eklediniz. Lütfen yalnızca 3 tane ekleyin. 3\'ten fazla kutucuk eklemek, uygulama denetimi ile ilgili sorunlara neden olabilir. - \ No newline at end of file + Sonra tekrar sor + diff --git a/tordnscrypt/src/main/res/values-uk/strings.xml b/tordnscrypt/src/main/res/values-uk/strings.xml index 48bb5972c..4711df409 100644 --- a/tordnscrypt/src/main/res/values-uk/strings.xml +++ b/tordnscrypt/src/main/res/values-uk/strings.xml @@ -113,11 +113,11 @@ Запуск модулів з Root Використовувати Root привілеї для модулів DNSCrypt, Tor та I2P. Увімкнення цієї функції залишає модулі некерованими і може викликати проблеми з підключенням! Інші - Захистіть програму в Безрутовому Режимі, щоб андроїд не завершив його + Захистіть програму, щоб андроїд не завершив її Заблокувати сайт при виявленні атаки повторного зв\'язування DNS Показувати повідомлення Заборонити сон пристрою - Завжди показувати довідкові повідомлення + Показувати всі повідомлення, раніше зазначені як недозволені для показу Увімкнути керування скриптами Вимкнути оптимізацію батареї? Будь ласка, виключіть InviZible Pro з оптимізації заряду батареї Android, щоб система не припиняла роботу DNSCrypt, Tor або I2P в будь-яку мить. Деякі спеціальні системи, такі як MIUI, можуть вимагати додаткових кроків. @@ -129,12 +129,12 @@ Будь ласка, перезапустіть DNSCrypt Будь ласка, перезапустіть Tor Будь ласка, перезапустіть I2P - Підтримка подвійних додатків, MIUI, Island, Shelter та додатків робочого профілю + Підтримка подвійних додатків, MIUI, Island, Shelter та додатків робочого профілю. Може бути неефективним у режимі VPN Виберіть iptables Інші налаштування. Сервер для початкового завантаження. Це звичайний сервер, не який підтримує шифрування. Використовується лише для завантаження списку серверів, які підтримують шифрування, якщо системний сервер DNS не працює. Він ніколи не використовується, якщо завантажено список серверів, які підтримують шифрування. - Не дозволяти dnscrypt-proxy використовувати системні установки DNS. Використовувати сервер для відновлення.. - ФІЛЬТРИ + Не дозволяти DNSCrypt використовувати системні установки DNS. Використовувати Сервер для початкового завантаження. + Фільтри Правила переадресації Перенаправити запити до вибраних сайтів на певні сервери. Чорний список @@ -175,9 +175,9 @@ Оновити правила під час зміни підключення Вибрати сайти Налаштування збережені - Додатковий захист у Безрутовому Режимі, щоб андроїд не закрив додаток. Може призвести до підвищеного розряду батареї + Не дозволяти пристрою переходити в режим сну. Може бути корисним при використанні точки доступу. Розряджає батарею! Режим сумісності - ЗАГАЛЬНІ НАЛАШТУВАННЯ + Загальні налаштування Увімкніть якщо у Вас кастомна прошивка, та інтернет зникає при натисканні кнопки START DNSCrypt, Tor, I2P захищені. Не приховуйте сповіщення. Видалити білий список @@ -185,10 +185,9 @@ Хост або IP для обходу Вибрати все Прибрати вибране - Зовнішній IP роутера для вхідних з\'єднань. - ntcp2 увімкнено + Зовнішній IP роутера для вхідних з\'єднань (по замовчуванню: auto якщо включений SSU2). Ресідінґ - Перевірте підпис .su3. + Перевіряти підпис su3. Схоже, що I2P було вбито системою Android. Перевірте налаштування пристрою! Завантаження файлу Доступне оновлення InviZible Pro. Бажаєте завантажити та оновити його\? Оновлення продовжиться у фоновому режимі. @@ -196,7 +195,7 @@ Неправильна конфігурація сервера. Будь ласка, перевірте поле SDNS. Запуск служб Оновлення сповіщень - Блокування IP-адрес на основі шаблонів (чорний список IP-адрес). + Блокування IP-адрес на основі шаблонів (чорний список IP-адрес) Заблокувати HOTSPOT http Проксі Використовувати socks5 proxy @@ -221,25 +220,22 @@ Список веб-сайтів, які відкривати безпосередньо через HOTSPOT Дозволити прив\'язку I2P Зберігати рут-команди до журналу - Вимагати, щоб сервери (зі статичних + віддалених джерел) відповідали певним властивостям. + Вимагати, щоб сервери (зі статичних + віддалених джерел) відповідали певним властивостям Використовувати сервери з підтримкою протоколу DNSCrypt. Використовувати сервери, доступні через IPv6 Сервер не має реєструвати запити користувачів (декларативно). - Може бути корисно, якщо вам потрібно направляти все через Tor. -\n В іншому разі залиште опцію вимкненою, оскільки це не покращує безпеку (dnscrypt-proxy завжди буде шифрувати все, навіть використовуючи UDP), і може лише збільшити затримку. - proxy_port - Перенаправляти всі TCP-з\'єднання на локальний вузол Tor. Tor не підтримує UDP, а отже ввімкніть force_tcp також. - Маскування повертає заздалегідь визначену адресу для певного імені. -\n Окрім того, що воно діє як файл HOSTS, це також може повертати IP-адресу іншого імені. Також виконує вирівнювання CNAME. - Увімкнути журнали запитів + Використовувати TCP замість UDP для підключення до серверів DNSCrypt. Цей параметр повинен бути увімкнений, якщо ви використовуєте DNSCrypt через Tor. + Порт проксі + Перенаправляти всі TCP-з\'єднання на вхідний Socks5 проксі Tor. Tor не підтримує UDP, а отже ввімкніть Force TCP також. + Маскування повертає заздалегідь визначену адресу для певного імені. Окрім того, що воно діє як файл HOSTS, це також може повертати IP-адресу іншого імені. Також виконує вирівнювання CNAME. + Журнали запитів Не записувати ці типи запитів, щоб зменшити багатослівність. Залишає порожній рядок, щоб записати все. Записує клієнтські запити у файл. - Журналювати запити для неіснуючих зон. -\n Ці запити можуть виявити наявний шкідливого програмного забезпечення, зламаних/застарілих програм і пристроїв, що сигналізують про свою присутність третім особам. + Журналювати запити для неіснуючих зон. Ці запити можуть виявити наявність шкідливого програмного забезпечення, зламаних/застарілих програм і пристроїв, що сигналізують про свою присутність третім особам. Чорний список IP складається з одного шаблону на рядок. Імпортувати чорний список IP-адрес Імпортує чорний список IP-адрес. Ви можете вибрати декілька файлів, повторювані рядки видаляться. - Білий список на основі шаблонів (обхід чорних списків). + Білий список на основі шаблонів (обхід чорних списків) Білий список Видалити чорний список IP-адрес У файлі dnscrypt-proxy.txt немає параметра преференцій! @@ -265,10 +261,10 @@ Не соромтеся повторно застосовувати контур, який використовувався не більше кількох секунд тому, але ніколи не приєднуйте новий потік до занадто старого контуру. Якщо увімкнено, Tor не буде розміщувати два сервери, IP-адреси яких знаходяться надто близько в одному ланцюзі. Наразі дві адреси вважаються занадто близькими, якщо вони лежать в одному діапазоні /16. Відкрити цей порт для прослуховування з\'єднань від SOCKS-програм. - Увімкнути HTTP-тунель + HTTP-тунель Відкриває цей порт для прослуховування проксі-з\'єднань за протоколом HTTP CONNECT замість SOCKS. Відкриває цей порт для прослуховування UDP DNS-запитів та їх анонімного вирішення. - Увімкнути DNS + Розв\'язувати DNS Якщо вимкнено, Tor уникатиме з\'єднання з серверами каталогів і вузлами входу через IPv4. Якщо увімкнено, Tor може підключатися до серверів каталогів або вузлів входу через IPv6. STUN-сервери для мостів SnowFlake @@ -283,13 +279,15 @@ Обмеження пропускної здатності в Кбіт/с. Максимальний % від ліміту пропускної здатності для транзиту. 0-100. Увімкніть транспортний протокол SSU (використовуйте UDP). - Увімкнути ntcpproxy + Вихідний проксі Вкажіть проксі-сервер для NTCP. Має бути http://address:port або socks://address:port. HTTP-проксі HTTP-проксі Порт для прослуховування (HTTP-проксі). HTTP-аутпроксі + Шлюз у звичайний інтернет Адреса HTTP-аутпроксі + URL адреса вихідного HTTP проксі (наприклад http://false.i2p) Порт HTTP-проксі Порт сокс-проксі Сокс проксі @@ -334,7 +332,7 @@ Режим VPN вимкнено Режим VPN активовано Проект InviZible Pro та його автор висловлюють подяку за допомогу! - Будь ласка, налаштуйте використання проксі-сервера в налаштуваннях підключеного пристрою. Типове значення: IP:10.1.10.1 Port:8118 + Будь ласка, налаштуйте використання проксі в налаштуваннях підключеного пристрою. Типове значення: IP:10.1.10.1 Port:8118 Помилка режиму VPN! Доступ до мережі I2P з Purple I2P Додати власний сервер @@ -353,8 +351,8 @@ Чорний список IP-адрес Імпортувати білий список Імпортує список доменів. Ви можете вибрати кілька файлів, повторювані рядки видаляться. - Список джерел закінчується після refresh_delay. - Список реле закінчується через годину refresh_delay. + Список серверів буде оновлений після зазначеної затримки у годинах. + Список ретрансляторів буде оновлений після зазначеної затримки у годинах. Реле DNSCrypt Журнал запитів DNSCrypt Відкриває цей порт для прослуховування прозорих проксі-з\'єднань. @@ -364,8 +362,8 @@ URL підписки AddressBook. Завантаження було зупинено Зверніть увагу, що у вас відкладена покупка: - Для керування модулями програми використовуйте наступну команду: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Де 1 - запускає, 0 - зупиняє модуль. - Вимагати, щоб сервери, визначені віддаленими джерелами, відповідали певним властивостям. + Для керування модулями програми використовуйте наступну команду: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Де 1 - запускає, 0 - зупиняє модуль + Вимагати, щоб сервери, визначені віддаленими джерелами, відповідали певним властивостям Увесь вхідний трафік через Тор Список веб-сайтів, які потрібно відкрити за допомогою Tor для HOTSPOT TTL буде зафіксовано на 64 за допомогою локальної VPN. Підтримка ядра не потрібна. Його можна використовувати лише у \"рут-режимі\" з вимкненою опцією \"Запускати модулі з правами рута\". Щоб зафіксувати TTL, будь ласка, запустіть DNSCrypt та/або Tor. @@ -373,21 +371,23 @@ Якщо ненульове, намагайтеся рідше записувати на диск. Відкрити налаштування прив\'язки Підтримувати багатокористувацький режим - Увімкнути прозорий проксі + Прозорий проксі Використовуйте сервери з підтримкою протоколу DNS-over-HTTPS. + Використовуйте сервери з підтримкою протоколу Oblivious DNS-over-HTTPS. У файлі tor.conf немає параметра преференцій! Хост або IP для розблокування - Завжди використовувати TCP для підключення до висхідних серверів. - SOCKS проксі. - Увімкнути проксі + Завжди використовувати TCP для підключення до висхідних серверів + SOCKS проксі + Вихідний проксі Імпортувати правила маскування Імпортує файл правил маскування. Ви можете вибрати декілька файлів, повторювані рядки видаляться. - Журналізація запитів. + Журналізація запитів SOCKS аутпроксі - Журналізація підозрілих запитів. - Увімкнути журналювання підозрілих подій + Адреса проксі (IP або локальна). Туди надходитимуть запити, які йдуть за межі мережі I2P. + Журналізація підозрілих запитів + Журнал підозрілих запитів Відкрити журнал підозрілих подій - Блокування на основі шаблонів (чорний список). + Блокування на основі шаблонів (чорний список) Імпортує список доменів або файл hosts. Ви можете вибрати кілька файлів, повторювані рядки видаляться. Ви можете заблокувати доступ до цієї програми. Будь ласка, введіть пароль або використовуйте попередній. Джерела @@ -402,13 +402,13 @@ Готово! Правила стерто. Занадто багато правил. Буде показано лише перші 1000. Намагатися використовувати вбудоване криптографічне апаратне прискорення, якщо воно доступне. - Увімкнути SOCKS проксі + SOCKS проксі Джерела - Увімкнути проксі для виводу SOCKS + Вихідний SOCKS проксі Застосунки для обходу InviZible - Видалити виділення - Дозволити вхідні з\'єднання - Порт для прослуховування вхідних з\'єднань. + Загальні налаштування + Вхідні з\'єднання + Порт для прослуховування вхідних з\'єднань (по замовчуванню: auto (random)). Увімкніть зв\'язок через IPv4. Увімкніть зв\'язок через IPv6. Увімкніть транспортний протокол NTCP2 (використовуйте TCP). @@ -506,7 +506,10 @@ Виключити з Tor Використовувати з Tor Виключити UDP з Tor - Виключити додаток + Виключити повністю \u2193 Потягніть, щоб оновити \u2193 Блокування цього системного додатку може призвести до нестабільного інтернет-з\'єднання! + Ноди + Налаштування ізолювання + Щоб активувати цю опцію, необхідно відключити мости, або використовувати мости тільки з 80 і 443 портами. diff --git a/tordnscrypt/src/main/res/values-zh/strings.xml b/tordnscrypt/src/main/res/values-zh/strings.xml index a4e6cc178..02ea3e6ea 100644 --- a/tordnscrypt/src/main/res/values-zh/strings.xml +++ b/tordnscrypt/src/main/res/values-zh/strings.xml @@ -61,9 +61,9 @@ "选择备份文件夹:" "设置" "自动启动" - "设备启动时启动 DNSCrypt" - "设备启动时启动 Tor" - "设备启动时启动 I2P" + 设备启动时启动 DNSCrypt + 设备启动时启动 Tor + 设备启动时启动 I2P "延迟" 仅在自动启动无法正确工作时使用延迟(秒) "DNSCrypt 服务器" @@ -72,17 +72,17 @@ "路由设置" "通过 Tor 路由全部流量" "通过 InviZible 路由全部流量" - "选择网站" - "通过 Tor 打开的网站列表。此功能无法用于 CDN 后的网站" - "选择应用" + 选择网站 + 通过 Tor 打开的网站列表。此功能无法用于 CDN 后的网站 + 选择应用 "使用 Tor 的应用列表" "使用 InviZible 的应用列表" - "排除网站" - "直接打开的网站列表。此功能无法用于 CDN 后的网站" - "排除应用" + 排除网站 + 直接打开的网站列表。此功能无法用于 CDN 后的网站 + 排除应用 "直接打开的应用列表" - "刷新间隔" - "刷新网站 IP 的周期(小时)。用于 Android 5.1 及更高版本。置为 0 停止刷新。" + 刷新间隔 + 刷新网站 IP 的周期(小时)。用于 Android 5.1 及更高版本。置为 0 停止刷新。 "网桥" "如果您无法连接到 Tor 网络请使用网桥" "不使用网桥" @@ -100,14 +100,14 @@ "保存" "关闭" "错误的主机名!" - "选择主题" - "选择语言" + 选择主题 + 选择语言 "阻止 http" "拒绝连接到 http 端口 80" "更新" - "自动更新" - "每日检查 InviZible Pro 和模块更新" - "检查更新" + 自动更新 + 每日检查 InviZible Pro 和模块更新 + 检查更新 "立即检查是否有新版本" "严格通过 Tor 更新" "仅通过 Tor 并且当 Tor 正在运行时检查更新" @@ -117,29 +117,29 @@ "其它" "阻止热点 http" "拒绝热点连接到 http 端口 80" - "在无 Root 模式下防止应用被 Android 系统杀死" + 在无 Root 模式下防止应用被 Android 系统杀死 "刷新规则" "每次连接性改变时更新规则" "显示规则" "防止设备睡眠" - "无 Root 模式下的附加保护防止应用被 Android 系统杀死。可能消耗电池" + 无 Root 模式下的附加保护防止应用被 Android 系统杀死。可能消耗电池电量! "帮助信息" - "总是显示帮助信息" + 显示所有已标记为不允许显示的信息 请将 InviZible Pro 从 Android 电池优化中排除,以防止系统在任何时候终止 DNSCrypt、Tor 或 I2P。对于某些特定系统,例如 MIUI,可能需要额外步骤。 "选择 BusyBox" "热点-实验性" - "设备启动时启动数据共享" - "允许 Tor 数据共享" + 设备启动时启动数据共享 + 允许 Tor 数据共享 "通过 Tor 路由全部" "通过 Tor 路由全部入站流量" - "选择网站" - "热点通过 Tor 打开的网站列表" - "排除网站" - "热点直接打开的网站列表" - "允许 I2P 数据共享" + 选择网站 + 热点通过 Tor 打开的网站列表 + 排除网站 + 热点直接打开的网站列表 + 允许 I2P 数据共享 "固定 TTL" - "TTL 将使用本地 VPN 固定为 64。不需要内核支持。 仅在“root 模式”下且禁用“使用 Root 运行模块”选项时可用。 为固定 TTL 请启动 DNSCrypt 或/和 Tor。" - "打开数据共享配置" + 使用本地VPN,TTL将固定为64。不需要内核支持。要修复TTL,请启动DNSCrypt或/和Tor。 + 打开数据共享配置 "请重启 DNSCrypt" "请重启 Tor" "请重启 I2P" @@ -149,59 +149,56 @@ "执行 Root 命令…" "请稍候…" "设置已保存" - "全局设置" + 全局设置 "仅用于高级用户!" "至少选择一个服务器!" "本地监听端口。" - "请求满足指定属性的服务器(从静态 + 远程源)。" + 请求满足指定属性的服务器(从静态 + 远程源) "使用实现了 DNSCrypt 协议的服务器。" "使用实现了 DNS-over-HTTPS 协议的服务器。" - "请求远程源定义的满足指定属性的服务器。" + 请求远程源定义的满足指定属性的服务器 "服务器必须支持 DNS 安全扩展 (DNSSEC)。" "服务器必须声明不记录用户日志。" "服务器必须不强制应用自己的黑名单(家长控制,广告拦截…)。" - "总是使用 TCP 连接上游服务器。" - 当您需要路由所有流量通过 Tor 时有用。 -\n 否则置为 false,因为它并不提高安全性(dnscrypt-proxy 将加密所有流量,即使使用 UDP),并只会提高延迟。 - "SOCKS 代理。" - "启用代理" - "路由全部 TCP 连接到本地 Tor 节点。 Tor 不支持 UDP,因此也设置 force_tcp 为 true。" - "proxy_port" - "其他设置。" - "回退解析器。 这是一个普通无加密 DNS 解析器,将用于获取初始解析器列表时的单发请求,且仅在系统 DNS 配置不工作时。 如果列表已缓存它将不会使用。中国用户可能需要在此使用 114.114.114.114:53。" - "从不让 dnscrypt-proxy 尝试使用系统 DNS 设置。无条件使用回退解析器。" - "过滤器" + 总是使用 TCP 连接上游服务器 + 当您需要路由所有流量通过 Tor 时有用。否则置为 false,因为它并不提高安全性(dnscrypt-proxy 将加密所有流量,即使使用 UDP),并只会提高延迟。 + SOCKS 代理 + 出站代理 + 将所有TCP连接路由到本地Tor入站Socks5代理。Tor不支持UDP,因此也将Force TCP设置为true。 + 代理端口 + 其他设置 + 这是一个普通无加密 DNS 解析器,将用于获取初始解析器列表时的单发请求,且仅在系统 DNS 配置不工作时。 如果列表已缓存它将不会使用。中国用户可能需要在此使用 114.114.114.114:53。 + 不要让DNSCrypt尝试使用系统DNS设置。无条件使用引导解析器。 + 过滤器 "转发规则" "指定域名的路由请求发送到一组指定的服务器。" "伪装规则" - 伪装规则对指定域名返回预定义地址。 -\n 除了像 HOSTS 文件一样工作,它也可以返回一个不同域名的 IP 地址。它也可以执行 CNAME 展开。 - "记录请求。" + 伪装规则对指定域名返回预定义地址。除了像 HOSTS 文件一样工作,它也可以返回一个不同域名的 IP 地址。它也可以执行 CNAME 展开。 + 记录请求 "将客户端请求记录到文件。" - "启用请求日志" + 请求日志 "不记录请求类型,以减少复杂性。保持空记录所有内容。" "打开请求日志" - "记录可疑请求。" - 记录不存在区域的请求。 -\n 这些请求将揭示恶意软件,损坏/过时应用,及向第三方显示存在的设备。 - "启用可疑请求日志" + 记录可疑请求 + 记录不存在区域的请求。这些请求将揭示恶意软件,损坏/过时应用,及向第三方显示存在的设备。 + 可疑请求日志 "打开可疑请求日志" - 基于封锁列表模式的域名阻止(黑名单)。 + 基于封锁列表模式的域名阻止(黑名单) "黑名单" 黑名单由每行一个域名或封锁列表组成。 - 基于IP块列表模式的 IP 阻止(IP 黑名单)。 + 基于IP块列表模式的 IP 阻止(IP 黑名单) "IP 黑名单" IP 黑名单由每行一个IP地址模式组成。 - 基于允许列表模式的白名单(绕过黑名单)。 + 基于允许列表模式的白名单(绕过黑名单) "白名单" "白名单支持与黑名单相同的模式。如果域名匹配白名单项,相应会话将绕过域名和 IP 过滤器。" "服务器" "源" "可用服务器远程列表。" - "源列表 refresh_delay 小时后过期。" + 服务器列表将在指定的延迟(小时)后更新。 "中继" "源" - "中继列表 refresh_delay 小时后过期。" + 中继列表将在指定的延迟(小时)后更新。 "DNSCrypt 中继" "dnscrypt-proxy.toml 中无偏好!" "删除日志" @@ -223,13 +220,13 @@ "每 NUM 决定是否构建新链路。" "随意重用最多 NUM 秒前初次使用的链路,但从不附加新流到太旧的链路。" "如果已启用,Tor 将不会将 IP “过于接近”的两台服务器置于相同链路。当前,如果两个地址处于同一 /16 区间则“过于接近”。" - "启用 SOCKS 代理" + SOCKS 代理 "打开此端口监听来自使用 SOCKS 的应用的连接。" - "启用 HTTP 隧道" + HTTP 隧道 "打开此端口监听使用 HTTP CONNECT 而不是 SOCKS 协议的代理连接。" - "启用透明代理" + 透明代理 "打开此端口监听透明代理连接。" - "启用 DNS" + 解析DNS "打开此端口监听 UDP DNS 请求,并匿名解析他们。" "如果禁用,Tor 将避免通过 IPv4 连接到目录服务器和入口节点。" "如果已启用,Tor 可能通过 IPv6 连接到目录服务器或入口节点。" @@ -243,10 +240,10 @@ "绕过 InviZible 的应用" "选择全部" "移除选择" - "通用设置" - "允许入站连接" - "监听入站连接的端口。" - "用于入站连接的路由器外部 IP。" + 通用设置 + 入站连接 + 侦听传入连接的端口(默认:自动(随机))。 + 传入连接的路由器外部IP(默认:如果启用SSU2,则自动)。 "启用通过 IPv4 通信。" "启用通过 IPv6 通信。" "路由器将不接受中转隧道,完全禁用中转流量。" @@ -255,7 +252,7 @@ "最大中转带宽限制比率。0–100。" "启用 SSU 传输协议(使用 UDP)。" "启用 NTCP2 传输协议(使用 TCP)。" - "启用 ntcpproxy" + 出站代理 "指定 NTCP 代理服务器。应为 http://address:port 或 socks://address:port。" "HTTP 代理" "HTTP 代理" @@ -272,14 +269,13 @@ "密码学" "使用 ElGamal 预计算表。" "启用或禁用 UPnP。" - "ntcp2 已启用" "正在补种" - "验证 .su3 签名。" + "验证 su3 签名。" "限制" "覆盖最大中转隧道数。默认为 2500。" "打开文件描述符限制数量(0 - 使用系统限制)。" - "corefile 最大大小 (Kb)(0 - 使用系统限制)。" - "地址簿" + corefile 最大大小 (Kb)(0 - 使用系统限制)。 + 地址簿 "初始设置地址簿订阅 URL。" "地址簿订阅 URL。" "i2pd.conf 中无偏好!" @@ -313,12 +309,12 @@ "DNSCrypt 更新可用。您想要下载并更新吗?更新将在后台继续。" "Tor 更新可用。您想要下载并更新吗?更新将在后台继续。" "Purple I2P 更新可用。您想要下载并更新吗?更新将在后台继续。" - "正在检查更新" - "正在检查更新,请稍侯。" + 正在检查更新 + 正在检查更新,请稍侯。 "更新服务器暂时无法访问。请稍后重试。" "更新服务器无法访问。" "更新错误。" - "未找到更新。" + 未找到更新。 "上次检查:" "已找到更新。" "更新已安装。" @@ -390,22 +386,22 @@ "新的默认 Tor 网桥可用。您想要更新吗?" "中间人攻击检测" "ARP 伪造检测" - "检测 Wi-Fi 中的中间人 ARP 伪造和流氓 DHCP 攻击。" + 检测 Wi-Fi 中的中间人 ARP 伪造和流氓 DHCP 攻击。 "检测到攻击时阻止互联网" "攻击期间互联网连接将被阻止" "代理" "使用 socks5 代理" "InviZible Pro 将使所有连接通过 SOCKS5 代理" "兼容模式" - "如果您的设备使用自定义 ROM 并且当点按启动按钮时连接丢失,启用此模式" + 如果您的设备使用自定义 ROM 并且当点按启动按钮时连接丢失,启用此模式 "启用脚本控制" "使用以下命令管理应用模块: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\"。其中 1 - 启动,0 - 停止模块。" "LAN 设备 IP 地址" "启用固定 TTL 并配置 LAN 设备连接到 InviZible。使用默认网关:%1$s,DNS 服务器:%2$s。" "多用户支持" - "支持双应用,MIUI,Island,Shelter 和工作资料应用" - "启用 SOCKS 出站代理" - "Tor 将使全部 OR 连接通过 SOCKS 5 代理。" + 支持双应用,MIUI,Island,Shelter 和工作资料应用。在VPN模式下可能无效 + SOCKS 出站代理 + Tor将通过SOCKS 5代理建立所有OR连接。 "正在运行服务" "更新规则" "Root 命令规则" @@ -504,19 +500,17 @@ 互联网连接检查 实时日志 在DNS选项卡中显示应用程序连接日志 - \\感谢您选择InviZble Pro。我相信它将增强您的隐私,并提供流畅的在线体验。 -\n -\nInviZble Pro包括Tor、DNSCryt和Purple I2P作为模块。 -\n -\n如果您的设备是root的,InviZble Pro可以使用root,或者使用本地VPN将互联网流量直接传递到Tor、DNSCryt和I2P网络。 -\n -\n隐私政策: -\nInviZble Pro不收集或共享任何个人或敏感用户数据。 -\n -\n版权所有©2019-2024。 -\nGarmatin Oleksandr。 -\n邮箱:invizible.soft@gmail.com。 -\nInvizible.net/en/privacy + + \t感谢您选择InviZble Pro。我相信它将增强您的隐私,并提供流畅的在线体验。 + \n\n\tInviZble Pro包括Tor、DNSCryt和Purple I2P作为模块。 + \n\n\t如果您的设备是root的,InviZble Pro可以使用root,或者使用本地VPN将互联网流量直接传递到Tor、DNSCryt和I2P网络。 + \n\n\t隐私政策: + \n\tInviZble Pro不收集或共享任何个人或敏感用户数据。 + \n\n\t版权所有©2019-2024。 + \n\tGarmatin Oleksandr。 + \n\t邮箱:invizible.soft@gmail.com。 + \n\tInvizible.net/en/privacy + 请允许使用后台流量,并在流量节省程序开启时允许使用流量。这对于流畅的在线体验非常重要。 稍后询问 停止优化电池使用? @@ -526,7 +520,7 @@ 从Tor中排除 通向Tor的路线 从Tor中排除UDP - 绕过应用程序 + 完全排除 IPv6网桥 伪造 SNI 启用对 HTTP/3(DoH3,QUIC 上的 HTTP)的支持。请注意,与 DNSCrypt 不同,与其他 HTTP 版本不同,此版本使用 UDP 和(通常)端口 443 而不是 TCP。 @@ -543,4 +537,12 @@ 如果您在仅支持ipv6的网络上,并且ipv4站点不可用,请激活此选项。否则,请不要启用它,否则您将无法连接到任何东西。 如果 Tor 在指定时间内没有看到客户端活动,它将进入休眠状态。必须至少 10 分钟 按下可编辑。 + 阻止此系统应用程序可能会导致互联网连接不稳定! + 使用实现了Oblivious DNS-over-HTTPS 协议的服务器。 + 常规互联网网关 + 出站代理的地址(IP或本地)。I2P之外的请求将转到那里。 + HTTP代理上行输出代理url(类似http://false.i2p) + 节点 + 隔离设置 + 要激活此选项,应禁用网桥或仅使用具有80和443端口的网桥。 diff --git a/tordnscrypt/src/main/res/values/array.xml b/tordnscrypt/src/main/res/values/array.xml index 55c5e4001..81a8e8dc6 100644 --- a/tordnscrypt/src/main/res/values/array.xml +++ b/tordnscrypt/src/main/res/values/array.xml @@ -577,10 +577,9 @@ njalla-doh mullvad-doh dns.digitale-gesellschaft.ch - dnscrypt.ca-1 plan9dns-nj-doh-ipv6 libredns - dnswarden-uncensor-dc + dnswarden-uncensor-dc-swiss meganerd-ipv6 scaleway-fr diff --git a/tordnscrypt/src/main/res/values/colors.xml b/tordnscrypt/src/main/res/values/colors.xml index ec152b94a..4e52c4590 100644 --- a/tordnscrypt/src/main/res/values/colors.xml +++ b/tordnscrypt/src/main/res/values/colors.xml @@ -23,6 +23,7 @@ #D45E5E #7F4E52 #614051 + #40614F #728FCE #4C787E #4863A0 @@ -67,4 +68,5 @@ @color/colorGreen @color/colorAccent @color/colorRed + #4CAF50 diff --git a/tordnscrypt/src/main/res/values/strings.xml b/tordnscrypt/src/main/res/values/strings.xml index 866f48294..d69d406c8 100644 --- a/tordnscrypt/src/main/res/values/strings.xml +++ b/tordnscrypt/src/main/res/values/strings.xml @@ -107,9 +107,9 @@ Settings Autostart - Start DNSCrypt On Boot - Start Tor On Boot - Start I2P On Boot + Autostart DNSCrypt + Autostart Tor + Autostart I2P Delay Use a delay (secs) only if Autostart does not work correctly DNSCrypt servers @@ -118,21 +118,21 @@ Routing Settings Route All traffic through Tor Route All traffic through InviZible - Select WebSites - WebSites list to open with Tor. This feature does not work for sites behind CDN - Select Applications + Select sites + Sites list to open with Tor. This feature does not work for sites behind CDN + Select applications Applications list to use with Tor Applications list to use with InviZible - Exclude WebSites - WebSites list to open directly. This feature does not work for sites behind CDN - Exclude Applications + Exclude sites + Sites list to open directly. This feature does not work for sites behind CDN + Exclude applications Applications list to open directly Exclude from Tor Route to Tor Exclude UDP from Tor - Bypass app - Refresh Interval - Period in hours to refresh WebSites IPs. For Android 5.1 and higher. Put 0 to stop refresh. + Exclude entirely + Refresh interval + Period in hours to refresh sites IP. For Android 5.1 and higher. Put 0 to stop refresh. Bridges Use it if you can not connect to Tor network Please disable Entry Nodes in Tor Settings, otherwise you cannot use Bridges. @@ -154,39 +154,38 @@ Close Spoof SNI Wrong host name! - Select Theme + Select theme Day Mode Night Mode Auto System default Bypass LAN addresses Do not use Tor for LAN destinations and IANA reserved IP blocks - Select Language + Select language Real-time logs Show application connection logs in the DNS tab Block http Deny connection to http port 80 Update - Automatic Updates - Check InviZible Pro and modules Updates daily - Check Update + Automatic updates + Check InviZible Pro and modules updates daily + Check update Check if new versions are available now Update strictly through Tor Check updates only with Tor and when Tor is running Use Root Privileges Run Modules With Root - Use Root privileges for DNSCrypt, Tor and I2P modules. - Enabling this feature leaves modules unmanaged and may cause connection problems! + Use Root privileges for DNSCrypt, Tor and I2P modules. Enabling this feature leaves modules unmanaged and may cause connection problems! Other Block HOTSPOT http Deny connection to http port 80 for HOTSPOT - Protect application with No Root Mode to prevent app being killed by android + Protect application from being killed by android MITM attack detection ARP spoofing detection - Detect Man-in-the-middle ARP spoofing and rogue DHCP attacks in Wi-Fi networks. + Detect Man-in-the-Middle ARP spoofing and rogue DHCP attacks in Wi-Fi networks. Rogue DHCP detection - Detect Man-in-the-middle rogue DHCP attacks in Wi-Fi networks. + Detect Man-in-the-Middle rogue DHCP attacks in Wi-Fi networks. Block internet when an attack is detected Internet connection will be blocked during attack DNS rebinding protection @@ -200,15 +199,13 @@ Update rules on every connectivity change Show notification Prevent device sleep - Additional Protection with No Root Mode to prevent app being killed by android. May drain battery + Do not allow the device to fall into doze mode. May be useful when using HOTSPOT. Drains the battery! Compatibility mode - Enable if your device with a custom ROM and the connection is lost when you press the START button + Enable if your device with a custom rom and the connection is lost when you press the START button Help messages - Always Show Help messages + Show all messages that have been marked as not allowed to show Enable script control - Use the following command to manage application modules: - \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL - --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module. + Use the following command to manage application modules: \"am broadcast -a pan.alexander.tordnscrypt.SHELL_SCRIPT_CONTROL --ei dnscrypt 1 --ei tor 1 --ei i2p 1 %s\". Where 1 - starts, 0 - stops the module. Stop optimizing battery usage? Please exclude InviZible Pro from Android battery optimization to prevent the system from terminating DNSCrypt, Tor, or I2P at any time. Some special systems, such as MIUI, may require additional steps. Disable network data saver? @@ -219,27 +216,25 @@ Use application BusyBox Not use BusyBox HOTSPOT-Experimental - Start Tethering On Boot - Allow Tor Tethering + Start sharing on boot + Allow Tor sharing Route All through Tor Route All incoming traffic through Tor - Select WebSites - WebSites list to open with Tor for HOTSPOT - Exclude WebSites - WebSites list to open directly for HOTSPOT - Allow I2P Tethering + Select sites + Sites list to open with Tor for HOTSPOT + Exclude sites + Sites list to open directly for HOTSPOT + Allow I2P sharing Fix TTL - TTL will be fixed to 64 using a local VPN. Kernel support is not required. - It can only be used in \"root mode\" with the \"Run Modules With Root\" option disabled. - To fix TTL please start DNSCrypt or/and Tor. + TTL will be fixed to 64 using a local VPN. Kernel support is not required. To fix TTL please start DNSCrypt or/and Tor. LAN device IP address Enable Fix TTL and configure LAN device to connect to InviZible. Use default gateway: %1$s, DNS server: %2$s. - Open Tethering config + Open tethering config Please restart DNSCrypt Please restart Tor Please restart I2P Multi-user support - Support for Dual Apps, MIUI, Island, Shelter and Work profile applications + Support for Dual Apps, MIUI, Island, Shelter and Work profile applications. May be ineffective in VPN mode Select iptables Use application iptables @@ -261,97 +256,92 @@ Settings saved - GLOBAL SETTINGS + Global settings For advanced user only! Select at least one server! Local port to listen to. - listen_port + Listen port - Require servers (from static + remote sources) to satisfy specific properties. + Require servers (from static + remote sources) to satisfy specific properties Use servers implementing the DNSCrypt protocol. - dnscrypt_servers + DNSCrypt servers Use servers implementing the DNS-over-HTTPS protocol. - doh_servers - ipv4_servers + Use servers implementing the Oblivious DNS-over-HTTPS protocol. + DoH servers + ODoH servers + IPv4 servers Use servers reachable over IPv4 - ipv6_servers + IPv6 servers Use servers reachable over IPv6 DNSCrypt Server DoH Server + ODoH Server Non-Filtering Filtering Non-Logging Keep Logs DNSSEC - Require servers defined by remote sources to satisfy specific properties. + Require servers defined by remote sources to satisfy specific properties Server must support DNS security extensions (DNSSEC). - require_dnssec + Require DNSSEC Server must not log user queries (declarative). - require_nolog + Require no log Server must not enforce its own blacklist (for parental control, ads blocking…). - require_nofilter - - Always use TCP to connect to upstream servers. - This can be can be useful if you need to route everything through Tor.\n - Otherwise, leave this to false, as it doesn\'t improve security (dnscrypt-proxy will always encrypt everything even using UDP), and can only increase latency. - - force_tcp - - SOCKS proxy. - Enable proxy - Route all TCP connections to a local Tor node. - Tor doesn\'t support UDP, so set force_tcp to true as well. - proxy_port - - Other Settings. - Bootstrap resolver. - This is a normal, non-encrypted DNS resolver, that will be only used for one-shot queries - when retrieving the initial resolvers list, and only if the system DNS configuration doesn\'t work. - It will never be used if lists have already been cached. - bootstrap_resolvers - Never let dnscrypt-proxy try to use the system DNS settings. Unconditionally use the fallback resolver.. - ignore_system_dns + Require no filter + + Always use TCP to connect to upstream servers + Use TCP instead of UDP to connect to DNSCrypt servers. This option should be enabled if you are using DNSCrypt over Tor. + Force TCP + + SOCKS proxy + Outbound proxy + Route all TCP connections to a local Tor inbound Socks5 proxy. Tor doesn\'t support UDP, so set Force TCP to true as well. + Proxy port + + Other Settings + This is a normal, non-encrypted DNS resolver, that will be only used for one-shot queries when retrieving the initial resolvers list, and only if the system DNS configuration doesn\'t work. It will never be used if lists have already been cached. + Bootstrap resolvers + Do not let DNSCrypt try to use system DNS settings. Unconditionally use the Bootstrap resolvers. + Ignore system DNS Enable support for HTTP/3 (DoH3, HTTP over QUIC). Note that, like DNSCrypt but unlike other HTTP versions, this uses UDP and (usually) port 443 instead of TCP. - http3 - dns64 - Activate this option if you are on an ipv6-only network and ipv4 sites become unavailable. Don\'t enable it otherwise, or you won\'t be able to connect to anything at all. - dns64 prefix + HTTP3 + DNS64 + Activate this option if you are on an IPv6-only network and IPv4 sites become unavailable. Don\'t enable it otherwise, or you won\'t be able to connect to anything at all. + DNS64 prefix Set of used static IPv6 prefixes. - FILTERS + Filters Forwarding rules - forwarding_rules + Forwarding rules Route queries for specific domains to a dedicated set of servers. Import forwarding rules Import a forwarding rules file. You can select multiple files, duplicate lines will be removed. Erase forwarding rules Cloaking rules - cloaking_rules - Cloaking returns a predefined address for a specific name.\n - In addition to acting as a HOSTS file, it can also return the IP address of a different name. It will also do CNAME flattening.. + Cloaking rules + Cloaking returns a predefined address for a specific name. In addition to acting as a HOSTS file, it can also return the IP address of a different name. It will also do CNAME flattening. Import cloaking rules Import a cloaking rules file. You can select multiple files, duplicate lines will be removed. Erase cloaking rules - Query logging. + Query logging Log client queries to a file. - Enable Query logging + Query logging Do not log these query types, to reduce verbosity. Keep empty to log everything. - ignored_qtypes + Ignored qtypes Open Query Log - Suspicious queries logging. - Log queries for nonexistent zones.\n - These queries can reveal the presence of malware, broken/obsolete applications, and devices signaling their presence to 3rd parties.. - Enable Suspicious logging + Suspicious queries logging + Log queries for nonexistent zones. These queries can reveal the presence of malware, broken/obsolete applications, and devices signaling their presence to 3rd parties. + Suspicious logging Open Suspicious Log - Pattern-based blocking (blacklist). + Pattern-based blocking (blacklist) Blacklist Blacklist are made of one pattern per line. Import blacklist @@ -359,14 +349,14 @@ Erase blacklist - Pattern-based IP blocking (IP blacklist). + Pattern-based IP blocking (IP blacklist) IP Blacklist IP Blacklist are made of one pattern per line. Import IP blacklist Import IP blacklist. You can select multiple files, duplicate lines will be removed. Erase IP blacklist - Pattern-based whitelisting (blacklists bypass). + Pattern-based whitelisting (blacklists bypass) Whitelist Whitelist support the same patterns as blacklists. If a name matches a whitelist entry, the corresponding session will bypass names and IP filters. Import whitelist @@ -376,13 +366,13 @@ Servers Sources Remote lists of available servers. - refresh_delay - Sources list expiring after refresh_delay hours. + Refresh delay + Server list will be updated after the specified delay in hours. Relays Sources - refresh_delay - Relays list expiring after refresh_delay hours. + Refresh delay + Relay list will be updated after the specified delay in hours. DNSCrypt Relays @@ -398,14 +388,13 @@ DNSCrypt IP Blacklist DNSCrypt Whitelist - block_unqualified + Block unqualified Immediately respond to A and AAAA queries for host names without a domain name. - block_undelegated + Block undelegated Immediately respond to queries for local zones instead of leaking them to upstream resolvers (always causing errors or timeouts). Edit dnscrypt-proxy.toml directly - block_ipv6 - Immediately respond to IPv6-related queries with an empty response. - This makes things faster when there is no IPv6 connectivity, but can also cause reliability issues with some stub resolvers. + Block IPv6 + Immediately respond to IPv6-related queries with an empty response. This makes things faster when there is no IPv6 connectivity, but can also cause reliability issues with some stub resolvers. Please turn off \"Private DNS\" in Android network settings. This option interferes with InviZible. Please disable proxy in Android WiFi network settings. This option interferes with InviZible. @@ -418,52 +407,55 @@ Too many rules to display. Only the first 1000 is shown. - VirtualAddrNetwork + Virtual Addr Network When Tor needs to assign a virtual (unused) address because of a MAPADDRESS command from the controller or the AutomapHostsOnResolve feature, Tor picks an unassigned address from this range. - HardwareAccel + Hardware Accel Try to use built-in crypto hardware acceleration when available. - AvoidDiskWrites + Avoid Disk Writes If non-zero, try to write to disk less frequently. - ConnectionPadding + Connection Padding This option governs Tor’s use of padding to defend against some forms of traffic analysis. Disable to save bandwidth. - ReducedConnectionPadding + Reduced Connection Padding If set enabled, Tor will not hold OR connections open for very long, and will send less padding on these connections. Enable to save bandwidth. - ExcludeExitNodes + Nodes + Isolation settings + Exclude Exit Nodes A list of country codes to never use when picking an exit node, that delivers traffic for you outside the Tor network. - ExitNodes + Exit Nodes A list of country codes to use as exit node - that is, a node that delivers traffic for you outside the Tor network. - ExcludeNodes + Exclude Nodes A list of country codes to avoid when building a circuit. - EntryNodes + Entry Nodes A list of country codes of nodes to use for the first hop in your normal circuits. Disable Tor bridges if you want to select entry nodes. - StrictNodes + Strict Nodes If StrictNodes enabled, Tor will treat solely the ExcludeNodes option as a requirement to follow for all the circuits you generate, even if doing so will break functionality for you. - FascistFirewall + Fascist Firewall If enabled, Tor will only create outgoing connections to ORs running on ports that your firewall allows (defaults to 80 and 443). - NewCircuitPeriod + To activate this option, you should disable bridges or use bridges with 80 and 443 ports only. + New Circuit Period Every NUM seconds consider whether to build a new circuit. - MaxCircuitDirtiness + Max Circuit Dirtiness Feel free to reuse a circuit that was first used at most NUM seconds ago, but never attach a new stream to a circuit that is too old. - DormantClientTimeout + Dormant Client Timeout Tor enters a dormant state if it does not see client activity for a specified time. Must be at least 10 minutes - EnforceDistinctSubnets + Enforce Distinct Subnets If enabled, Tor will not put two servers whose IP addresses are "too close" on the same circuit. Currently, two addresses are "too close" if they lie in the same /16 range. - Enable SOCKS proxy - SOCKSPort + SOCKS proxy + SOCKS Port Open this port to listen for connections from SOCKS-speaking applications. - Enable HTTPTunnel - HTTPTunnelPort + HTTP Tunnel + HTTP Tunnel Port Open this port to listen for proxy connections using the "HTTP CONNECT" protocol instead of SOCKS. - Enable Transparent proxy - TransPort + Transparent proxy + Trans Port Open this port to listen for transparent proxy connections. - Enable DNS - DNSPort + Resolve DNS + DNS Port Open this port to listen for UDP DNS requests, and resolve them anonymously. - ClientUseIPv4 + Client Use IPv4 If disable, Tor will avoid connecting to directory servers and entry nodes over IPv4. - ClientUseIPv6 + Client Use IPv6 If enabled, Tor might connect to directory servers or entry nodes over IPv6. Preference does not exist in tor.conf! Host or IP to unblock @@ -472,24 +464,23 @@ Disabled Snowflake Select rendezvous - - Hides the broker\'s domain name from the Internet provider. The broker is used to establish a connection. + Hides the broker\'s domain name from the Internet provider. The broker is used to establish a connection. AMP Fastly CDN77 AZURE AMAZON STUN servers for SnowFlake bridges - Enable SOCKS output proxy - Socks5Proxy + SOCKS outbound proxy + Socks5 Proxy Tor will make all OR connections through the SOCKS 5 proxy. Edit tor.conf directly Clear cache - TrackHostExits + Track Host Exits Tor will track recent connections to hosts and attempt to reuse the same exit node for each. This option may help avoid endless captcha. - IsolateDestAddr + Isolate Dest Addr Don’t share circuits with streams targeting a different destination address. - IsolateDestPort + Isolate Dest Port Don’t share circuits with streams targeting a different destination port. Apps to use with InviZible @@ -498,44 +489,47 @@ Select All Remove Selection - Common Settings - Allow incoming connections - incoming port - Port to listen for incoming connections. - incoming host - Router external IP for incoming connections. - ipv4 + Common settings + Incoming connections + Incoming port + Port to listen for incoming connections (default: auto (random)). + Incoming host + Router external IP for incoming connections (default: auto if SSU2 is enabled). + IPv4 Enable communication through IPv4. - ipv6 + IPv6 Enable communication through IPv6. - notransit + No transit Router will not accept transit tunnels, disabling transit traffic completely. - floodfill + Floodfill Router will be floodfill. - bandwidth + Bandwidth Bandwidth limit in KBps. - share + Share Max % of bandwidth limit for transit. 0–100. - ssu + SSU Enable SSU transport protocol (use UDP). - ssu2 + SSU2 Enable SSU2 transport protocol (use UDP). - ntcp + NTCP Enable NTCP2 transport protocol (use TCP). - Enable ntcpproxy - ntcpproxy + Outbound proxy + NTCP proxy Specify proxy server for NTCP. Should be http://address:port or socks://address:port. HTTP proxy HTTP proxy HTTP proxy port The port to listen on (HTTP Proxy). HTTP outproxy + Gateway to the regular internet HTTP outproxy address + HTTP proxy upstream out proxy url (like http://false.i2p) Socks proxy Socks proxy Socks proxy port The port to listen on (SOCKS Proxy). SOCKS outproxy + Address of outproxy(IP or local). Requests outside I2P will go there. SOCKS outproxy address SOCKS outproxy port SAM interface @@ -543,41 +537,37 @@ SAM interface port Port of SAM bridge. Cryptography - elgamal + Elgamal Use ElGamal precomputated tables. UPNP UPNP Enable or disable UPnP. - ntcp2 - ntcp2 enabled + NTCP2 Reseeding - verify - Verify .su3 signature. + Verify + Verify su3 signature. Limits - transittunnels + Transit tunnels Override maximum number of transit tunnels. 2500 by default. - openfiles + Open files Limit number of open file descriptors (0 - use system limit). - coresize - Maximum size of corefile in Kb (0 - use system limit). - Addressbook - defaulturl + Core size + Maximum size of core file in Kb (0 - use system limit). + Address book + Default url AddressBook subscription URL for initial setup. - subscriptions + Subscriptions AddressBook subscriptions URLs. Preference not exist in i2pd.conf! Edit i2pd.conf directly Edit tunnels.conf directly Info - Looks like DNSCrypt was killed by android system. - Your internet connection was restored. Check device Settings! - Looks like Tor was killed by android system. - Your internet connection was restored. Check device Settings! + Looks like DNSCrypt was killed by android system. Your internet connection was restored. Check device Settings! + Looks like Tor was killed by android system. Your internet connection was restored. Check device Settings! Looks like I2P was killed by android system. Check device Settings! Looks like DNSCrypt can\'t connect to the internet. You can try to choose another DNSCrypt servers. Please find them in MENU -> Fast Settings -> Select DNSCrypt servers - Looks like Tor can\'t connect to the internet. - ISP may blocks Tor connections. You can try to use Tor Bridges. Please find them in MENU -> Fast Settings -> Bridges + Looks like Tor can\'t connect to the internet. ISP may blocks Tor connections. You can try to use Tor Bridges. Please find them in MENU -> Fast Settings -> Bridges Child Lock You can lock control of this application. Please enter password, or use previous. @@ -593,12 +583,11 @@ Logs Saved. Please send InvizibleLogs.txt to developer. You can find logs in the folder: Update - Some of InviZible modules are ready for update. Do you want to update its? This will overwrite your modules settings! + Some of InviZible modules are ready for update. Do you want to update its? This will overwrite your modules settings! Update Later Not ask again - Please restart InviZible Pro and allow complete installation! - After installation reconfigure HOTSPOT, if you use it! + Please restart InviZible Pro and allow complete installation! After installation reconfigure HOTSPOT, if you use it! Version: Free @@ -644,12 +633,12 @@ DNSCrypt update is available. Do you want to download and update it? The update will continue in the background. Tor update is available. Do you want to download and update it? The update will continue in the background. Purple I2P update is available. Do you want to download and update it? The update will continue in the background. - Checking Updates - Please wait while Updates are checking. + Checking updates + Please wait while updates are checking. The update server is temporarily unavailable. Please try again later. The update server was unavailable. Update fault. - No Updates were Found. + No updates were found. Last check: Updates were found. Updates were installed. @@ -664,8 +653,7 @@ Visit Enter Code Enter Code - InviZible Pro Project and its author express appreciation - for the assistance. Would you like to download and upgrade to PRO? The update will continue in the background. + InviZible Pro Project and its author express appreciation for the assistance. Would you like to download and upgrade to PRO? The update will continue in the background. InviZible Pro Project and its author express appreciation for the assistance! Remote lists of available relays. @@ -682,8 +670,7 @@ Attention Reset - InviZible Pro cannot start %1$s! Please try resetting %2$s settings. - If this does not help, please reboot your device. + InviZible Pro cannot start %1$s! Please try resetting %2$s settings. If this does not help, please restart your device. Add custom server Invalid custom server configuration. Please check the SDNS field. @@ -734,8 +721,7 @@ Successful connection. Ping %s ms. ARP spoofing detected! Rogue DHCP detected! - Man-in-the-middle attack detected! Your data can be intercepted by another device on the local network. - Turn off, wait a few seconds, and turn on Wi-Fi. Using current Wi-Fi hotspot may be unsafe! + Man-in-the-middle attack detected! Your data can be intercepted by another device on the local network. Turn off, wait a few seconds, and turn on Wi-Fi. Using current Wi-Fi hotspot may be unsafe! ARP spoofing detection is not supported for your device! DNS rebinding Potential DNS Rebinding Attack Detected! Site %s has been blocked. @@ -769,8 +755,7 @@ Only apps that can connect to the Internet are shown. Change Tor IP Tor IP changing - You have added more than 3 tiles to Quick Settings. - Please leave only 3. Adding more than 3 tiles can cause issues with app control. + You have added more than 3 tiles to Quick Settings. Please leave only 3. Adding more than 3 tiles can cause issues with app control. List is Empty \u2193 Pull to refresh \u2193 Internet connectivity check diff --git a/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml b/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml index 72bed767d..48190aecf 100644 --- a/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml +++ b/tordnscrypt/src/main/res/xml/preferences_dnscrypt.xml @@ -3,7 +3,7 @@ android:key="dnscrypt_settings"> + - - - - - + + + + + + + + + + android:layout="@layout/preferences_category_advanced" + android:title="@string/pref_advanced" /> + + + + + + - - + + + + + + + + + + - - +