### Install Slipstream client binary via CMake Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Checks for the existence of the 'slipstream-client' executable in the 'tools' directory. If present, it installs the file as a program; otherwise, it logs an optional status message. ```cmake set(SLIPSTREAM_BIN "${CMAKE_CURRENT_SOURCE_DIR}/tools/slipstream-client") if(EXISTS "${SLIPSTREAM_BIN}") install(PROGRAMS "${SLIPSTREAM_BIN}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) message(STATUS "Slipstream client found: ${SLIPSTREAM_BIN}") else() message(STATUS "Slipstream client not found at ${SLIPSTREAM_BIN} (optional)") endif() ``` -------------------------------- ### Troubleshooting gomobile and gobind Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md These snippets address common issues encountered when working with Go mobile development, specifically 'gomobile not found' and 'gobind not found'. They provide commands to add the Go bin directory to the PATH and to install the necessary gobind tool. ```bash export PATH=$PATH:$HOME/go/bin gomobile init ``` ```bash go install golang.org/x/mobile/cmd/gobind@latest ``` -------------------------------- ### Install DNSTT shared library via CMake Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Checks for the existence of 'libdnstt.so' in the 'go_src' directory and schedules it for installation. If the file is missing, it issues a warning suggesting the user run the build script. ```cmake set(DNSTT_SO "${CMAKE_CURRENT_SOURCE_DIR}/../go_src/libdnstt.so") if(EXISTS "${DNSTT_SO}") install(FILES "${DNSTT_SO}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) message(STATUS "DNSTT library found: ${DNSTT_SO}") else() message(WARNING "DNSTT library not found at ${DNSTT_SO} - run 'scripts/build_linux.sh' to build it") endif() ``` -------------------------------- ### Plugin and Asset Installation Rules Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Includes generated plugin build rules. It sets up installation directories for the application bundle, including data and library paths. It installs the main executable, ICU data, Flutter library, bundled plugin libraries, and native assets. ```cmake include(flutter/generated_plugins.cmake) set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") install(DIRECTORY "${NATIVE_ASSETS_DIR}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Device Testing and Logging with ADB Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md This section provides essential Android Debug Bridge (ADB) commands for testing and debugging on a device or emulator. It covers checking connected devices, verifying device architecture, installing the APK, and viewing application logs, including filtering for specific service or flutter logs. ```bash # Check connected devices adb devices ``` ```bash # Check device architecture adb shell getprop ro.product.cpu.abi ``` ```bash # Install APK adb install -r build/app/outputs/flutter-apk/app-debug.apk ``` ```bash # View logs adb logcat | grep -E "(DnsttVpnService|flutter|dnstt)" ``` ```bash # Clear logs and watch adb logcat -c && adb logcat | grep DnsttVpnService ``` ```bash # Install specific architecture release APK adb install -r build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ``` ```bash # Run with logs flutter run --release ``` ```bash # Watch logs adb logcat | grep DnsttVpnService ``` -------------------------------- ### Test DNS Servers with AppState Provider Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Shows how to initiate and manage DNS server testing using the AppState provider. It includes starting tests for all servers, testing a single server, canceling ongoing tests, and accessing the progress and results of the testing process. ```dart // Test DNS servers await appState.startTestingAllDnsServers(); // Tests all servers await appState.testSingleDnsServer(server); // Test one server await appState.cancelTesting(); // Cancel ongoing tests // Check testing progress print('Progress: ${appState.testingProgress}/${appState.testingTotal}'); print('Working: ${appState.testingWorking}, Failed: ${appState.testingFailed}'); ``` -------------------------------- ### Create and Manage DNSTT Client (Go) Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Provides core DNSTT tunnel functionality exposed via gomobile bindings. Allows creating a client with specified DNS server, tunnel domain, public key, and listen address. Supports starting, stopping, and checking the client's running status. ```go package mobile import "mobile" // Create a new DNSTT client // Parameters: // dnsServer: DNS server IP (e.g., "8.8.8.8") // tunnelDomain: Tunnel domain (e.g., "tunnel.example.com") // pubKeyHex: 64-character hex public key // listenAddr: Local SOCKS5 address (e.g., "127.0.0.1:7000") client, err := mobile.NewClient( "8.8.8.8", "tunnel.example.com", "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2", "127.0.0.1:7000", ) if err != nil { log.Fatal("Failed to create client:", err) } // Optional: Enable proxy sharing (bind to 0.0.0.0) client.SetShareProxy(true) // Optional: Set socket protection callback for Android VPN client.SetProtectSocket(func(fd int) bool { // Call Android's VpnService.protect(fd) return protectSocketFromVpn(fd) }) // Start the SOCKS5 proxy if err := client.Start(); err != nil { log.Fatal("Failed to start:", err) } deferr client.Stop() // Check if running fmt.Println("Running:", client.IsRunning()) // Dial through the tunnel (for custom connections) conn, err := client.DialTunnel("target.example.com:443") if err != nil { log.Fatal("Dial failed:", err) } deferr conn.Close() // Get local IP addresses (for proxy sharing display) ips := mobile.GetLocalIPAddresses() fmt.Println("Local IPs:", ips) // "192.168.1.100,10.0.0.5" ``` -------------------------------- ### Project Configuration and Build Settings Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Sets up the CMake version, project name, executable name, and application ID. It also configures build policies, installation paths, and root filesystem for cross-compiling. Defines build type (Debug, Profile, Release) if not already set. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) set(BINARY_NAME "dnstt_xyz_app") set(APPLICATION_ID "xyz.dnstt.app") cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() ``` -------------------------------- ### Troubleshooting NDK Errors Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md This section provides guidance on resolving NDK (Native Development Kit) errors during AAR builds. It suggests ensuring the NDK is installed via Android Studio's SDK Manager or by explicitly setting the ANDROID_NDK_HOME environment variable to the correct NDK path. ```bash # Ensure NDK is installed via Android Studio SDK Manager # Or set ANDROID_NDK_HOME export ANDROID_NDK_HOME=$HOME/Library/Android/sdk/ndk/25.2.9519653 ``` -------------------------------- ### Manage Slipstream Client Lifecycle and Testing in Dart Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Demonstrates how to initialize the SlipstreamService, start a tunnel client with specific congestion control settings, perform server latency tests, and stop the service. This implementation relies on the dnstt_xyz_app service layer to interface with the underlying binary. ```dart import 'package:dnstt_xyz_app/services/slipstream_service.dart'; final slipstream = SlipstreamService.instance; // Start slipstream client final started = await slipstream.startClient( domain: 'fast.example.com', // Tunnel domain dnsServerAddr: '8.8.8.8', // DNS resolver listenPort: 7000, // Local SOCKS5 port congestionControl: 'dcubic', // 'dcubic' (default) or 'bbr' keepAliveInterval: 400, // Keep-alive in ms gso: false, // Generic Segmentation Offload ); if (started) { print('Slipstream running on port 7000'); // Configure browser: SOCKS5 proxy at 127.0.0.1:7000 } else { print('Failed to start: ${slipstream.lastError}'); } // Check status print('Is running: ${slipstream.isRunning}'); // Test a server (spawns temporary client) final latency = await slipstream.testServer( domain: 'fast.example.com', dnsServerAddr: '8.8.8.8', testUrl: 'https://api.ipify.org?format=json', timeoutMs: 15000, congestionControl: 'dcubic', keepAliveInterval: 400, ); if (latency >= 0) { print('Server working! Latency: ${latency}ms'); } else { print('Server test failed'); } // Stop the client await slipstream.stopClient(); ``` -------------------------------- ### GET /testDnsServer Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Performs a latency test against a DNS server through the DNSTT tunnel. ```APIDOC ## GET testDnsServer ### Description Tests connectivity and latency to a DNS server through the tunnel. ### Method GET ### Endpoint xyz.dnstt.app/vpn -> testDnsServer ### Parameters #### Query Parameters - **dnsServer** (string) - Required - Server to test - **tunnelDomain** (string) - Required - Tunnel domain - **timeoutMs** (int) - Optional - Timeout in milliseconds ### Response #### Success Response (200) - **latencyMs** (int) - Latency in ms, or -1 for failure, -2 for cancelled ### Response Example { "latencyMs": 450 } ``` -------------------------------- ### Build Windows Desktop Application Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Steps to compile the Go library as a DLL and integrate it into a Windows Flutter build. ```bash cd go_src CGO_ENABLED=1 go build -buildmode=c-shared -o dnstt.dll ./desktop cd .. flutter pub get flutter build windows --release cp go_src/dnstt.dll build/windows/x64/runner/Release/ ``` -------------------------------- ### Build Linux Desktop Application Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Steps to compile the Go library as a shared object and integrate it into a Linux Flutter build. ```bash cd go_src CGO_ENABLED=1 go build -buildmode=c-shared -o libdnstt.so ./desktop cd .. flutter pub get flutter build linux --release cp go_src/libdnstt.so build/linux/x64/release/bundle/lib/ ``` -------------------------------- ### Build macOS Desktop Application Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Commands to compile the Go shared library, build the Flutter application, and sign the resulting macOS bundle. ```bash cd go_src CGO_ENABLED=1 go build -buildmode=c-shared -o libdnstt.dylib ./desktop cd .. flutter pub get flutter build macos --release cp go_src/libdnstt.dylib build/macos/Build/Products/Release/DNSTT_XYZ.app/Contents/Frameworks/ codesign --force --sign - build/macos/Build/Products/Release/DNSTT_XYZ.app/Contents/Frameworks/libdnstt.dylib codesign --force --sign - build/macos/Build/Products/Release/DNSTT_XYZ.app ``` -------------------------------- ### Generate and Configure Android Release Signing Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Steps to generate a Java Keystore and configure the Gradle build system to use these credentials for signing release builds. ```bash keytool -genkey -v -keystore ~/dnstt-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias dnstt-key ``` ```properties storePassword=your_store_password keyPassword=your_key_password keyAlias=dnstt-key storeFile=/Users/yourname/dnstt-release-key.jks ``` ```gradle def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] } } buildTypes { release { signingConfig signingConfigs.release } } } ``` -------------------------------- ### Initialize and Use AppState Provider in Flutter Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Demonstrates how to initialize the AppState provider with a StorageService, integrate it with the Flutter widget tree using ChangeNotifierProvider, and access the state within consumer widgets. It shows how to display connection status, list DNS servers with their latency and working status, and list configurations with options to set the active one. ```dart import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:dnstt_xyz_app/providers/app_state.dart'; import 'package:dnstt_xyz_app/services/storage_service.dart'; import 'package:dnstt_xyz_app/models/dns_server.dart'; import 'package:dnstt_xyz_app/models/dnstt_config.dart'; // Initialize AppState with storage final storage = await StorageService.init(); final appState = AppState(); await appState.init(storage); // Use with Provider in Flutter runApp( ChangeNotifierProvider.value( value: appState, child: MyApp(), ), ); // Access in widgets class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer( builder: (context, state, child) { return Column( children: [ // Display connection status Text('Status: ${state.connectionStatus}'), // List DNS servers sorted by latency ...state.dnsServers.map((server) => ListTile( title: Text(server.name ?? server.address), subtitle: Text('${server.lastLatencyMs ?? "?"} ms'), trailing: server.isWorking ? Icon(Icons.check, color: Colors.green) : Icon(Icons.close, color: Colors.red), )), // List configurations ...state.dnsttConfigs.map((config) => ListTile( title: Text(config.name), subtitle: Text('${config.transportType.name} - ${config.tunnelDomain}'), selected: state.activeConfig?.id == config.id, onTap: () => state.setActiveConfig(config), )), ], ); }, ); } } ``` -------------------------------- ### Build Go AAR with gomobile Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md This snippet demonstrates how to rebuild the Go library into an Android Archive (AAR) file using gomobile. It involves navigating to the Go source directory, running the `gomobile bind` command with specific targets and API levels, and then copying the resulting AAR file to the Android project's libs directory. ```bash cd go_src gomobile bind -v -androidapi 21 -target=android -o dnstt.aar ./mobile cp dnstt.aar ../android/app/libs/ cd .. ``` -------------------------------- ### Build and Compile Application for Multiple Platforms Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Contains shell commands for building the Flutter application on Android, macOS, Windows, and Linux. It also includes instructions for recompiling the underlying Go libraries for mobile and desktop targets. ```bash # Build Android APKs flutter build apk --release --split-per-abi # Build macOS app ./scripts/build_macos.sh release # Rebuild Go library for Android cd go_src gomobile bind -v -androidapi 21 -target=android -o dnstt.aar ./mobile cp dnstt.aar ../android/app/libs/ ``` -------------------------------- ### POST /connect Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Establishes a full device VPN connection using the DNSTT protocol. ```APIDOC ## POST connect ### Description Connects the DNSTT VPN, routing all device traffic through the specified tunnel. ### Method POST ### Endpoint xyz.dnstt.app/vpn -> connect ### Request Body - **proxyHost** (string) - Required - Local proxy host address - **proxyPort** (int) - Required - Local proxy port - **dnsServer** (string) - Required - Upstream DNS server - **tunnelDomain** (string) - Required - Target tunnel domain - **publicKey** (string) - Required - DNSTT public key ### Request Example { "proxyHost": "127.0.0.1", "proxyPort": 7000, "dnsServer": "8.8.8.8", "tunnelDomain": "tunnel.example.com", "publicKey": "a1b2c3..." } ``` -------------------------------- ### Manage Configurations with AppState Provider Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Demonstrates how to manage DNSTT configurations using the AppState provider. This includes adding a new configuration with essential details like name, tunnel domain, and public key, setting an active configuration, and setting an active DNS server. ```dart // Manage configurations await appState.addDnsttConfig(DnsttConfig( name: 'My Server', tunnelDomain: 'tunnel.example.com', publicKey: 'a1b2c3...', )); await appState.setActiveConfig(config); await appState.setActiveDns(dnsServer); ``` -------------------------------- ### Build Slipstream for Desktop Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt This script compiles the Slipstream client for desktop platforms. It outputs the necessary binary to the designated platform-specific library directory for integration with the runner. ```bash ./scripts/build_slipstream_desktop.sh ``` -------------------------------- ### Apply Standard Build Settings (CMake) Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/windows/runner/CMakeLists.txt Applies a standard set of build settings to the specified target. This simplifies configuration for common build requirements. It can be removed if the application requires custom build settings. ```cmake # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Build Flutter App Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Commands to clean and build the Flutter application. This includes cleaning previous build artifacts, fetching dependencies, and then building the APK in either debug or release mode. The release build can be further optimized by splitting the APK per architecture. ```bash flutter clean flutter pub get flutter build apk --debug ``` ```bash flutter clean flutter pub get flutter build apk --release ``` ```bash flutter clean flutter pub get flutter build apk --release --split-per-abi ``` ```bash flutter clean flutter pub get flutter build apk --release --target-platform android-arm64 ``` -------------------------------- ### Configure Android Gradle Build Settings Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Configuration snippets for the android/app/build.gradle file, covering application versioning and AAR dependency inclusion. ```gradle android { defaultConfig { applicationId "xyz.dnstt.app" minSdkVersion 21 targetSdkVersion 34 versionCode 1 versionName "1.0.0" } } dependencies { implementation fileTree(dir: 'libs', include: ['*.aar']) } ``` -------------------------------- ### Clean Release APKs for Distribution Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md This script automates the process of cleaning release APKs by removing build metadata like properties and version control information, and then re-signing them. It sets up necessary environment variables for Android SDK tools and processes each APK in a specified directory. ```bash cd build/app/outputs/flutter-apk # Set up Android SDK tools ANDROID_SDK="$HOME/Library/Android/sdk" BUILD_TOOLS=$(ls -d "$ANDROID_SDK/build-tools"/*/ | tail -1) APKSIGNER="$BUILD_TOOLS/apksigner" DEBUG_KEYSTORE="$HOME/.android/debug.keystore" # Create clean directory mkdir -p clean_apks # Process each APK for apk in app-*-release.apk; do # Copy original cp "$apk" "clean_apks/$apk" # Remove metadata files zip -d "clean_apks/$apk" \ "META-INF/com/android/build/gradle/app-metadata.properties" \ "META-INF/version-control-info.textproto" \ 2>/dev/null || true # Re-sign the APK "$APKSIGNER" sign --ks "$DEBUG_KEYSTORE" \ --ks-pass pass:android --key-pass pass:android \ "clean_apks/$apk" done # Remove extended attributes (macOS) xattr -c clean_apks/*.apk 2>/dev/null ``` -------------------------------- ### Verify APK Metadata and Signatures Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Shell scripts to check for unwanted metadata in APK files and verify their cryptographic signatures using apksigner. ```bash for apk in clean_apks/*.apk; do echo "--- $(basename $apk) ---" if unzip -l "$apk" | grep -qE "app-metadata|version-control"; then echo "WARNING: Metadata present" else echo "Metadata removed ✓" fi done for apk in clean_apks/*.apk; do "$APKSIGNER" verify "$apk" && echo "$(basename $apk): Valid ✓" done ``` -------------------------------- ### Define Executable Target with CMake Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/runner/CMakeLists.txt This snippet defines the main executable target for the application. It lists the source files, including the main entry point, application-specific files, and generated plugin registrant code. The executable name is controlled by BINARY_NAME. ```cmake cmake_minimum_required(VERSION 3.13) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add preprocessor definitions for the application ID. add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Dependency Management and Subdirectory Inclusion Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Loads bundled libraries, finds PkgConfig, checks for GTK+ 3.0, and includes the Flutter managed directory and the runner subdirectory. It also adds dependencies for the main binary to ensure Flutter assembly is complete. ```cmake set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_subdirectory("runner") add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Build and Package Flutter Android Application Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md Commands to manage dependencies and generate various Android build artifacts, including debug APKs, release APKs, split ABIs, and App Bundles for the Play Store. ```bash flutter pub get flutter build apk --debug flutter build apk --release flutter build apk --release --split-per-abi flutter build apk --release --target-platform android-arm64 flutter build appbundle --release ``` -------------------------------- ### Troubleshooting App Crashes and VPN Permissions Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/CLAUDE.md This snippet helps diagnose app crashes by instructing users to check logs for FATAL exceptions. It also details the necessary AndroidManifest.xml configurations for VPN services, including required permissions and service declarations, to prevent 'VPN permission denied' errors. ```bash adb logcat | grep -E "(FATAL|Exception|DnsttVpnService)" ``` ```xml ``` -------------------------------- ### Executable Output Directory Configuration Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Configures the output directory for the main executable. It places the executable in a subdirectory `intermediates_do_not_run` to prevent users from running the unbundled copy, ensuring correct resource loading. ```cmake set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) ``` -------------------------------- ### Configure Connection Settings with AppState Provider Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt This snippet details how to configure various connection settings through the AppState provider. It covers setting the proxy port, defining a test URL for connectivity checks, specifying the connection mode (VPN or proxy), and enabling or disabling automatic DNS detection. ```dart // Configure connection settings await appState.setProxyPort(7000); await appState.setTestUrl('https://www.google.com'); await appState.setConnectionMode('vpn'); // 'vpn' or 'proxy' on Android await appState.setUseAutoDns(true); // Auto-detect system DNS ``` -------------------------------- ### Standard Compilation Settings Function Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/CMakeLists.txt Defines a CMake function `APPLY_STANDARD_SETTINGS` to apply common compilation features and options to a target. It enforces C++14, enables all warnings, sets optimization levels, and defines NDEBUG for non-Debug builds. ```cmake function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "<$>:NDEBUG>") endfunction() ``` -------------------------------- ### Define Executable Target with Source Files (CMake) Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/windows/runner/CMakeLists.txt Defines the main executable target for the application, listing all necessary source files. This configuration is crucial for the build system to compile the application correctly. It includes C++ source files, generated plugin registration code, and resource files. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) ``` -------------------------------- ### Add Preprocessor Definitions for Build Version (CMake) Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/windows/runner/CMakeLists.txt Adds preprocessor definitions to the target for build version information. This allows the application to access version details at compile time. It defines major, minor, patch, and build numbers. ```cmake # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") ``` -------------------------------- ### Import/Export Configurations and DNS Servers (Dart) Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Handles importing and exporting DNSTT tunnel configurations and DNS server lists. Supports importing from URLs or JSON strings, and exporting to JSON. It also fetches official servers from dnstt.xyz. ```dart import 'package:dnstt_xyz_app/services/config_import_export_service.dart'; import 'package:dnstt_xyz_app/models/dnstt_config.dart'; import 'package:dnstt_xyz_app/models/dns_server.dart'; // Import configs from URL final configs = await ConfigImportExportService.importConfigsFromUrl( 'https://example.com/dnstt-configs.json', ); // Expected JSON format: // { // "version": "1.0", // "configs": [ // { // "name": "Server 1", // "tunnelDomain": "tunnel1.example.com", // "publicKey": "a1b2c3...", // "transportType": "dnstt" // }, // { // "name": "Fast Server", // "tunnelDomain": "fast.example.com", // "transportType": "slipstream", // "congestionControl": "bbr" // } // ] // } // Import from JSON string (file contents) final jsonString = '{"configs": [...]}'; final parsedConfigs = ConfigImportExportService.importConfigsFromJson(jsonString); // Export configs to JSON final exportedJson = ConfigImportExportService.exportConfigsToJson(configs); print(exportedJson); // Output: // { // "version": "1.3", // "configs": [ // { // "name": "Server 1", // "tunnelDomain": "tunnel1.example.com", // "transportType": "dnstt", // "tunnelType": "socks5", // "publicKey": "a1b2c3..." // } // ] // } // Import DNS servers from URL final dnsServers = await ConfigImportExportService.importDnsServersFromUrl( 'https://example.com/dns-servers.json', ); // Expected JSON format: // { // "version": "1.0", // "servers": [ // {"ip": "8.8.8.8", "name": "Google DNS", "region": "US"}, // {"ip": "1.1.1.1", "name": "Cloudflare", "provider": "Cloudflare"} // ] // } // Export DNS servers final dnsJson = ConfigImportExportService.exportDnsServersToJson(dnsServers); // Fetch official servers from dnstt.xyz final result = await ConfigImportExportService.fetchDnsttXyzServers(); print('Found ${result.configs.length} configs'); print('Found ${result.dnsServers.length} DNS servers'); ``` -------------------------------- ### Manage DNS Servers with AppState Provider Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt This snippet illustrates the methods provided by the AppState class for managing DNS servers. It covers adding individual servers, importing multiple servers from a list, removing a specific server by its ID, and clearing all managed DNS servers. ```dart // Manage DNS servers await appState.addDnsServer(DnsServer(address: '8.8.8.8', name: 'Google')); await appState.importDnsServers([ DnsServer(address: '1.1.1.1', name: 'Cloudflare'), DnsServer(address: '9.9.9.9', name: 'Quad9'), ]); await appState.removeDnsServer('server-id'); await appState.clearAllDnsServers(); ``` -------------------------------- ### POST /connectSshTunnel Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt Establishes a secure SSH tunnel with dynamic forwarding capabilities. ```APIDOC ## POST connectSshTunnel ### Description Connects an SSH tunnel using DNSTT as the transport layer. ### Method POST ### Endpoint xyz.dnstt.app/vpn -> connectSshTunnel ### Request Body - **dnsServer** (string) - Required - Upstream DNS server - **tunnelDomain** (string) - Required - Target tunnel domain - **publicKey** (string) - Required - DNSTT public key - **sshUsername** (string) - Required - SSH login username - **sshPassword** (string) - Required - SSH login password - **shareProxy** (boolean) - Optional - Allow LAN access to proxy ### Request Example { "dnsServer": "8.8.8.8", "tunnelDomain": "ssh.example.com", "publicKey": "a1b2c3...", "sshUsername": "user", "sshPassword": "pass", "shareProxy": false } ``` -------------------------------- ### Link Libraries and Include Directories (CMake) Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/windows/runner/CMakeLists.txt Specifies the libraries and include directories required for the target. This ensures that the compiler and linker can find all necessary components. It includes Flutter-specific libraries and system libraries like dwmapi.lib. ```cmake # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Manage VPN Tunnel Connections with VpnService Source: https://context7.com/dnstt-xyz/dnstt_xyz_app/llms.txt The VpnService singleton manages tunnel connections across platforms, supporting DNSTT, Slipstream, and SSH tunnel modes. It allows configuration of proxy ports, connection via different transports, and listening to connection state changes. Dependencies include the VpnService class itself and models like DnsttConfig. ```dart import 'package:dnstt_xyz_app/services/vpn_service.dart'; import 'package:dnstt_xyz_app/models/dnstt_config.dart'; final vpnService = VpnService(); await vpnService.init(); // Configure proxy port (default: 1080) vpnService.proxyPort = 7000; // Connect using DNSTT transport (VPN mode on Android) final connected = await vpnService.connect( proxyHost: '127.0.0.1', proxyPort: 7000, dnsServer: '8.8.8.8', tunnelDomain: 'tunnel.example.com', publicKey: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2', ); // Connect using Slipstream transport (faster QUIC-over-DNS) final slipstreamConnected = await vpnService.connectSlipstream( dnsServer: '8.8.8.8', tunnelDomain: 'fast.example.com', congestionControl: 'dcubic', // 'dcubic' or 'bbr' keepAliveInterval: 400, gso: false, ); // Connect in proxy-only mode (Android, no VPN) final proxyConnected = await vpnService.connectProxy( dnsServer: '8.8.8.8', tunnelDomain: 'tunnel.example.com', publicKey: 'a1b2c3...', proxyPort: 7000, ); // Connect SSH tunnel (DNSTT + SSH dynamic port forwarding) final sshConnected = await vpnService.connectSshTunnel( dnsServer: '8.8.8.8', tunnelDomain: 'ssh.example.com', publicKey: 'a1b2c3...', sshUsername: 'tunnel_user', sshPassword: 'password123', ); // Listen to connection state changes vpnService.stateStream.listen((state) { switch (state) { case VpnState.connecting: print('Connecting...'); break; case VpnState.connected: print('Connected! SOCKS5 proxy at ${vpnService.socksProxyAddress}'); break; case VpnState.disconnected: print('Disconnected'); break; case VpnState.error: print('Error: ${vpnService.lastError}'); break; } }); // Check connection status print('Is connected: ${await vpnService.isConnected()}'); print('Active transport: ${vpnService.activeTransport}'); // DNSTT or Slipstream // Disconnect await vpnService.disconnect(); ``` -------------------------------- ### Prepend prefix to CMake list Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/linux/flutter/CMakeLists.txt A utility function that iterates through a list and prepends a specified prefix to each element. This is used as a workaround for the lack of list(TRANSFORM) support in CMake 3.10. ```cmake function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() ``` -------------------------------- ### Configure Flutter Library and C++ Wrappers in CMake Source: https://github.com/dnstt-xyz/dnstt_xyz_app/blob/main/windows/flutter/CMakeLists.txt This snippet defines the Flutter interface library and the static C++ wrapper libraries required for plugins and applications. It sets up include directories, links the Flutter DLL, and ensures dependencies are built via the flutter_assemble target. ```cmake add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}") target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP}) target_link_libraries(flutter_wrapper_app PUBLIC flutter) ```