security: prevent send-on-close panic
Move channel sends into mutex lock to prevent channel closure from racing with the send. Add a buffer to the event and inbox channels for backpressure management.
This commit is contained in:
+13
-19
@@ -214,7 +214,7 @@ func (e *Embassy) send(url string, data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Embassy) subscribeEventsLock(url string) <-chan PoolEvent {
|
func (e *Embassy) subscribeEventsLock(url string) <-chan PoolEvent {
|
||||||
ch := make(chan PoolEvent)
|
ch := make(chan PoolEvent, 256)
|
||||||
e.eventSubs[url] = ch
|
e.eventSubs[url] = ch
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ func (e *Embassy) unsubscribeEventsLock(url string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *Embassy) subscribeInboxLock(url string) <-chan InboxMessage {
|
func (e *Embassy) subscribeInboxLock(url string) <-chan InboxMessage {
|
||||||
ch := make(chan InboxMessage)
|
ch := make(chan InboxMessage, 256)
|
||||||
e.inboxSubs[url] = ch
|
e.inboxSubs[url] = ch
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
@@ -258,21 +258,18 @@ func (e *Embassy) routeEvents() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
e.mu.RLock()
|
e.mu.Lock()
|
||||||
sub, ok := e.eventSubs[url]
|
ch, ok := e.eventSubs[url]
|
||||||
e.mu.RUnlock()
|
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
e.mu.Unlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
ch <- PoolEvent{
|
||||||
case <-e.ctx.Done():
|
|
||||||
return
|
|
||||||
case sub <- PoolEvent{
|
|
||||||
URL: ev.URL, Kind: mapEmbassyEvent(ev.Kind), At: ev.At, Err: ev.Err,
|
URL: ev.URL, Kind: mapEmbassyEvent(ev.Kind), At: ev.At, Err: ev.Err,
|
||||||
}:
|
|
||||||
}
|
}
|
||||||
|
e.mu.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,20 +289,17 @@ func (e *Embassy) routeInbox() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
e.mu.RLock()
|
e.mu.Lock()
|
||||||
sub, ok := e.inboxSubs[url]
|
ch, ok := e.inboxSubs[url]
|
||||||
e.mu.RUnlock()
|
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
|
e.mu.Unlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
ch <- InboxMessage{
|
||||||
case <-e.ctx.Done():
|
URL: ev.URL, Data: ev.Data, ReceivedAt: ev.ReceivedAt}
|
||||||
return
|
e.mu.Unlock()
|
||||||
case sub <- InboxMessage{
|
|
||||||
URL: ev.URL, Data: ev.Data, ReceivedAt: ev.ReceivedAt}:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user