Skip to content

Commit a0d7247

Browse files
committed
1.4.8 release
1 parent a0f7e41 commit a0d7247

File tree

162 files changed

+20149
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+20149
-31
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Use default line ending for Git (LF)
2+
* text=auto

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.user
2+
generated
3+
build/

.gitlab-ci.yml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
stages:
2+
- Build
3+
- Test
4+
- Artifact Links
5+
6+
variables:
7+
BUILD_WIN: 'y'
8+
BUILD_WIN_ARM64: 'y'
9+
BUILD_MAC: 'y'
10+
BUILD_LINUX: 'y'
11+
BUILD_LINUX_ARM64: 'y'
12+
BUILD_LINUX_CLI: 'y'
13+
NIGHTLY_TEST_BUILD: 'n'
14+
GIT_DEPTH: 5 # Only grab the last 5 commits when cloning
15+
NEXUS_PATH_ROOT: 'https://nexus.int.windscribe.com/repository/client-desktop/client-desktop'
16+
NEXUS_PATH_DEPS: '$NEXUS_PATH_ROOT/dependencies/current'
17+
NEXUS_PATH_VCPKG_CACHE: '$NEXUS_PATH_ROOT/vcpkg_cache/current'
18+
NEXUS_PATH_BRANCH_UPLOAD: '${NEXUS_PATH_ROOT}/branches/${CI_COMMIT_BRANCH}'
19+
NEXUS_PATH_TAGGED_UPLOAD: '${NEXUS_PATH_ROOT}/tagged-builds'
20+
ARCH_LINUX_BUILD_PATH: '/home/build/windscribe'
21+
RHEL_CMAKE_BUILD_PATH: '/home/build/windscribe'
22+
BUILD_LIBS_FOLDER: 'build-libs'
23+
VCPKG_ROOT_WINDOWS: 'c:\vcpkg'
24+
VCPKG_DEFAULT_BINARY_CACHE_WINDOWS: 'c:\vcpkg_cache'
25+
26+
.template_win10_build: &template_win10_build
27+
tags: [win10qty6]
28+
before_script:
29+
- $env:VCPKG_ROOT = $env:VCPKG_ROOT_WINDOWS
30+
- $env:VCPKG_DEFAULT_BINARY_CACHE = $env:VCPKG_DEFAULT_BINARY_CACHE_WINDOWS
31+
- $env:VCPKG_INSTALL_OPTIONS = "--clean-after-build"
32+
- if (Test-Path ws-vcpkg-registry) { Remove-Item -Recurse -Force ws-vcpkg-registry }
33+
- git clone https://github.com/Windscribe/ws-vcpkg-registry.git
34+
- .\ws-vcpkg-registry\install-vcpkg\vcpkg_install.bat $env:VCPKG_ROOT_WINDOWS --configure-git
35+
interruptible: true
36+
37+
.template_mac_build: &template_mac_build
38+
tags: [macos-arm64-qt6]
39+
before_script:
40+
- export VCPKG_ROOT="${HOME}/vcpkg"
41+
- export VCPKG_INSTALL_OPTIONS="--clean-after-build"
42+
- rm -rf ws-vcpkg-registry
43+
- git clone https://github.com/Windscribe/ws-vcpkg-registry.git
44+
- ./ws-vcpkg-registry/install-vcpkg/vcpkg_install.sh "${VCPKG_ROOT}" --configure-git
45+
interruptible: true
46+
47+
.template_aarch64_ubuntu_build: &template_aarch64_ubuntu_build
48+
tags: [linux-arm64-qt6]
49+
image: registry.gitlab.int.windscribe.com:5005/ws/client/desktop/client-desktop/ubuntu-aarch64
50+
before_script:
51+
- python3 -m pip install --user -r tools/requirements.txt
52+
# hack to fix 777 file permissions, which breaks the dpkg-deb command in the build_all script.
53+
- chmod -R o-w src/installer/linux
54+
# vcpkg settings
55+
- export VCPKG_ROOT="${HOME}/vcpkg"
56+
- export VCPKG_FORCE_SYSTEM_BINARIES=1
57+
- wget -q https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-aarch64.tar.gz && mkdir -p tools/patchelf && tar -C tools/patchelf -xzf patchelf-0.18.0-aarch64.tar.gz
58+
- export PATH=${RHEL_CMAKE_BUILD_PATH}/bin:`pwd`/tools/patchelf/bin:$PATH
59+
- cmake --version
60+
- ninja --version
61+
interruptible: true
62+
63+
.template_rhel_build: &template_rhel_build
64+
# RHEL 8.4 is the minimum build target for Qt 6.5
65+
# Could not use the RHEL 8.4 ubi Docker images, as they require a subscription license in order to install many of the packages we require below.
66+
image: registry.gitlab.int.windscribe.com:5005/ws/client/desktop/client-desktop/fedora36
67+
before_script:
68+
# hack to fix 777 file permissions, which breaks the dpkg-deb command in the build_all script.
69+
- chmod -R o-w src/installer/linux
70+
# vcpkg settings
71+
- export VCPKG_ROOT="${HOME}/vcpkg"
72+
- export PATH=${RHEL_CMAKE_BUILD_PATH}/bin:$PATH
73+
- python3 -m pip install -r tools/requirements.txt
74+
interruptible: true
75+
76+
77+
78+
build:wsnet:win:
79+
<<: *template_win10_build
80+
stage: Build
81+
variables:
82+
GIT_STRATEGY: clone
83+
script:
84+
- cmake -B build -S .
85+
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"
86+
-DVCPKG_TARGET_TRIPLET=ws-x64-windows-static-release
87+
-DVCPKG_HOST_TRIPLET=ws-x64-windows-static-release
88+
-DIS_BUILD_TESTS=ON
89+
- cmake --build build --config Release --parallel
90+
rules:
91+
- if: $BUILD_WIN == "y" && $NIGHTLY_TEST_BUILD == "y"
92+
- if: $CI_PIPELINE_SOURCE == "push" && $BUILD_WIN == "y"
93+
artifacts:
94+
expire_in: 1 day
95+
paths:
96+
- build/test
97+
98+
build:wsnet:mac:
99+
<<: *template_mac_build
100+
stage: Build
101+
variables:
102+
GIT_STRATEGY: clone
103+
script:
104+
- cmake -B build -S .
105+
-DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
106+
-DVCPKG_TARGET_TRIPLET=ws-universal-osx
107+
-DIS_BUILD_TESTS=ON
108+
- cmake --build build --parallel
109+
artifacts:
110+
expire_in: 1 day
111+
paths:
112+
- build/test
113+
- build/libs/wsnet
114+
- build/_cmrc
115+
rules:
116+
- if: $BUILD_MAC == "y" && $NIGHTLY_TEST_BUILD == "y"
117+
- if: $CI_PIPELINE_SOURCE == "push" && $BUILD_MAC == "y"
118+

CLAUDE.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
**wsnet** is a cross-platform C++17 networking library for Windscribe VPN clients (Windows/Mac/Linux/Android/iOS). It provides unified access to Windscribe's server APIs with built-in anti-censorship bypass methods, along with DNS resolution, HTTP networking, and ping functionality.
8+
9+
The library uses:
10+
- **Boost.ASIO** for async I/O (single io_context thread model)
11+
- **libcurl** (with ECH patches) for HTTP requests
12+
- **c-ares** for asynchronous DNS resolution
13+
- **OpenSSL** (with ECH patches) for TLS
14+
- **Scapix** for automatic C++ → Java/Swift bindings on mobile platforms
15+
- **vcpkg** for dependency management
16+
17+
## Building
18+
19+
### Desktop (Windows/Mac/Linux)
20+
21+
The library integrates via vcpkg. CMake must be installed along with platform-specific C++ compiler (Visual C++/XCode/clang).
22+
23+
**Build with tests (desktop only):**
24+
```bash
25+
cmake -B build -S . \
26+
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
27+
-DIS_BUILD_TESTS=ON
28+
cmake --build build
29+
```
30+
31+
**Run tests:**
32+
```bash
33+
./build/test/wsnet_test
34+
```
35+
36+
Tests use Google Test and are located in `src/private/tests/`. Tests are only built when `IS_BUILD_TESTS` is defined and are excluded from mobile builds.
37+
38+
### Android
39+
40+
**Requirements:** Android Studio, `$VCPKG_ROOT` and `$JAVA_HOME` environment variables set.
41+
42+
```bash
43+
cd tools
44+
./build_android.sh
45+
```
46+
47+
Output: `wsnet.aar` (Android Archive ready for integration)
48+
49+
### iOS
50+
51+
**Requirements:** XCode, `$VCPKG_ROOT` environment variable set.
52+
53+
```bash
54+
cd tools
55+
./build_ios.sh
56+
```
57+
58+
Output: `build/WSNet.xcframework` (supports iOS, iOS Simulator, tvOS, tvOS Simulator)
59+
60+
## Architecture
61+
62+
### Core Components
63+
64+
The library is accessed through a singleton `WSNet::instance()` after initialization. Main components:
65+
66+
- **ServerAPI** - Main Windscribe API access (login, session, server locations, WireGuard configs, etc.) with full failover support
67+
- **BridgeAPI** - Legacy Bridge protocol API (IP rotation, simple session-based, no failover)
68+
- **DnsResolver** - Async DNS with custom server support and caching
69+
- **HttpNetworkManager** - HTTP client with custom DNS integration and TLS modifications (SNI spoofing, ECH)
70+
- **EmergencyConnect** - Fallback connectivity via hardcoded OpenVPN endpoints
71+
- **PingManager** - ICMP and HTTP ping functionality
72+
- **DecoyTraffic** - Traffic obfuscation features
73+
- **ApiResourcesManager** - Manages API resources like server lists
74+
75+
All async operations return `shared_ptr<WSNetCancelableCallback>` for cancellation and use callback pattern.
76+
77+
### Public/Private Build System
78+
79+
The codebase has a **dual-build configuration**:
80+
81+
- **`src/private/`** - Production build with proprietary censorship bypass methods (16+ failover strategies including ECH, CDN fronting, dynamic domains). Contains `privatesettings.h` with hardcoded (obfuscated) endpoints and credentials.
82+
83+
- **`src/public/`** - Open-source fallback with minimal failover (only hardcoded domains).
84+
85+
CMake automatically selects private if it exists, otherwise uses public. Both implement the same `IFailoverContainer` interface.
86+
87+
### Failover Mechanism
88+
89+
ServerAPI uses a **hierarchical failover system** to bypass censorship:
90+
91+
1. Each request goes through `RequestExecutorViaFailover`
92+
2. Tries failovers sequentially (tracked by UUID to prevent loops)
93+
3. Each `BaseFailover` returns `FailoverData` containing:
94+
- `domain` - Target domain
95+
- `sniDomain` - SNI for domain fronting
96+
- `echConfig` - Encrypted Client Hello configuration
97+
- `ttl` - Time-to-live for dynamic failovers
98+
4. If all failovers fail → returns `ApiRetCode::kFailoverFailed`
99+
100+
Failover types (private build): hardcoded domains → ECH with Cloudflare → dynamic Cloudflare → dynamic Google DoH → direct IP access → CDN fronting (Fastly/Yelp/PyPI).
101+
102+
### Mobile Bindings (Scapix)
103+
104+
For Android/iOS builds, Scapix automatically generates Java/Swift bindings from C++ headers:
105+
106+
- All public headers in `include/wsnet/WSNet*.h` are bridged
107+
- Each header must contain exactly one class matching the filename (Java requirement)
108+
- All public classes inherit from `scapix_object<T>` (empty on desktop, actual bridge on mobile)
109+
- Generated code: `generated/bridge/java/com/wsnet/lib/` (Android) or `generated/bridge/objc/` (iOS)
110+
111+
Android-specific: Custom JNI with thread auto-attach and class loader caching.
112+
113+
iOS-specific: Builds as framework with Objective-C bridge headers.
114+
115+
### Threading Model
116+
117+
- Single worker thread runs Boost.ASIO `io_context`
118+
- All callbacks dispatched to this thread
119+
- Thread-safe from client perspective (can call from any thread)
120+
- Protected by mutexes where needed (e.g., `PersistentSettings`)
121+
122+
### Key Patterns
123+
124+
1. **Pimpl** - Public interfaces delegate to `*_impl` classes for ABI stability
125+
2. **Async callbacks** - All I/O returns cancelable callbacks with guaranteed invocation (unless canceled)
126+
3. **Request queueing** - ServerAPI queues requests during failover attempts
127+
4. **Persistent state** - Client must save/restore settings via `serverAPI()->currentSettings()` for optimal failover performance
128+
5. **State management** - `ConnectState` tracks device online/offline and VPN connection status
129+
130+
## Common Development Tasks
131+
132+
### Adding a new ServerAPI endpoint
133+
134+
1. Add method signature to `include/wsnet/WSNetServerAPI.h`
135+
2. Implement in `src/api/serverapi/serverapi_impl.h` and `.cpp`
136+
3. Create a `Request` subclass (e.g., `MyIPRequest`) that inherits from `BaseRequest`
137+
4. Override `getUrl()`, `getPlatformNamePostfix()`, and optionally `execute()`
138+
5. Use `RequestExecutorViaFailover` helper for automatic failover handling
139+
140+
### Running a single test
141+
142+
Tests are Google Test based:
143+
144+
```bash
145+
./build/test/wsnet_test --gtest_filter=TestSuiteName.TestName
146+
```
147+
148+
Test files are in `src/private/tests/` and named `*.test.cpp`.
149+
150+
### Code Coverage
151+
152+
Coverage is enabled automatically when building with tests on non-Windows platforms:
153+
154+
```bash
155+
# Build with coverage
156+
cmake -B build -S . -DIS_BUILD_TESTS=ON \
157+
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
158+
cmake --build build
159+
160+
# Run tests
161+
./build/test/wsnet_test
162+
163+
# Generate coverage report (requires lcov)
164+
lcov --capture --directory build --output-file coverage.info
165+
lcov --remove coverage.info '/usr/*' --output-file coverage.info # Remove system files
166+
genhtml coverage.info --output-directory coverage_report
167+
```
168+
169+
## Important Constraints
170+
171+
### ServerAPI State Management
172+
173+
Clients **must**:
174+
1. Call `serverAPI()->setConnectivityState(bool)` when device connectivity changes
175+
2. Call `serverAPI()->setIsConnectedToVpnState(bool)` when VPN state changes
176+
3. Save `serverAPI()->currentSettings()` to persistent storage before shutdown
177+
4. Restore settings via `WSNet::initialize(..., serverApiSettings)` on startup
178+
179+
This enables the library to remember the last working failover method for faster recovery.
180+
181+
### Request Behavior
182+
183+
- Requests can be called from any thread in any order
184+
- Callbacks are **always** invoked unless explicitly canceled
185+
- Callback timing is unpredictable (can be long during failover attempts)
186+
- Return codes:
187+
- `kSuccess = 0` - JSON data is valid and usable
188+
- `kNetworkError = 1`, `kNoNetworkConnection = 2` - Retry recommended
189+
- `kFailoverFailed = 3` - All bypass methods failed; recommend user enable "ignore SSL errors"
190+
191+
### Public Headers
192+
193+
When adding new public APIs:
194+
- Filename must start with `WSNet` prefix
195+
- Filename must match class name exactly (e.g., `WSNetFoo.h``class WSNetFoo`)
196+
- Must be in `include/wsnet/` directory
197+
- Must inherit from `scapix_object<ClassName>` for mobile compatibility
198+
199+
## File Locations
200+
201+
- **Public API**: `include/wsnet/WSNet*.h`
202+
- **Implementation**: `src/api/`, `src/httpnetworkmanager/`, `src/dnsresolver/`, etc.
203+
- **Failover logic**: `src/private/failover/` or `src/public/failover/`
204+
- **Tests**: `src/private/tests/*.test.cpp`
205+
- **Resources**: `resources/` (embedded via CMakeRC as `wsnet::rc`)
206+
- **Build scripts**: `tools/build_android.sh`, `tools/build_ios.sh`
207+
208+
## Dependencies (vcpkg)
209+
210+
Main dependencies managed via vcpkg:
211+
- `c-ares` - DNS resolution
212+
- `curl` - HTTP (with ECH patches from private vcpkg registry)
213+
- `openssl` - TLS (with ECH patches from private vcpkg registry)
214+
- `spdlog` - Logging
215+
- `rapidjson` - JSON parsing
216+
- `skyr-url` - URL parsing
217+
- `boost-filesystem` - File operations
218+
- `gtest` - Testing
219+
- `scapix` - Mobile bindings (Android/iOS only)
220+
- `cmakerc` - Resource embedding
221+
222+
Custom patches for curl/openssl are in the private vcpkg registry: `ws/client/client-libs/ws-vcpkg-registry.git`

0 commit comments

Comments
 (0)