11package service
22
33import (
4+ "context"
45 "errors"
56 "fmt"
7+ "net"
68
79 "github.com/database64128/shadowsocks-go/conn"
810 "github.com/database64128/shadowsocks-go/direct"
@@ -57,6 +59,10 @@ type ClientConfig struct {
5759 // Do not use if Endpoint is specified.
5860 UDPAddress conn.Addr `json:"udpAddress,omitzero"`
5961
62+ // OverrideResolverDialAddress optionally specifies an alternate DNS server address
63+ // to override the dial address of the dialer's DNS resolver.
64+ OverrideResolverDialAddress string `json:"overrideResolverDialAddress,omitzero"`
65+
6066 // DialerFwmark sets the dialer's fwmark on Linux, or user cookie on FreeBSD.
6167 //
6268 // Available on Linux and FreeBSD.
@@ -244,8 +250,8 @@ func (cc *ClientConfig) Initialize(tlsCertStore *tlscerts.Store, listenConfigCac
244250
245251 if cc .EnableTCP || cc .EnableUDP && cc .Protocol == "socks5" {
246252 cc .networkTCP = cc .tcpNetwork ()
247- cc .connDialer = cc . dialer ()
248- cc .innerClient = cc . newInnerClient ()
253+ cc .initConnDialer ()
254+ cc .initInnerClient ()
249255 }
250256
251257 return nil
@@ -264,23 +270,32 @@ func (cc *ClientConfig) tcpNetwork() string {
264270 }
265271}
266272
267- func (cc * ClientConfig ) dialer () conn. Dialer {
268- return cc .dialerCache .Get (conn.DialerSocketOptions {
273+ func (cc * ClientConfig ) initConnDialer () {
274+ cc . connDialer = cc .dialerCache .Get (conn.DialerSocketOptions {
269275 Fwmark : cc .DialerFwmark ,
270276 TrafficClass : cc .DialerTrafficClass ,
271277 TCPFastOpen : cc .DialerTFO ,
272278 TCPFastOpenFallback : cc .TCPFastOpenFallback ,
273279 MultipathTCP : cc .MultipathTCP ,
274280 })
281+ if cc .OverrideResolverDialAddress != "" {
282+ cc .connDialer .SetResolver (& net.Resolver {
283+ PreferGo : true ,
284+ Dial : func (ctx context.Context , network , address string ) (net.Conn , error ) {
285+ c , _ , err := cc .connDialer .Dial (ctx , network , cc .OverrideResolverDialAddress , nil )
286+ return c , err
287+ },
288+ })
289+ }
275290}
276291
277- func (cc * ClientConfig ) newInnerClient () * netio. TCPClient {
292+ func (cc * ClientConfig ) initInnerClient () {
278293 tcc := netio.TCPClientConfig {
279294 Name : cc .Name ,
280295 Network : cc .networkTCP ,
281296 Dialer : cc .connDialer ,
282297 }
283- return tcc .NewTCPClient ()
298+ cc . innerClient = tcc .NewTCPClient ()
284299}
285300
286301// TCPClient returns a new [netio.StreamClient] from the configuration.
0 commit comments