7.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build & Test Commands
# Install dependencies
pod install
# Build SDK (Release configuration)
xcodebuild -workspace AlicloudHttpDNS.xcworkspace -scheme AlicloudHttpDNS -configuration Release build
# Run all unit tests
xcodebuild test -workspace AlicloudHttpDNS.xcworkspace -scheme AlicloudHttpDNSTests -destination 'platform=iOS Simulator,name=iPhone 15'
# Build distributable XCFramework
sh build_xc_framework.sh
Note: After creating new Xcode files, wait for the user to add them to the appropriate target before running builds or tests.
Architecture Overview
This is an iOS HTTPDNS SDK with a multi-layered architecture designed for secure, cached, and resilient DNS resolution over HTTP/HTTPS.
Core Architecture Layers
1. Public API Layer (HttpdnsService)
- Singleton facade providing three resolution modes:
resolveHostSync:- Blocking with timeoutresolveHostAsync:- Non-blocking with callbacksresolveHostSyncNonBlocking:- Returns cache immediately, refreshes async
- Manages multi-account instances (one per account ID)
- Configuration entry point for all SDK features
2. Request Management Layer (HttpdnsRequestManager)
- Orchestrates cache lookups before triggering network requests
- Manages two-tier caching:
- Memory cache (
HttpdnsHostObjectInMemoryCache) - Persistent SQLite cache (
HttpdnsDB)
- Memory cache (
- Handles TTL validation and expired IP reuse policy
- Coordinates retry logic and degradation to local DNS
3. Network Transport Layer (HttpdnsNWHTTPClient)
- Low-level HTTP/HTTPS transport using Apple's Network framework
- Singleton with persistent connection pooling (max 4 idle connections per host:port:scheme)
- Manages reusable connections (
HttpdnsNWReusableConnection) with automatic idle timeout (30s) - Thread-safe concurrent request handling via serial pool queue
- Custom HTTP header parser supporting chunked transfer encoding
- TLS certificate validation with configurable trust evaluation
- Exposed by
HttpdnsRemoteResolverfor DNS resolution requests
4. DNS Resolution Layer
HttpdnsRemoteResolver: HTTPS/HTTP requests to Alicloud servers- Builds authenticated requests with HMAC-SHA256 signatures
- Optional AES-CBC encryption for sensitive parameters
- Parses JSON responses into
HttpdnsHostObject(IPv4/IPv6) - Uses
HttpdnsNWHTTPClientfor actual HTTP transport
HttpdnsLocalResolver: Fallback to system DNS when remote fails
5. Scheduling & Service Discovery (HttpdnsScheduleCenter)
- Maintains regional service endpoint pools (CN, HK, SG, US, DE)
- Rotates between endpoints on failure for load balancing
- Separates IPv4 and IPv6 endpoint lists
- Per-account endpoint isolation
6. Data Flow (Synchronous Resolution)
User Request
→ Validate & wrap in HttpdnsRequest
→ Check memory cache (valid? return)
→ Load from SQLite DB (valid? return)
→ HttpdnsRemoteResolver
- Build URL with auth (HMAC-SHA256)
- Encrypt params if enabled (AES-CBC)
- Send to service endpoint
- Parse JSON response
- Decrypt if needed
→ Cache in memory + DB
→ Return HttpdnsResult
On Failure:
→ Retry with different endpoint (max 1 retry)
→ Return expired IP (if setReuseExpiredIPEnabled:YES)
→ Fall back to local DNS (if setDegradeToLocalDNSEnabled:YES)
→ Return nil
Authentication & Encryption
Request Signing:
- All sensitive params signed with HMAC-SHA256
- Signature includes: account ID, expiration timestamp, domain, query type
- Params sorted alphabetically before signing
- Expiration: current_time + 10 minutes
Request Encryption (Optional):
- Domain name, query type, and SDNS params encrypted with AES-CBC
- Encrypted blob included as
encparameter - Only encrypted when
aesSecretKeyprovided at init
Key Internal Components
HttpdnsHostObject: Internal model with separate IPv4/IPv6 arrays, TTLs, timestampsHttpdnsResult: Public-facing result model (simplified view)HttpdnsHostRecord: Serializable model for SQLite persistenceHttpdnsNWHTTPClient: Singleton HTTP transport layer with connection poolingHttpdnsNWReusableConnection: Wrapper for Network framework connections with idle timeout trackingHttpdnsIpStackDetector: Detects network stack type (IPv4/IPv6 capability)HttpdnsReachability: Monitors network changes, triggers pre-resolutionHttpdnsUtil: Crypto utilities (HMAC, AES), IP validation, encoding
Concurrency Model
- Concurrent queues for async user requests and DNS resolution
- Serial pool queue in
HttpdnsNWHTTPClientfor connection pool management dispatch_semaphore_tfor blocking synchronous callsHttpDnsLockerprevents duplicate concurrent resolution of same domain- Network framework handles underlying I/O asynchronously
Coding Conventions
Style:
- 4-space indentation, no trailing whitespace
- Braces on same line as control statements; body starts on next line
- Always use braces for control statement bodies, even single statements
- Comments in Chinese, only for complex logic explaining WHY
Naming:
- Types/files:
UpperCamelCase(e.g.,AlicloudHttpDNSClient.h) - Methods/variables:
lowerCamelCase - Constants:
kAC...prefix - Internal headers:
+Internal.hsuffix
Commit Messages:
- Use conventional prefixes:
feat:,fix:,docs:,refactor:,chore:,config: - Write in Chinese
- After
git add, run:/Users/xuyecan/.macconfig/script/strip-trailing-ws-in-diff --staged
Testing Notes
- Test target:
AlicloudHttpDNSTests - OCMock-based tests may have memory issues when run in batch - run individually if needed
- Non-mock tests use predefined credentials:
- Account ID:
1000000 - Test domains:
*.onlyforhttpdnstest.run.place(renewed annually)
- Account ID:
- Never commit real production Account IDs or Secret Keys
- Test file naming mirrors class under test (e.g.,
AlicloudHttpDNSClientTests.m) - Network layer integration tests organized into 5 focused modules:
HttpdnsNWHTTPClient_BasicIntegrationTests.m: Basic HTTP/HTTPS requestsHttpdnsNWHTTPClient_ConcurrencyTests.m: Thread safety and concurrent accessHttpdnsNWHTTPClient_PoolManagementTests.m: Connection pooling and reuseHttpdnsNWHTTPClient_EdgeCasesAndTimeoutTests.m: Timeout and error handlingHttpdnsNWHTTPClient_StateMachineTests.m: Connection lifecycle state transitions
SDK-Specific Notes
Multi-Account Support:
- Each account ID gets isolated singleton instance
- Separate endpoint pools, caches, and configurations per account
Public vs Internal Headers:
- Public headers listed in
AlicloudHTTPDNS.podspecunderpublic_header_files - Internal headers use
+Internal.hsuffix and are not exposed - Umbrella header:
AlicloudHttpDNS.himports all public APIs
Required System Frameworks:
CoreTelephony,SystemConfiguration,Network(for HTTP transport)- Libraries:
sqlite3.0,resolv,z - Linker flags:
-ObjC -lz - Minimum deployment target: iOS 12.0+ (required for Network framework)
Pre-Resolution Strategy:
- Call
setPreResolveHosts:byIPType:at app startup for hot domains - Automatically re-triggered on network changes (WiFi ↔ cellular)
- Batch requests combine multiple hosts in single HTTP call
Persistence & Cache:
- SQLite DB per account in isolated directory
- Enable with
setPersistentCacheIPEnabled:YES - Automatic expiration cleanup
- Speeds up cold starts with pre-cached DNS results