Hook to replace DOHL dialer

This commit is contained in:
世界 2021-09-01 09:37:40 +08:00
parent 16d96aa54d
commit e316cd4c66
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
3 changed files with 41 additions and 2 deletions

View file

@ -114,7 +114,7 @@ func NewDoHLocalNameServer(url *url.URL) *DoHNameServer {
if err != nil { if err != nil {
return nil, err return nil, err
} }
conn, err := internet.DialSystem(ctx, dest, nil) conn, err := internet.DialSystemDNS(ctx, dest, nil)
log.Record(&log.AccessMessage{ log.Record(&log.AccessMessage{
From: "DoH", From: "DoH",
To: s.dohURL, To: s.dohURL,

View file

@ -161,6 +161,35 @@ func DialSystem(ctx context.Context, dest net.Destination, sockopt *SocketConfig
return effectiveSystemDialer.Dial(ctx, src, dest, sockopt) return effectiveSystemDialer.Dial(ctx, src, dest, sockopt)
} }
func DialSystemDNS(ctx context.Context, dest net.Destination, sockopt *SocketConfig) (net.Conn, error) {
var src net.Address
if outbound := session.OutboundFromContext(ctx); outbound != nil {
src = outbound.Gateway
}
if sockopt == nil {
return effectiveSystemDNSDialer.Dial(ctx, src, dest, sockopt)
}
if canLookupIP(ctx, dest, sockopt) {
ips, err := lookupIP(dest.Address.String(), sockopt.DomainStrategy, src)
if err == nil && len(ips) > 0 {
dest.Address = net.IPAddress(ips[dice.Roll(len(ips))])
newError("replace destination with " + dest.String()).AtInfo().WriteToLog()
} else if err != nil {
newError("failed to resolve ip").Base(err).AtWarning().WriteToLog()
}
}
if obm != nil && len(sockopt.DialerProxy) > 0 {
nc := redirect(ctx, dest, sockopt.DialerProxy)
if nc != nil {
return nc, nil
}
}
return effectiveSystemDNSDialer.Dial(ctx, src, dest, sockopt)
}
func InitSystemDialer(dc dns.Client, om outbound.Manager) { func InitSystemDialer(dc dns.Client, om outbound.Manager) {
dnsClient = dc dnsClient = dc
obm = om obm = om

View file

@ -11,7 +11,10 @@ import (
"github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/outbound"
) )
var effectiveSystemDialer SystemDialer = &DefaultSystemDialer{} var (
effectiveSystemDialer SystemDialer = &DefaultSystemDialer{}
effectiveSystemDNSDialer SystemDialer = &DefaultSystemDialer{}
)
type SystemDialer interface { type SystemDialer interface {
Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *SocketConfig) (net.Conn, error) Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *SocketConfig) (net.Conn, error)
@ -176,6 +179,13 @@ func UseAlternativeSystemDialer(dialer SystemDialer) {
effectiveSystemDialer = dialer effectiveSystemDialer = dialer
} }
func UseAlternativeSystemDNSDialer(dialer SystemDialer) {
if dialer == nil {
effectiveSystemDNSDialer = &DefaultSystemDialer{}
}
effectiveSystemDNSDialer = dialer
}
// RegisterDialerController adds a controller to the effective system dialer. // RegisterDialerController adds a controller to the effective system dialer.
// The controller can be used to operate on file descriptors before they are put into use. // The controller can be used to operate on file descriptors before they are put into use.
// It only works when effective dialer is the default dialer. // It only works when effective dialer is the default dialer.