From e93706445f3cdee04bf3ef6d4ab54f98cffd3d65 Mon Sep 17 00:00:00 2001 From: yuzuki999 Date: Fri, 4 Aug 2023 23:25:27 +0800 Subject: [PATCH] change v2rayServer to clashServer, and complete limit for sing --- core/sing/hook.go | 128 ++++++++++++++++++++++++++++++++++------------ core/sing/sing.go | 2 +- 2 files changed, 96 insertions(+), 34 deletions(-) diff --git a/core/sing/hook.go b/core/sing/hook.go index afd4c70..35f72ad 100644 --- a/core/sing/hook.go +++ b/core/sing/hook.go @@ -1,8 +1,9 @@ package sing import ( + "context" + "github.com/inazumav/sing-box/common/urltest" "net" - "strings" "sync" "github.com/InazumaV/V2bX/common/rate" @@ -16,15 +17,14 @@ import ( ) type HookServer struct { - hooker *Hooker + logger log.Logger + counter sync.Map } func NewHookServer(logger log.Logger) *HookServer { return &HookServer{ - hooker: &Hooker{ - logger: logger, - counter: sync.Map{}, - }, + logger: logger, + counter: sync.Map{}, } } @@ -36,47 +36,109 @@ func (h *HookServer) Close() error { return nil } -func (h *HookServer) StatsService() adapter.V2RayStatsService { - return h.hooker +func (h *HookServer) PreStart() error { + return nil } -func (h *HookServer) Hooker() *Hooker { - return h.hooker -} - -type Hooker struct { - logger log.Logger - counter sync.Map -} - -func (h *Hooker) RoutedConnection(inbound string, outbound string, user string, conn net.Conn) net.Conn { - l, err := limiter.GetLimiter(inbound) +func (h *HookServer) RoutedConnection(_ context.Context, conn net.Conn, m adapter.InboundContext, _ adapter.Rule) (net.Conn, adapter.Tracker) { + l, err := limiter.GetLimiter(m.Inbound) if err != nil { - log.Error("get limiter for ", inbound, " error: ", err) + log.Error("get limiter for ", m.Inbound, " error: ", err) } - ip, _, _ := strings.Cut(conn.RemoteAddr().String(), ":") - if b, r := l.CheckLimit(user, ip, true); r { + if l.CheckDomainRule(m.Domain) { conn.Close() - h.logger.Error("[", inbound, "] ", "Limited ", user, " by ip or conn") - return conn + h.logger.Error("[", m.Inbound, "] ", + "Limited ", m.User, "access to", m.Domain, " by domain rule") + return conn, &Tracker{l: func() {}} + } + if l.CheckProtocolRule(m.Protocol) { + conn.Close() + h.logger.Error("[", m.Inbound, "] ", + "Limited ", m.User, "use", m.Domain, " by protocol rule") + return conn, &Tracker{l: func() {}} + } + ip := m.Source.Addr.String() + if b, r := l.CheckLimit(m.User, ip, true); r { + conn.Close() + h.logger.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") + return conn, &Tracker{l: func() {}} } else if b != nil { conn = rate.NewConnRateLimiter(conn, b) } - if c, ok := h.counter.Load(inbound); ok { - return counter.NewConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(user)) + t := &Tracker{ + l: func() { + l.ConnLimiter.DelConnCount(m.User, ip) + }, + } + if c, ok := h.counter.Load(m.Inbound); ok { + return counter.NewConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.Inbound)), t } else { c := counter.NewTrafficCounter() - h.counter.Store(inbound, c) - return counter.NewConnCounter(conn, c.GetCounter(user)) + h.counter.Store(m.Inbound, c) + return counter.NewConnCounter(conn, c.GetCounter(m.Inbound)), t } } -func (h *Hooker) RoutedPacketConnection(inbound string, outbound string, user string, conn N.PacketConn) N.PacketConn { - if c, ok := h.counter.Load(inbound); ok { - return counter.NewPacketConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(user)) +func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn, m adapter.InboundContext, _ adapter.Rule) (N.PacketConn, adapter.Tracker) { + t := &Tracker{ + l: func() {}, + } + l, err := limiter.GetLimiter(m.Inbound) + if err != nil { + log.Error("get limiter for ", m.Inbound, " error: ", err) + } + if l.CheckDomainRule(m.Domain) { + conn.Close() + h.logger.Error("[", m.Inbound, "] ", + "Limited ", m.User, "access to", m.Domain, " by domain rule") + return conn, t + } + if l.CheckProtocolRule(m.Protocol) { + conn.Close() + h.logger.Error("[", m.Inbound, "] ", + "Limited ", m.User, "use", m.Domain, " by protocol rule") + return conn, t + } + ip := m.Source.Addr.String() + if b, r := l.CheckLimit(m.User, ip, true); r { + conn.Close() + h.logger.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") + return conn, &Tracker{l: func() {}} + } else if b != nil { + conn = rate.NewPacketConnCounter(conn, b) + } + if c, ok := h.counter.Load(m.Inbound); ok { + return counter.NewPacketConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.User)), t } else { c := counter.NewTrafficCounter() - h.counter.Store(inbound, c) - return counter.NewPacketConnCounter(conn, c.GetCounter(user)) + h.counter.Store(m.Inbound, c) + return counter.NewPacketConnCounter(conn, c.GetCounter(m.User)), t } } + +// not need + +func (h *HookServer) Mode() string { + return "" +} +func (h *HookServer) StoreSelected() bool { + return false +} +func (h *HookServer) CacheFile() adapter.ClashCacheFile { + return nil +} +func (h *HookServer) HistoryStorage() *urltest.HistoryStorage { + return nil +} + +func (h *HookServer) StoreFakeIP() bool { + return false +} + +type Tracker struct { + l func() +} + +func (t *Tracker) Leave() { + t.l() +} diff --git a/core/sing/sing.go b/core/sing/sing.go index 1f5a814..a7189f7 100644 --- a/core/sing/sing.go +++ b/core/sing/sing.go @@ -129,7 +129,7 @@ func New(c *conf.CoreConfig) (vCore.Core, error) { if err != nil { return nil, E.Cause(err, "create v2ray api server") } - router.SetV2RayServer(server) + router.SetClashServer(server) return &Box{ router: router, inbounds: inMap,