Remove unnecessary DNS queries in case of SOCKS5 outbound

This commit is contained in:
yinyue200 2023-02-12 21:19:28 +08:00
parent a48d6ddb7c
commit 23f1546591
2 changed files with 38 additions and 8 deletions

View file

@ -140,10 +140,13 @@ func (c *serverClient) handleMessage(msg []byte) {
var err error
if c.ACLEngine != nil {
action, arg, isDomain, ipAddr, err = c.ACLEngine.ResolveAndMatch(dfMsg.Host, dfMsg.Port, true)
} else if c.Transport.ProxyEnabled() { // Case for SOCKS5 outbound
ipAddr, isDomain = c.Transport.ParseIPAddr(dfMsg.Host) // It is safe to leave ipAddr as nil since addrExToSOCKS5Addr will ignore it when there is a domain
err = nil
} else {
ipAddr, isDomain, err = c.Transport.ResolveIPAddr(dfMsg.Host)
}
if err != nil && !(isDomain && c.Transport.ProxyEnabled()) { // Special case for domain requests + SOCKS5 outbound
if err != nil {
return
}
switch action {
@ -162,8 +165,16 @@ func (c *serverClient) handleMessage(msg []byte) {
case acl.ActionBlock:
// Do nothing
case acl.ActionHijack:
hijackIPAddr, isDomain, err := c.Transport.ResolveIPAddr(arg)
if err == nil || (isDomain && c.Transport.ProxyEnabled()) { // Special case for domain requests + SOCKS5 outbound
var isDomain bool
var hijackIPAddr *net.IPAddr
var err error
if c.Transport.ProxyEnabled() { // Case for domain requests + SOCKS5 outbound
hijackIPAddr, isDomain = c.Transport.ParseIPAddr(arg) // It is safe to leave ipAddr as nil since addrExToSOCKS5Addr will ignore it when there is a domain
err = nil
} else {
hijackIPAddr, isDomain, err = c.Transport.ResolveIPAddr(arg)
}
if err == nil {
addrEx := &transport.AddrEx{
IPAddr: hijackIPAddr,
Port: int(dfMsg.Port),
@ -190,10 +201,13 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) {
var err error
if c.ACLEngine != nil {
action, arg, isDomain, ipAddr, err = c.ACLEngine.ResolveAndMatch(host, port, false)
} else if c.Transport.ProxyEnabled() { // Case for domain requests + SOCKS5 outbound
ipAddr, isDomain = c.Transport.ParseIPAddr(host) // It is safe to leave ipAddr as nil since addrExToSOCKS5Addr will ignore it when there is a domain
err = nil
} else {
ipAddr, isDomain, err = c.Transport.ResolveIPAddr(host)
}
if err != nil && !(isDomain && c.Transport.ProxyEnabled()) { // Special case for domain requests + SOCKS5 outbound
if err != nil {
_ = struc.Pack(stream, &serverResponse{
OK: false,
Message: "host resolution failure",
@ -229,8 +243,16 @@ func (c *serverClient) handleTCP(stream quic.Stream, host string, port uint16) {
})
return
case acl.ActionHijack:
hijackIPAddr, isDomain, err := c.Transport.ResolveIPAddr(arg)
if err != nil && !(isDomain && c.Transport.ProxyEnabled()) { // Special case for domain requests + SOCKS5 outbound
var isDomain bool
var hijackIPAddr *net.IPAddr
var err error
if c.Transport.ProxyEnabled() { // Case for domain requests + SOCKS5 outbound
hijackIPAddr, isDomain = c.Transport.ParseIPAddr(arg) // It is safe to leave ipAddr as nil since addrExToSOCKS5Addr will ignore it when there is a domain
err = nil
} else {
hijackIPAddr, isDomain, err = c.Transport.ResolveIPAddr(arg)
}
if err != nil {
_ = struc.Pack(stream, &serverResponse{
OK: false,
Message: err.Error(),

View file

@ -69,10 +69,18 @@ var DefaultServerTransport = &ServerTransport{
ResolvePreference: ResolvePreferenceDefault,
}
func (st *ServerTransport) ResolveIPAddr(address string) (*net.IPAddr, bool, error) {
func (st *ServerTransport) ParseIPAddr(address string) (*net.IPAddr, bool) {
ip, zone := utils.ParseIPZone(address)
if ip != nil {
return &net.IPAddr{IP: ip, Zone: zone}, false, nil
return &net.IPAddr{IP: ip, Zone: zone}, false
}
return nil, true
}
func (st *ServerTransport) ResolveIPAddr(address string) (*net.IPAddr, bool, error) {
ip, isDomain := st.ParseIPAddr(address)
if !isDomain {
return ip, false, nil
}
ipAddr, err := resolveIPAddrWithPreference(address, st.ResolvePreference)
return ipAddr, true, err