diff --git a/component/fakeip/pool.go b/component/fakeip/pool.go index 925882bb..e6730a05 100644 --- a/component/fakeip/pool.go +++ b/component/fakeip/pool.go @@ -3,6 +3,7 @@ package fakeip import ( "errors" "net" + "strings" "sync" "github.com/Dreamacro/clash/common/cache" @@ -36,6 +37,9 @@ type Pool struct { func (p *Pool) Lookup(host string) net.IP { p.mux.Lock() defer p.mux.Unlock() + + // RFC4343: DNS Case Insensitive, we SHOULD return result with all cases. + host = strings.ToLower(host) if ip, exist := p.store.GetByHost(host); exist { return ip } diff --git a/component/fakeip/pool_test.go b/component/fakeip/pool_test.go index bd034636..7e161d03 100644 --- a/component/fakeip/pool_test.go +++ b/component/fakeip/pool_test.go @@ -75,6 +75,27 @@ func TestPool_Basic(t *testing.T) { } } +func TestPool_Case_Insensitive(t *testing.T) { + _, ipnet, _ := net.ParseCIDR("192.168.0.1/29") + pools, tempfile, err := createPools(Options{ + IPNet: ipnet, + Size: 10, + }) + assert.Nil(t, err) + defer os.Remove(tempfile) + + for _, pool := range pools { + first := pool.Lookup("foo.com") + last := pool.Lookup("Foo.Com") + foo, exist := pool.LookBack(last) + + assert.True(t, first.Equal(pool.Lookup("Foo.Com"))) + assert.Equal(t, pool.Lookup("fOo.cOM"), first) + assert.True(t, exist) + assert.Equal(t, foo, "foo.com") + } +} + func TestPool_CycleUsed(t *testing.T) { _, ipnet, _ := net.ParseCIDR("192.168.0.1/29") pools, tempfile, err := createPools(Options{