Jelajahi Sumber

Fix log for rejected connections

世界 4 bulan lalu
induk
melakukan
cba0e46aba
6 mengubah file dengan 48 tambahan dan 31 penghapusan
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 2 3
      route/dns.go
  4. 20 20
      route/route.go
  5. 2 2
      route/route_dns.go
  6. 21 3
      route/rule/rule_action.go

+ 1 - 1
go.mod

@@ -33,7 +33,7 @@ require (
 	github.com/sagernet/sing-shadowsocks v0.2.8
 	github.com/sagernet/sing-shadowsocks2 v0.2.1
 	github.com/sagernet/sing-shadowtls v0.2.0
-	github.com/sagernet/sing-tun v0.6.8
+	github.com/sagernet/sing-tun v0.6.9
 	github.com/sagernet/sing-vmess v0.2.3
 	github.com/sagernet/smux v1.5.34-mod.2
 	github.com/sagernet/utls v1.6.7

+ 2 - 2
go.sum

@@ -133,8 +133,8 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
 github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
 github.com/sagernet/sing-shadowtls v0.2.0 h1:cLKe4OAOFwuhmAIuPLj//CIL7Q9js+pIDardhJ+/osk=
 github.com/sagernet/sing-shadowtls v0.2.0/go.mod h1:agU+Fw5X+xnWVyRHyFthoZCX3MfWKCFPm4JUf+1oaxo=
-github.com/sagernet/sing-tun v0.6.8 h1:tr+LKHe09C2I9GfNuB2vnzaZm+ekoNlAhLLrdiLjtAA=
-github.com/sagernet/sing-tun v0.6.8/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
+github.com/sagernet/sing-tun v0.6.9 h1:uP8O4Q7U9QesjWumgxd2S9fjT3c6aEPWl5RB6uBdVB8=
+github.com/sagernet/sing-tun v0.6.9/go.mod h1:fisFCbC4Vfb6HqQNcwPJi2CDK2bf0Xapyz3j3t4cnHE=
 github.com/sagernet/sing-vmess v0.2.3 h1:z6Ym8dnZG7k1fP3+54vz8G0tvRVJeOoTFFeUPwXTD44=
 github.com/sagernet/sing-vmess v0.2.3/go.mod h1:jDAZ0A0St1zVRkyvhAPRySOFfhC+4SQtO5VYyeFotgA=
 github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=

+ 2 - 3
route/dns.go

@@ -2,15 +2,14 @@ package route
 
 import (
 	"context"
-	"errors"
 	"net"
 	"time"
 
 	"github.com/sagernet/sing-box/adapter"
 	C "github.com/sagernet/sing-box/constant"
 	dnsOutbound "github.com/sagernet/sing-box/protocol/dns"
+	R "github.com/sagernet/sing-box/route/rule"
 	"github.com/sagernet/sing-dns"
-	"github.com/sagernet/sing-tun"
 	"github.com/sagernet/sing/common/buf"
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
@@ -58,7 +57,7 @@ func (r *Router) hijackDNSPacket(ctx context.Context, conn N.PacketConn, packetB
 
 func ExchangeDNSPacket(ctx context.Context, router *Router, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) {
 	err := exchangeDNSPacket(ctx, router, conn, buffer, metadata, destination)
-	if err != nil && !errors.Is(err, tun.ErrDrop) && !E.IsClosedOrCanceled(err) {
+	if err != nil && !R.IsRejected(err) && !E.IsClosedOrCanceled(err) {
 		router.dnsLogger.ErrorContext(ctx, E.Cause(err, "process packet connection"))
 	}
 }

+ 20 - 20
route/route.go

@@ -16,7 +16,7 @@ import (
 	"github.com/sagernet/sing-box/common/sniff"
 	C "github.com/sagernet/sing-box/constant"
 	"github.com/sagernet/sing-box/option"
-	"github.com/sagernet/sing-box/route/rule"
+	R "github.com/sagernet/sing-box/route/rule"
 	"github.com/sagernet/sing-dns"
 	"github.com/sagernet/sing-mux"
 	"github.com/sagernet/sing-vmess"
@@ -51,7 +51,7 @@ func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata
 	err := r.routeConnection(ctx, conn, metadata, onClose)
 	if err != nil {
 		N.CloseOnHandshakeFailure(conn, onClose, err)
-		if E.IsClosedOrCanceled(err) {
+		if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
 			r.logger.DebugContext(ctx, "connection closed: ", err)
 		} else {
 			r.logger.ErrorContext(ctx, err)
@@ -101,7 +101,7 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
 	var selectedOutbound adapter.Outbound
 	if selectedRule != nil {
 		switch action := selectedRule.Action().(type) {
-		case *rule.RuleActionRoute:
+		case *R.RuleActionRoute:
 			var loaded bool
 			selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
 			if !loaded {
@@ -112,11 +112,11 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
 				buf.ReleaseMulti(buffers)
 				return E.New("TCP is not supported by outbound: ", selectedOutbound.Tag())
 			}
-		case *rule.RuleActionReject:
+		case *R.RuleActionReject:
 			buf.ReleaseMulti(buffers)
 			N.CloseOnHandshakeFailure(conn, onClose, action.Error(ctx))
 			return nil
-		case *rule.RuleActionHijackDNS:
+		case *R.RuleActionHijackDNS:
 			for _, buffer := range buffers {
 				conn = bufio.NewCachedConn(conn, buffer)
 			}
@@ -154,7 +154,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
 	}))
 	if err != nil {
 		conn.Close()
-		if E.IsClosedOrCanceled(err) {
+		if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
 			r.logger.DebugContext(ctx, "connection closed: ", err)
 		} else {
 			r.logger.ErrorContext(ctx, err)
@@ -171,7 +171,7 @@ func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn,
 	err := r.routePacketConnection(ctx, conn, metadata, onClose)
 	if err != nil {
 		N.CloseOnHandshakeFailure(conn, onClose, err)
-		if E.IsClosedOrCanceled(err) {
+		if E.IsClosedOrCanceled(err) || R.IsRejected(err) {
 			r.logger.DebugContext(ctx, "connection closed: ", err)
 		} else {
 			r.logger.ErrorContext(ctx, err)
@@ -217,7 +217,7 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
 	var selectReturn bool
 	if selectedRule != nil {
 		switch action := selectedRule.Action().(type) {
-		case *rule.RuleActionRoute:
+		case *R.RuleActionRoute:
 			var loaded bool
 			selectedOutbound, loaded = r.outbound.Outbound(action.Outbound)
 			if !loaded {
@@ -228,11 +228,11 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
 				N.ReleaseMultiPacketBuffer(packetBuffers)
 				return E.New("UDP is not supported by outbound: ", selectedOutbound.Tag())
 			}
-		case *rule.RuleActionReject:
+		case *R.RuleActionReject:
 			N.ReleaseMultiPacketBuffer(packetBuffers)
 			N.CloseOnHandshakeFailure(conn, onClose, action.Error(ctx))
 			return nil
-		case *rule.RuleActionHijackDNS:
+		case *R.RuleActionHijackDNS:
 			r.hijackDNSPacket(ctx, conn, packetBuffers, metadata, onClose)
 			return nil
 		}
@@ -271,7 +271,7 @@ func (r *Router) PreMatch(metadata adapter.InboundContext) error {
 	if selectedRule == nil {
 		return nil
 	}
-	rejectAction, isReject := selectedRule.Action().(*rule.RuleActionReject)
+	rejectAction, isReject := selectedRule.Action().(*R.RuleActionReject)
 	if !isReject {
 		return nil
 	}
@@ -346,7 +346,7 @@ func (r *Router) matchRule(
 	//nolint:staticcheck
 	if metadata.InboundOptions != common.DefaultValue[option.InboundOptions]() {
 		if !preMatch && metadata.InboundOptions.SniffEnabled {
-			newBuffer, newPackerBuffers, newErr := r.actionSniff(ctx, metadata, &rule.RuleActionSniff{
+			newBuffer, newPackerBuffers, newErr := r.actionSniff(ctx, metadata, &R.RuleActionSniff{
 				OverrideDestination: metadata.InboundOptions.SniffOverrideDestination,
 				Timeout:             time.Duration(metadata.InboundOptions.SniffTimeout),
 			}, inputConn, inputPacketConn, nil)
@@ -361,7 +361,7 @@ func (r *Router) matchRule(
 			}
 		}
 		if dns.DomainStrategy(metadata.InboundOptions.DomainStrategy) != dns.DomainStrategyAsIS {
-			fatalErr = r.actionResolve(ctx, metadata, &rule.RuleActionResolve{
+			fatalErr = r.actionResolve(ctx, metadata, &R.RuleActionResolve{
 				Strategy: dns.DomainStrategy(metadata.InboundOptions.DomainStrategy),
 			})
 			if fatalErr != nil {
@@ -398,11 +398,11 @@ match:
 				}
 			}
 		}
-		var routeOptions *rule.RuleActionRouteOptions
+		var routeOptions *R.RuleActionRouteOptions
 		switch action := currentRule.Action().(type) {
-		case *rule.RuleActionRoute:
+		case *R.RuleActionRoute:
 			routeOptions = &action.RuleActionRouteOptions
-		case *rule.RuleActionRouteOptions:
+		case *R.RuleActionRouteOptions:
 			routeOptions = action
 		}
 		if routeOptions != nil {
@@ -448,7 +448,7 @@ match:
 			}
 		}
 		switch action := currentRule.Action().(type) {
-		case *rule.RuleActionSniff:
+		case *R.RuleActionSniff:
 			if !preMatch {
 				newBuffer, newPacketBuffers, newErr := r.actionSniff(ctx, metadata, action, inputConn, inputPacketConn, buffers)
 				if newErr != nil {
@@ -465,7 +465,7 @@ match:
 				selectedRuleIndex = currentRuleIndex
 				break match
 			}
-		case *rule.RuleActionResolve:
+		case *R.RuleActionResolve:
 			fatalErr = r.actionResolve(ctx, metadata, action)
 			if fatalErr != nil {
 				return
@@ -485,7 +485,7 @@ match:
 }
 
 func (r *Router) actionSniff(
-	ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionSniff,
+	ctx context.Context, metadata *adapter.InboundContext, action *R.RuleActionSniff,
 	inputConn net.Conn, inputPacketConn N.PacketConn, inputBuffers []*buf.Buffer,
 ) (buffer *buf.Buffer, packetBuffers []*N.PacketBuffer, fatalErr error) {
 	if sniff.Skip(metadata) {
@@ -645,7 +645,7 @@ func (r *Router) actionSniff(
 	return
 }
 
-func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *rule.RuleActionResolve) error {
+func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundContext, action *R.RuleActionResolve) error {
 	if metadata.Destination.IsFqdn() {
 		metadata.DNSServer = action.Server
 		addresses, err := r.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, action.Strategy)

+ 2 - 2
route/route_dns.go

@@ -170,7 +170,7 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, er
 							Question: []mDNS.Question{message.Question[0]},
 						}, nil
 					case C.RuleActionRejectMethodDrop:
-						return nil, tun.ErrDrop
+						return nil, &R.RejectedError{Cause: tun.ErrDrop}
 					}
 				}
 			}
@@ -289,7 +289,7 @@ func (r *Router) Lookup(ctx context.Context, domain string, strategy dns.DomainS
 					case C.RuleActionRejectMethodDefault:
 						return nil, nil
 					case C.RuleActionRejectMethodDrop:
-						return nil, tun.ErrDrop
+						return nil, &R.RejectedError{Cause: tun.ErrDrop}
 					}
 				}
 			}

+ 21 - 3
route/rule/rule_action.go

@@ -2,6 +2,7 @@ package rule
 
 import (
 	"context"
+	"errors"
 	"net/netip"
 	"strings"
 	"sync"
@@ -250,6 +251,23 @@ func (r *RuleActionDirect) String() string {
 	return "direct" + r.description
 }
 
+type RejectedError struct {
+	Cause error
+}
+
+func (r *RejectedError) Error() string {
+	return "rejected"
+}
+
+func (r *RejectedError) Unwrap() error {
+	return r.Cause
+}
+
+func IsRejected(err error) bool {
+	var rejected *RejectedError
+	return errors.As(err, &rejected)
+}
+
 type RuleActionReject struct {
 	Method      string
 	NoDrop      bool
@@ -273,9 +291,9 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
 	var returnErr error
 	switch r.Method {
 	case C.RuleActionRejectMethodDefault:
-		returnErr = syscall.ECONNREFUSED
+		returnErr = &RejectedError{syscall.ECONNREFUSED}
 	case C.RuleActionRejectMethodDrop:
-		return tun.ErrDrop
+		return &RejectedError{tun.ErrDrop}
 	default:
 		panic(F.ToString("unknown reject method: ", r.Method))
 	}
@@ -293,7 +311,7 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
 		if ctx != nil {
 			r.logger.DebugContext(ctx, "dropped due to flooding")
 		}
-		return tun.ErrDrop
+		return &RejectedError{tun.ErrDrop}
 	}
 	return returnErr
 }