From b1d38db30af3188ac84fcfb6f49b0a104d6789f9 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sat, 18 Feb 2023 02:50:20 +0800 Subject: [PATCH] Support using custom resolver when dialing domain address --- common/session/session.go | 2 ++ transport/internet/dialer.go | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/common/session/session.go b/common/session/session.go index 25ce204c1..0c4f1fd93 100644 --- a/common/session/session.go +++ b/common/session/session.go @@ -51,6 +51,8 @@ type Outbound struct { Target net.Destination // Gateway address Gateway net.Address + // Domain resolver to use when dialing + Resolver func(ctx context.Context, domain string) net.Address } // SniffingRequest controls the behavior of content sniffing. diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 0f978fbf9..7a9b8981b 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -68,8 +68,10 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *MemoryStrea // DialSystem calls system dialer to create a network connection. func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) { + outbound := session.OutboundFromContext(ctx) + var src net.Address - if outbound := session.OutboundFromContext(ctx); outbound != nil { + if outbound != nil { src = outbound.Gateway } @@ -77,6 +79,22 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig return DialTaggedOutbound(ctx, dest, transportLayerOutgoingTag) } + originalAddr := dest.Address + if outbound != nil && outbound.Resolver != nil && dest.Address.Family().IsDomain() { + if addr := outbound.Resolver(ctx, dest.Address.Domain()); addr != nil { + dest.Address = addr + } + } + + switch { + case src != nil && dest.Address != originalAddr: + newError("dialing to ", dest, " resolved from ", originalAddr, " via ", src).WriteToLog(session.ExportIDToError(ctx)) + case src != nil: + newError("dialing to ", dest, " via ", src).WriteToLog(session.ExportIDToError(ctx)) + case dest.Address != originalAddr: + newError("dialing to ", dest, " resolved from ", originalAddr).WriteToLog(session.ExportIDToError(ctx)) + } + return effectiveSystemDialer.Dial(ctx, src, dest, sockopt) }