fix: 认证失败不泄漏连接表并脱敏 mochi 整包日志
This commit is contained in:
@@ -92,6 +92,8 @@ type Broker struct {
|
||||
connsMu sync.RWMutex
|
||||
current map[string]*connState
|
||||
byClient map[*mqtt.Client]*connState
|
||||
byConnID map[port.ConnID]*connState
|
||||
closedCh chan struct{}
|
||||
|
||||
queuesMu sync.Mutex
|
||||
queues map[string]*uplinkQueue
|
||||
@@ -116,6 +118,8 @@ type connState struct {
|
||||
largePIDs map[uint16]struct{}
|
||||
largePending int
|
||||
metricsCounted bool
|
||||
established bool
|
||||
createdAt time.Time
|
||||
mu sync.Mutex
|
||||
|
||||
handshakeTimer *time.Timer
|
||||
@@ -135,6 +139,7 @@ func New(opts Options) (*Broker, error) {
|
||||
if log == nil {
|
||||
log = slog.Default()
|
||||
}
|
||||
log = slog.New(newRedactHandler(log.Handler()))
|
||||
|
||||
caps := mqtt.NewDefaultServerCapabilities()
|
||||
caps.MaximumClients = maxClients
|
||||
@@ -165,6 +170,8 @@ func New(opts Options) (*Broker, error) {
|
||||
metrics: opts.Metrics,
|
||||
current: make(map[string]*connState),
|
||||
byClient: make(map[*mqtt.Client]*connState),
|
||||
byConnID: make(map[port.ConnID]*connState),
|
||||
closedCh: make(chan struct{}),
|
||||
queues: make(map[string]*uplinkQueue),
|
||||
largeSem: make(chan struct{}, largeFrameSlots),
|
||||
}
|
||||
@@ -175,6 +182,7 @@ func New(opts Options) (*Broker, error) {
|
||||
if err := srv.Serve(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go b.sweepLoop()
|
||||
return b, nil
|
||||
}
|
||||
|
||||
@@ -186,6 +194,11 @@ func (b *Broker) Close() error {
|
||||
if b.closed.Swap(true) {
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
case <-b.closedCh:
|
||||
default:
|
||||
close(b.closedCh)
|
||||
}
|
||||
b.queuesMu.Lock()
|
||||
for _, q := range b.queues {
|
||||
q.close()
|
||||
@@ -345,10 +358,9 @@ func (b *Broker) lookupConn(endpointID string, connID port.ConnID) *connState {
|
||||
b.connsMu.RLock()
|
||||
defer b.connsMu.RUnlock()
|
||||
if connID != "" {
|
||||
for _, st := range b.byClient {
|
||||
if st.endpointID == endpointID && st.connID == connID {
|
||||
return st
|
||||
}
|
||||
st := b.byConnID[connID]
|
||||
if st != nil && st.endpointID == endpointID {
|
||||
return st
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -462,12 +474,46 @@ func (b *Broker) CurrentConnID(endpointID string) (port.ConnID, bool) {
|
||||
func (b *Broker) connStateOf(endpointID string, connID port.ConnID) *connState {
|
||||
b.connsMu.RLock()
|
||||
defer b.connsMu.RUnlock()
|
||||
for _, st := range b.byClient {
|
||||
if st.endpointID == endpointID && st.connID == connID {
|
||||
return st
|
||||
st := b.byConnID[connID]
|
||||
if st == nil || st.endpointID != endpointID {
|
||||
return nil
|
||||
}
|
||||
return st
|
||||
}
|
||||
|
||||
func (b *Broker) sweepLoop() {
|
||||
tick := time.NewTicker(time.Minute)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
b.sweepUnestablished(time.Minute)
|
||||
case <-b.closedCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Broker) sweepUnestablished(minAge time.Duration) {
|
||||
now := time.Now()
|
||||
b.connsMu.Lock()
|
||||
defer b.connsMu.Unlock()
|
||||
for cl, st := range b.byClient {
|
||||
if st.established {
|
||||
continue
|
||||
}
|
||||
if cl != nil && !cl.Closed() {
|
||||
continue
|
||||
}
|
||||
if minAge > 0 && now.Sub(st.createdAt) < minAge {
|
||||
continue
|
||||
}
|
||||
delete(b.byClient, cl)
|
||||
delete(b.byConnID, st.connID)
|
||||
if b.current[st.endpointID] == st {
|
||||
delete(b.current, st.endpointID)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Broker) hasDownSub(st *connState) bool {
|
||||
|
||||
Reference in New Issue
Block a user