@@ -8,10 +8,6 @@ import (
88 "encoding/binary"
99 "encoding/json"
1010 "errors"
11- "golang.org/x/net/icmp"
12- "golang.org/x/net/ipv4"
13- "golang.org/x/net/ipv6"
14- "golang.zx2c4.com/wireguard/device"
1511 "io"
1612 "log"
1713 "math/rand"
@@ -24,6 +20,11 @@ import (
2420 "sync"
2521 "time"
2622
23+ "golang.org/x/net/icmp"
24+ "golang.org/x/net/ipv4"
25+ "golang.org/x/net/ipv6"
26+ "golang.zx2c4.com/wireguard/device"
27+
2728 "github.com/things-go/go-socks5"
2829 "github.com/things-go/go-socks5/bufferpool"
2930
@@ -43,10 +44,11 @@ type CredentialValidator struct {
4344
4445// VirtualTun stores a reference to netstack network and DNS configuration
4546type VirtualTun struct {
46- Tnet * netstack.Net
47- Dev * device.Device
48- SystemDNS bool
49- Conf * DeviceConfig
47+ Tnet * netstack.Net
48+ Dev * device.Device
49+ SystemDNS bool
50+ Conf * DeviceConfig
51+ ResolveConfig * ResolveConfig
5052 // PingRecord stores the last time an IP was pinged
5153 PingRecord map [string ]uint64
5254 PingRecordLock * sync.Mutex
@@ -79,33 +81,48 @@ func (d VirtualTun) ResolveAddrWithContext(ctx context.Context, name string) (*n
7981 return nil , err
8082 }
8183
82- size := len (addrs )
83- if size == 0 {
84- return nil , errors .New ("no address found for: " + name )
85- }
86-
87- rand .Shuffle (size , func (i , j int ) {
88- addrs [i ], addrs [j ] = addrs [j ], addrs [i ]
89- })
84+ addrs_v4 := []netip.Addr {}
85+ addrs_v6 := []netip.Addr {}
9086
91- var addr netip.Addr
9287 for _ , saddr := range addrs {
93- addr , err = netip .ParseAddr (saddr )
88+ addr , err : = netip .ParseAddr (saddr )
9489 if err == nil {
95- break
90+ if addr .Is4 () {
91+ addrs_v4 = append (addrs_v4 , addr )
92+ } else if addr .Is6 () {
93+ addrs_v6 = append (addrs_v6 , addr )
94+ }
9695 }
9796 }
9897
99- if err != nil {
100- return nil , err
98+ rand .Shuffle (len (addrs_v4 ), func (i , j int ) {
99+ addrs_v4 [i ], addrs_v4 [j ] = addrs_v4 [j ], addrs_v4 [i ]
100+ })
101+ rand .Shuffle (len (addrs_v6 ), func (i , j int ) {
102+ addrs_v6 [i ], addrs_v6 [j ] = addrs_v6 [j ], addrs_v6 [i ]
103+ })
104+
105+ addrs_all := []netip.Addr {}
106+
107+ switch d .ResolveConfig .ResolveStrategy {
108+ case "ipv4" :
109+ addrs_all = append (addrs_v4 , addrs_v6 ... )
110+ case "ipv6" :
111+ addrs_all = append (addrs_v6 , addrs_v4 ... )
112+ }
113+
114+ if len (addrs_all ) == 0 {
115+ return nil , errors .New ("no address found for: " + name )
101116 }
102117
103- return & addr , nil
118+ return & addrs_all [ 0 ] , nil
104119}
105120
106121// Resolve resolves a hostname and returns an IP.
107122// DNS traffic may or may not be routed depending on VirtualTun's setting
108123func (d VirtualTun ) Resolve (ctx context.Context , name string ) (context.Context , net.IP , error ) {
124+ log .Printf ("Resolving address for %s\n " , name )
125+
109126 addr , err := d .ResolveAddrWithContext (ctx , name )
110127 if err != nil {
111128 return nil , nil , err
0 commit comments