mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-24 16:23:30 +03:00
Fix DNS query loopback deadlock from shared dedup lock
This commit is contained in:
@@ -41,9 +41,9 @@ type Client struct {
|
|||||||
initRDRCFunc func() adapter.RDRCStore
|
initRDRCFunc func() adapter.RDRCStore
|
||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
cache freelru.Cache[dns.Question, *dns.Msg]
|
cache freelru.Cache[dns.Question, *dns.Msg]
|
||||||
cacheLock compatible.Map[dns.Question, chan struct{}]
|
cacheLock compatible.Map[transportCacheKey, chan struct{}]
|
||||||
transportCache freelru.Cache[transportCacheKey, *dns.Msg]
|
transportCache freelru.Cache[transportCacheKey, *dns.Msg]
|
||||||
transportCacheLock compatible.Map[dns.Question, chan struct{}]
|
transportCacheLock compatible.Map[transportCacheKey, chan struct{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientOptions struct {
|
type ClientOptions struct {
|
||||||
@@ -138,8 +138,9 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
|||||||
!options.ClientSubnet.IsValid()
|
!options.ClientSubnet.IsValid()
|
||||||
disableCache := !isSimpleRequest || c.disableCache || options.DisableCache
|
disableCache := !isSimpleRequest || c.disableCache || options.DisableCache
|
||||||
if !disableCache {
|
if !disableCache {
|
||||||
|
cacheKey := transportCacheKey{Question: question, transportTag: transport.Tag()}
|
||||||
if c.cache != nil {
|
if c.cache != nil {
|
||||||
cond, loaded := c.cacheLock.LoadOrStore(question, make(chan struct{}))
|
cond, loaded := c.cacheLock.LoadOrStore(cacheKey, make(chan struct{}))
|
||||||
if loaded {
|
if loaded {
|
||||||
select {
|
select {
|
||||||
case <-cond:
|
case <-cond:
|
||||||
@@ -148,12 +149,12 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
defer func() {
|
defer func() {
|
||||||
c.cacheLock.Delete(question)
|
c.cacheLock.Delete(cacheKey)
|
||||||
close(cond)
|
close(cond)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
} else if c.transportCache != nil {
|
} else if c.transportCache != nil {
|
||||||
cond, loaded := c.transportCacheLock.LoadOrStore(question, make(chan struct{}))
|
cond, loaded := c.transportCacheLock.LoadOrStore(cacheKey, make(chan struct{}))
|
||||||
if loaded {
|
if loaded {
|
||||||
select {
|
select {
|
||||||
case <-cond:
|
case <-cond:
|
||||||
@@ -162,7 +163,7 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
defer func() {
|
defer func() {
|
||||||
c.transportCacheLock.Delete(question)
|
c.transportCacheLock.Delete(cacheKey)
|
||||||
close(cond)
|
close(cond)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user