@@ -36,7 +36,7 @@ func runRandomSubnetProxy(listenAddr string, parsedNetwork netip.Prefix, cidrSiz
3636
3737 conf := & socks5.Config {
3838 Logger : l ,
39- Resolver : resolver ,
39+ Resolver : NewDNSResolver ( getCIDRNetwork ( parsedNetwork )) ,
4040 Dial : ipItr .Dial ,
4141 BindIP : net .ParseIP (host ),
4242 BindPort : port ,
@@ -69,19 +69,46 @@ func runRandomSubnetProxy(listenAddr string, parsedNetwork netip.Prefix, cidrSiz
6969// It ensures that domain names are resolved to the same IP family (IPv4 or IPv6)
7070// as the proxy's egress IP.
7171type DNSResolver struct {
72- network string
72+ network string
73+ resolver net.Resolver
74+ }
75+
76+ func NewDNSResolver (network string ) * DNSResolver {
77+ d := & DNSResolver {
78+ network : network ,
79+ }
80+ return d
7381}
7482
7583// Resolve resolves a domain name to an IP address using the system DNS resolver.
7684// It ensures the resolved IP is in the same address family (IPv4 or IPv6) as specified
7785// by the network field, which helps maintain consistency with the proxy's egress IP.
78- // TODO use context for name resolution
79- func (d DNSResolver ) Resolve (ctx context.Context , name string ) (context.Context , net.IP , error ) {
80- //v("resolving %q: %q", d.network, name)
81- addr , err := net .ResolveIPAddr (d .network , name )
86+ func (d * DNSResolver ) Resolve (ctx context.Context , name string ) (context.Context , net.IP , error ) {
87+ addrs , err := d .resolver .LookupIPAddr (ctx , name )
8288 if err != nil {
8389 return ctx , nil , err
8490 }
85- v ("resolved %q to %q" , name , addr .IP .String ())
86- return ctx , addr .IP , err
91+
92+ // Filter addresses by the desired IP family
93+ for _ , addr := range addrs {
94+ if d .network == "ip4" && addr .IP .To4 () != nil {
95+ v ("resolved %q to %q" , name , addr .IP .String ())
96+ return ctx , addr .IP , nil
97+ }
98+ if d .network == "ip6" && addr .IP .To4 () == nil && addr .IP .To16 () != nil {
99+ v ("resolved %q to %q" , name , addr .IP .String ())
100+ return ctx , addr .IP , nil
101+ }
102+ }
103+
104+ return ctx , nil , & net.AddrError {Err : "no suitable address found" , Addr : name }
105+ }
106+
107+ // getCIDRNetwork returns "ip4" for IPv4 addresses or "ip6" for IPv6 addresses.
108+ // This is used for DNS resolution context.
109+ func getCIDRNetwork (prefix netip.Prefix ) string {
110+ if prefix .Addr ().Is4 () {
111+ return "ip4"
112+ }
113+ return "ip6"
87114}
0 commit comments