mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
Fix panic: index out of range (#727)
This commit is contained in:
parent
733c5dea88
commit
45740be4af
@ -66,9 +66,6 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
|
|||||||
for _, ns := range config.NameServer {
|
for _, ns := range config.NameServer {
|
||||||
domainRuleCount += len(ns.PrioritizedDomain)
|
domainRuleCount += len(ns.PrioritizedDomain)
|
||||||
}
|
}
|
||||||
// Fixes https://github.com/v2fly/v2ray-core/issues/529
|
|
||||||
// Compatible with `localhost` nameserver specified in config file
|
|
||||||
domainRuleCount += len(localTLDsAndDotlessDomains)
|
|
||||||
|
|
||||||
// MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1
|
// MatcherInfos is ensured to cover the maximum index domainMatcher could return, where matcher's index starts from 1
|
||||||
matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1)
|
matcherInfos := make([]DomainMatcherInfo, domainRuleCount+1)
|
||||||
@ -86,7 +83,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
|
|||||||
|
|
||||||
for _, ns := range config.NameServer {
|
for _, ns := range config.NameServer {
|
||||||
clientIdx := len(clients)
|
clientIdx := len(clients)
|
||||||
updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int) error {
|
updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []DomainMatcherInfo) error {
|
||||||
midx := domainMatcher.Add(domainRule)
|
midx := domainMatcher.Add(domainRule)
|
||||||
matcherInfos[midx] = DomainMatcherInfo{
|
matcherInfos[midx] = DomainMatcherInfo{
|
||||||
clientIdx: uint16(clientIdx),
|
clientIdx: uint16(clientIdx),
|
||||||
@ -100,7 +97,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
|
|||||||
case net.IPv4len, net.IPv6len:
|
case net.IPv4len, net.IPv6len:
|
||||||
myClientIP = net.IP(ns.ClientIp)
|
myClientIP = net.IP(ns.ClientIp)
|
||||||
}
|
}
|
||||||
client, err := NewClient(ctx, ns, myClientIP, geoipContainer, updateDomain)
|
client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, newError("failed to create client").Base(err)
|
return nil, newError("failed to create client").Base(err)
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher) (Server, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
|
// NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
|
||||||
func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container router.GeoIPMatcherContainer, updateDomainRule func(strmatcher.Matcher, int) error) (*Client, error) {
|
func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container router.GeoIPMatcherContainer, matcherInfos *[]DomainMatcherInfo, updateDomainRule func(strmatcher.Matcher, int, []DomainMatcherInfo) error) (*Client, error) {
|
||||||
client := &Client{}
|
client := &Client{}
|
||||||
err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {
|
err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {
|
||||||
// Create a new server for each client for now
|
// Create a new server for each client for now
|
||||||
@ -78,6 +78,19 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container r
|
|||||||
if _, isLocalDNS := server.(*LocalNameServer); isLocalDNS {
|
if _, isLocalDNS := server.(*LocalNameServer); isLocalDNS {
|
||||||
ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...)
|
ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...)
|
||||||
ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule)
|
ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule)
|
||||||
|
// The following lines is a solution to avoid core panics(rule index out of range) when setting `localhost` DNS client in config.
|
||||||
|
// Because the `localhost` DNS client will apend len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule.
|
||||||
|
// But `matcherInfos` has no enough length to add rules, which leads to core panics (rule index out of range).
|
||||||
|
// To avoid this, the length of `matcherInfos` must be equal to the expected, so manually append it with Golang default zero value first for later modification.
|
||||||
|
// Related issues:
|
||||||
|
// https://github.com/v2fly/v2ray-core/issues/529
|
||||||
|
// https://github.com/v2fly/v2ray-core/issues/719
|
||||||
|
for i := 0; i < len(localTLDsAndDotlessDomains); i++ {
|
||||||
|
*matcherInfos = append(*matcherInfos, DomainMatcherInfo{
|
||||||
|
clientIdx: uint16(0),
|
||||||
|
domainRuleIdx: uint16(0),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establish domain rules
|
// Establish domain rules
|
||||||
@ -104,7 +117,7 @@ func NewClient(ctx context.Context, ns *NameServer, clientIP net.IP, container r
|
|||||||
rules = append(rules, domainRule.String())
|
rules = append(rules, domainRule.String())
|
||||||
ruleCurr++
|
ruleCurr++
|
||||||
}
|
}
|
||||||
err = updateDomainRule(domainRule, originalRuleIdx)
|
err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newError("failed to create prioritized domain").Base(err).AtWarning()
|
return newError("failed to create prioritized domain").Base(err).AtWarning()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user