Skip to content

Commit e07a20d

Browse files
committed
fix(tun): make FakeDNS UDP listener persistent and fix SOCKS tracking half-close and IPv6 route capture
1 parent 1280cb3 commit e07a20d

6 files changed

Lines changed: 253 additions & 173 deletions

File tree

android/app/src/main/java/com/masterdns/vpn/service/MasterDnsVpnService.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,17 @@ class MasterDnsVpnService : VpnService() {
396396
VpnManager.appendLog("Added fake DNS route: 198.18.0.0/16")
397397
}
398398

399+
// Route IPv6 into VPN so apps don't leak or hang on IPv6 DNS / connections
400+
runCatching {
401+
builder.addAddress("fd00::1", 128)
402+
builder.addRoute("::", 0)
403+
if (inputs.globalSettings.fakeDnsEnabled) {
404+
builder.addDnsServer("fd00::2")
405+
}
406+
}.onFailure { e ->
407+
VpnManager.appendLog("IPv6 VPN route setup: ${e.message}")
408+
}
409+
399410
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
400411
val splitEnabled = inputs.globalSettings.splitTunnelingEnabled &&
401412
inputs.globalSettings.splitPackagesCsv.isNotBlank()

mobile/mobile.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,26 @@ func handleTracking(c net.Conn, realProxyAddr string) {
113113
onWrite: func(n int64) { atomic.AddInt64(&trackedDown, n) },
114114
}
115115

116-
errc := make(chan error, 2)
116+
var wg sync.WaitGroup
117+
wg.Add(2)
118+
117119
go func() {
118-
_, err := io.Copy(server, tcClient)
119-
errc <- err
120+
defer wg.Done()
121+
_, _ = io.Copy(server, tcClient)
122+
if tc, ok := server.(interface{ CloseWrite() error }); ok {
123+
_ = tc.CloseWrite()
124+
}
120125
}()
126+
121127
go func() {
122-
_, err := io.Copy(tcClient, server)
123-
errc <- err
128+
defer wg.Done()
129+
_, _ = io.Copy(tcClient, server)
130+
if tc, ok := tcClient.Conn.(interface{ CloseWrite() error }); ok {
131+
_ = tc.CloseWrite()
132+
}
124133
}()
125-
<-errc
134+
135+
wg.Wait()
126136
}
127137

128138
// Bandwidth holds upload and download counters for gomobile bindings.

mobile/tun/dns_mapper.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tun
33
import (
44
"fmt"
55
"log"
6+
"strings"
67
"sync"
78
"sync/atomic"
89
)
@@ -26,7 +27,9 @@ func (d *DNSMapper) GetFakeIP(hostname string) string {
2627
d.mu.Lock()
2728
defer d.mu.Unlock()
2829

29-
if ip, ok := d.hostnameToIP[hostname]; ok {
30+
normalized := strings.ToLower(strings.TrimSuffix(hostname, "."))
31+
32+
if ip, ok := d.hostnameToIP[normalized]; ok {
3033
return ip
3134
}
3235

@@ -40,10 +43,10 @@ func (d *DNSMapper) GetFakeIP(hostname string) string {
4043
octet4 := byte(counter & 0xFF)
4144
fakeIP := fmt.Sprintf("198.18.%d.%d", octet3, octet4)
4245

43-
d.hostnameToIP[hostname] = fakeIP
44-
d.ipToHostname[fakeIP] = hostname
46+
d.hostnameToIP[normalized] = fakeIP
47+
d.ipToHostname[fakeIP] = normalized
4548

46-
log.Printf("[TUN-DNS] Mapped %s -> %s", hostname, fakeIP)
49+
log.Printf("[TUN-DNS] Mapped %s -> %s", normalized, fakeIP)
4750
return fakeIP
4851
}
4952

mobile/tun/dns_mapper_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ func TestDNSMapper_GetFakeIP_StableForSameHostname(t *testing.T) {
2929
}
3030
}
3131

32+
func TestDNSMapper_GetFakeIP_CaseInsensitiveAndDotNormalization(t *testing.T) {
33+
d := NewDNSMapper()
34+
35+
first := d.GetFakeIP("WwW.GoOgLe.CoM")
36+
second := d.GetFakeIP("www.google.com.")
37+
third := d.GetFakeIP("WWW.GOOGLE.COM")
38+
if first != second || second != third {
39+
t.Fatalf("case-randomized hostnames mapped differently: %q vs %q vs %q", first, second, third)
40+
}
41+
42+
host, ok := d.GetHostname(first)
43+
if !ok || host != "www.google.com" {
44+
t.Fatalf("GetHostname(%q) = %q (ok=%v), want www.google.com", first, host, ok)
45+
}
46+
}
47+
3248
func TestDNSMapper_GetHostname_RoundTrips(t *testing.T) {
3349
d := NewDNSMapper()
3450

0 commit comments

Comments
 (0)