test: Singbox内核删除用户时尝试关闭该用户所有TCP会话
Some checks failed
Build and Release / build (386, freebsd) (push) Waiting to run
Build and Release / build (386, linux) (push) Waiting to run
Build and Release / build (386, windows) (push) Waiting to run
Build and Release / build (amd64, darwin) (push) Waiting to run
Build and Release / build (amd64, freebsd) (push) Waiting to run
Build and Release / build (amd64, linux) (push) Waiting to run
Build and Release / build (amd64, windows) (push) Waiting to run
Build and Release / build (arm, 5, linux) (push) Waiting to run
Build and Release / build (arm, 6, linux) (push) Waiting to run
Build and Release / build (arm, 7, freebsd) (push) Waiting to run
Build and Release / build (arm, 7, linux) (push) Waiting to run
Build and Release / build (arm64, android) (push) Waiting to run
Build and Release / build (arm64, darwin) (push) Waiting to run
Build and Release / build (arm64, freebsd) (push) Waiting to run
Build and Release / build (arm64, linux) (push) Waiting to run
Build and Release / build (mips, linux) (push) Waiting to run
Build and Release / build (mips64, linux) (push) Waiting to run
Build and Release / build (mips64le, linux) (push) Waiting to run
Build and Release / build (mipsle, linux) (push) Waiting to run
Build and Release / build (ppc64, linux) (push) Waiting to run
Build and Release / build (ppc64le, linux) (push) Waiting to run
Build and Release / build (riscv64, linux) (push) Waiting to run
Build and Release / build (s390x, linux) (push) Waiting to run
CodeQL / Analyze (go) (push) Has been cancelled

This commit is contained in:
wyx2685 2025-03-05 19:54:06 +09:00
parent 61606646b9
commit 1c8c17b067
No known key found for this signature in database
GPG Key ID: 8827A30FF1DB1379
4 changed files with 64 additions and 15 deletions

View File

@ -61,7 +61,7 @@ jobs:
run: | run: |
mkdir -p /tmp/digests mkdir -p /tmp/digests
digest="${{ steps.build.outputs.digest }}" digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}" echo "${digest#sha256:}" > "/tmp/digests/${digest#sha256:}"
- name: Upload digest - name: Upload digest
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4

View File

@ -20,7 +20,8 @@ import (
var _ adapter.ConnectionTracker = (*HookServer)(nil) var _ adapter.ConnectionTracker = (*HookServer)(nil)
type HookServer struct { 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 { func (h *HookServer) ModeList() []string {
@ -29,7 +30,8 @@ func (h *HookServer) ModeList() []string {
func NewHookServer() *HookServer { func NewHookServer() *HookServer {
server := &HookServer{ server := &HookServer{
counter: sync.Map{}, counter: sync.Map{},
userconn: sync.Map{},
} }
return server 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) log.Warn("get limiter for ", m.Inbound, " error: ", err)
return conn return conn
} }
taguuid := format.UserTag(m.Inbound, m.User)
ip := m.Source.Addr.String() 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() conn.Close()
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
return 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 { var t *counter.TrafficCounter
return counter.NewConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.User)) if c, ok := h.counter.Load(m.Inbound); !ok {
t = counter.NewTrafficCounter()
h.counter.Store(m.Inbound, t)
} else { } else {
c := counter.NewTrafficCounter() t = c.(*counter.TrafficCounter)
h.counter.Store(m.Inbound, c)
return counter.NewConnCounter(conn, c.GetCounter(m.User))
} }
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 { 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 return conn
} }
ip := m.Source.Addr.String() 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() conn.Close()
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn") log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
return 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 { var t *counter.TrafficCounter
return counter.NewPacketConnCounter(conn, c.(*counter.TrafficCounter).GetCounter(m.User)) if c, ok := h.counter.Load(m.Inbound); !ok {
t = counter.NewTrafficCounter()
h.counter.Store(m.Inbound, t)
} else { } else {
c := counter.NewTrafficCounter() t = c.(*counter.TrafficCounter)
h.counter.Store(m.Inbound, c)
return counter.NewPacketConnCounter(conn, c.GetCounter(m.User))
} }
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
} }

View File

@ -138,5 +138,9 @@ func (b *Sing) DelUsers(users []panel.UserInfo, tag string, info *panel.NodeInfo
if err != nil { if err != nil {
return err return err
} }
err = b.hookServer.CloseConnections(tag, uuids)
if err != nil {
return err
}
return nil return nil
} }

View File

@ -164,6 +164,8 @@ func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool, noSSUDP bool
} else { } else {
userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit) userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit)
} }
} else {
return nil, true
} }
if noSSUDP { if noSSUDP {
// Store online user for device limit // Store online user for device limit