From 1c8c17b06717004c89c86be3597362b4745cceae Mon Sep 17 00:00:00 2001 From: wyx2685 Date: Wed, 5 Mar 2025 19:54:06 +0900 Subject: [PATCH] =?UTF-8?q?test:=20Singbox=E5=86=85=E6=A0=B8=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=94=A8=E6=88=B7=E6=97=B6=E5=B0=9D=E8=AF=95=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E8=AF=A5=E7=94=A8=E6=88=B7=E6=89=80=E6=9C=89TCP?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Publish Docker image.yml | 2 +- core/sing/hook.go | 71 +++++++++++++++++----- core/sing/user.go | 4 ++ limiter/limiter.go | 2 + 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/.github/workflows/Publish Docker image.yml b/.github/workflows/Publish Docker image.yml index ea0e5e6..e9a11ca 100644 --- a/.github/workflows/Publish Docker image.yml +++ b/.github/workflows/Publish Docker image.yml @@ -61,7 +61,7 @@ jobs: run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" + echo "${digest#sha256:}" > "/tmp/digests/${digest#sha256:}" - name: Upload digest uses: actions/upload-artifact@v4 diff --git a/core/sing/hook.go b/core/sing/hook.go index 9bce059..98ef871 100644 --- a/core/sing/hook.go +++ b/core/sing/hook.go @@ -20,7 +20,8 @@ import ( var _ adapter.ConnectionTracker = (*HookServer)(nil) type HookServer struct { - counter sync.Map + counter sync.Map //map[string]*counter.TrafficCounter + userconn sync.Map //map[string][]net.Conn } func (h *HookServer) ModeList() []string { @@ -29,7 +30,8 @@ func (h *HookServer) ModeList() []string { func NewHookServer() *HookServer { server := &HookServer{ - counter: sync.Map{}, + counter: sync.Map{}, + userconn: sync.Map{}, } return server } @@ -40,8 +42,9 @@ func (h *HookServer) RoutedConnection(_ context.Context, conn net.Conn, m adapte log.Warn("get limiter for ", m.Inbound, " error: ", err) return conn } + taguuid := format.UserTag(m.Inbound, m.User) ip := m.Source.Addr.String() - if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true, true); r { + if b, r := l.CheckLimit(taguuid, ip, true, true); r { conn.Close() log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") return conn @@ -70,13 +73,26 @@ func (h *HookServer) RoutedConnection(_ context.Context, conn net.Conn, m adapte } } } - if c, ok := h.counter.Load(m.Inbound); ok { - return counter.NewConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.User)) + var t *counter.TrafficCounter + if c, ok := h.counter.Load(m.Inbound); !ok { + t = counter.NewTrafficCounter() + h.counter.Store(m.Inbound, t) } else { - c := counter.NewTrafficCounter() - h.counter.Store(m.Inbound, c) - return counter.NewConnCounter(conn, c.GetCounter(m.User)) + t = c.(*counter.TrafficCounter) } + + conn = counter.NewConnCounter(conn, t.GetCounter(m.User)) + if conns, exist := h.userconn.Load(taguuid); exist { + if connList, ok := conns.([]net.Conn); ok { + h.userconn.Store(taguuid, append(connList, conn)) + } else { + h.userconn.Store(taguuid, []net.Conn{conn}) + } + } else { + h.userconn.Store(taguuid, []net.Conn{conn}) + } + + return conn } func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn, m adapter.InboundContext, _ adapter.Rule, _ adapter.Outbound) N.PacketConn { @@ -86,7 +102,8 @@ func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn return conn } ip := m.Source.Addr.String() - if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, false, false); r { + taguuid := format.UserTag(m.Inbound, m.User) + if b, r := l.CheckLimit(taguuid, ip, false, false); r { conn.Close() log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") return conn @@ -115,11 +132,37 @@ func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn } } } - if c, ok := h.counter.Load(m.Inbound); ok { - return counter.NewPacketConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.User)) + var t *counter.TrafficCounter + if c, ok := h.counter.Load(m.Inbound); !ok { + t = counter.NewTrafficCounter() + h.counter.Store(m.Inbound, t) } else { - c := counter.NewTrafficCounter() - h.counter.Store(m.Inbound, c) - return counter.NewPacketConnCounter(conn, c.GetCounter(m.User)) + t = c.(*counter.TrafficCounter) } + conn = counter.NewPacketConnCounter(conn, t.GetCounter(m.User)) + return conn +} + +func (h *HookServer) CloseConnections(tag string, uuids []string) error { + for _, uuid := range uuids { + taguuid := format.UserTag(tag, uuid) + v, ok := h.userconn.Load(taguuid) + if !ok { + continue + } + connList, ok := v.([]net.Conn) + if !ok { + h.userconn.Delete(taguuid) + continue + } + + for _, conn := range connList { + err := conn.Close() + if err != nil { + log.Error("close conn error: ", err) + } + } + h.userconn.Delete(taguuid) + } + return nil } diff --git a/core/sing/user.go b/core/sing/user.go index 7668c8e..cfe57b0 100644 --- a/core/sing/user.go +++ b/core/sing/user.go @@ -138,5 +138,9 @@ func (b *Sing) DelUsers(users []panel.UserInfo, tag string, info *panel.NodeInfo if err != nil { return err } + err = b.hookServer.CloseConnections(tag, uuids) + if err != nil { + return err + } return nil } diff --git a/limiter/limiter.go b/limiter/limiter.go index b24209f..a6470f5 100644 --- a/limiter/limiter.go +++ b/limiter/limiter.go @@ -164,6 +164,8 @@ func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool, noSSUDP bool } else { userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit) } + } else { + return nil, true } if noSSUDP { // Store online user for device limit