Skip to content

Commit 962a619

Browse files
committed
perf: parallel DNS resolution for faster route setup
- DNS lookups now run in parallel instead of sequentially - Fixes 'Setting Up' getting stuck when many services enabled - Route count now displays reliably in menu bar after VPN connects
1 parent 4e48c19 commit 962a619

5 files changed

Lines changed: 46 additions & 13 deletions

File tree

Casks/vpn-bypass.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Or if using local tap: brew install --cask --no-quarantine ./Casks/vpn-bypass.rb
44

55
cask "vpn-bypass" do
6-
version "1.3.1"
6+
version "1.3.2"
77
sha256 "37b127a55aec0bdb80e824e59e840ce5b529c09086aac7fc24dc4616abb817bd"
88

99
url "https://github.com/GeiserX/VPNBypass/releases/download/v#{version}/VPNBypass-#{version}.dmg"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<p align="center">
1212
<img src="https://img.shields.io/badge/macOS-13%2B-blue" alt="macOS 13+">
1313
<img src="https://img.shields.io/badge/Swift-5.9-orange" alt="Swift 5.9">
14-
<a href="https://github.com/GeiserX/vpn-macos-bypass/releases"><img src="https://img.shields.io/badge/version-1.3.1-green" alt="Version"></a>
14+
<a href="https://github.com/GeiserX/vpn-macos-bypass/releases"><img src="https://img.shields.io/badge/version-1.3.2-green" alt="Version"></a>
1515
</p>
1616

1717
## Why?

Sources/RouteManager.swift

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -777,23 +777,49 @@ final class RouteManager: ObservableObject {
777777
var newRoutes: [ActiveRoute] = []
778778
var failedCount = 0
779779

780-
// Apply domain routes
780+
// Collect all domains to resolve (for parallel resolution)
781+
var allDomains: [(domain: String, source: String)] = []
782+
783+
// Add custom domains
781784
for domain in config.domains where domain.enabled {
782-
if let routes = await applyRoutesForDomain(domain.domain, gateway: gateway) {
785+
allDomains.append((domain.domain, domain.domain))
786+
}
787+
788+
// Add service domains
789+
for service in config.services where service.enabled {
790+
for domain in service.domains {
791+
allDomains.append((domain, service.name))
792+
}
793+
}
794+
795+
// Resolve domains in parallel (much faster than sequential)
796+
log(.info, "Resolving \(allDomains.count) domains...")
797+
798+
let routeResults = await withTaskGroup(of: [ActiveRoute]?.self, returning: [[ActiveRoute]?].self) { group in
799+
for item in allDomains {
800+
group.addTask {
801+
await self.applyRoutesForDomain(item.domain, gateway: gateway, source: item.source)
802+
}
803+
}
804+
805+
var results: [[ActiveRoute]?] = []
806+
for await result in group {
807+
results.append(result)
808+
}
809+
return results
810+
}
811+
812+
// Collect results
813+
for result in routeResults {
814+
if let routes = result {
783815
newRoutes.append(contentsOf: routes)
784816
} else {
785817
failedCount += 1
786818
}
787819
}
788820

789-
// Apply service routes
821+
// Apply IP ranges (these don't need DNS resolution)
790822
for service in config.services where service.enabled {
791-
for domain in service.domains {
792-
if let routes = await applyRoutesForDomain(domain, gateway: gateway, source: service.name) {
793-
newRoutes.append(contentsOf: routes)
794-
}
795-
}
796-
// Apply IP ranges
797823
for range in service.ipRanges {
798824
if await applyRouteForRange(range, gateway: gateway) {
799825
newRoutes.append(ActiveRoute(

Sources/SettingsView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ struct GeneralTab: View {
10141014
HStack {
10151015
VStack(alignment: .leading, spacing: 2) {
10161016
BrandedAppName(fontSize: 13)
1017-
Text("Version 1.3.1")
1017+
Text("Version 1.3.2")
10181018
.font(.system(size: 11))
10191019
.foregroundColor(Color(hex: "6B7280"))
10201020
}
@@ -1472,7 +1472,7 @@ struct InfoTab: View {
14721472
// App name with branded colors
14731473
BrandedAppName(fontSize: 24)
14741474

1475-
Text("v1.3.1")
1475+
Text("v1.3.2")
14761476
.font(.system(size: 12, design: .monospaced))
14771477
.foregroundColor(Color(hex: "6B7280"))
14781478

docs/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to VPN Bypass will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.3.2] - 2026-01-19
9+
10+
### Fixed
11+
- **Parallel DNS Resolution** - Route setup now resolves domains in parallel (much faster)
12+
- **No More "Setting Up" Stuck** - VPN connection no longer hangs on route application
13+
- **Route Count Display** - Menu bar now shows route count reliably after VPN connects
14+
815
## [1.3.1] - 2026-01-18
916

1017
### Fixed

0 commit comments

Comments
 (0)