소스 검색

Fix hosts DNS server

k9982874 7 달 전
부모
커밋
7d6adf6933
5개의 변경된 파일24개의 추가작업 그리고 10개의 파일을 삭제
  1. 2 2
      dns/client.go
  2. 17 3
      dns/transport/hosts/hosts.go
  3. 1 1
      dns/transport/hosts/hosts_file.go
  4. 2 2
      dns/transport/hosts/hosts_test.go
  5. 2 2
      option/dns.go

+ 2 - 2
dns/client.go

@@ -537,7 +537,7 @@ func FixedResponse(id uint16, question dns.Question, addresses []netip.Addr, tim
 		Question: []dns.Question{question},
 	}
 	for _, address := range addresses {
-		if address.Is4() {
+		if address.Is4() && question.Qtype == dns.TypeA {
 			response.Answer = append(response.Answer, &dns.A{
 				Hdr: dns.RR_Header{
 					Name:   question.Name,
@@ -547,7 +547,7 @@ func FixedResponse(id uint16, question dns.Question, addresses []netip.Addr, tim
 				},
 				A: address.AsSlice(),
 			})
-		} else {
+		} else if address.Is6() && question.Qtype == dns.TypeAAAA {
 			response.Answer = append(response.Answer, &dns.AAAA{
 				Hdr: dns.RR_Header{
 					Name:   question.Name,

+ 17 - 3
dns/transport/hosts/hosts.go

@@ -2,6 +2,7 @@ package hosts
 
 import (
 	"context"
+	"net/netip"
 	"os"
 
 	"github.com/sagernet/sing-box/adapter"
@@ -22,11 +23,15 @@ var _ adapter.DNSTransport = (*Transport)(nil)
 
 type Transport struct {
 	dns.TransportAdapter
-	files []*File
+	files      []*File
+	predefined map[string][]netip.Addr
 }
 
 func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.HostsDNSServerOptions) (adapter.DNSTransport, error) {
-	var files []*File
+	var (
+		files      []*File
+		predefined = make(map[string][]netip.Addr)
+	)
 	if len(options.Path) == 0 {
 		files = append(files, NewFile(DefaultPath))
 	} else {
@@ -34,9 +39,15 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
 			files = append(files, NewFile(filemanager.BasePath(ctx, os.ExpandEnv(path))))
 		}
 	}
+	if options.Predefined != nil {
+		for _, entry := range options.Predefined.Entries() {
+			predefined[mDNS.CanonicalName(entry.Key)] = entry.Value
+		}
+	}
 	return &Transport{
 		TransportAdapter: dns.NewTransportAdapter(C.DNSTypeHosts, tag, nil),
 		files:            files,
+		predefined:       predefined,
 	}, nil
 }
 
@@ -45,8 +56,11 @@ func (t *Transport) Reset() {
 
 func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
 	question := message.Question[0]
-	domain := dns.FqdnToDomain(question.Name)
+	domain := mDNS.CanonicalName(question.Name)
 	if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
+		if addresses, ok := t.predefined[domain]; ok {
+			return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
+		}
 		for _, file := range t.files {
 			addresses := file.Lookup(domain)
 			if len(addresses) > 0 {

+ 1 - 1
dns/transport/hosts/hosts_file.go

@@ -34,7 +34,7 @@ func (f *File) Lookup(name string) []netip.Addr {
 	f.access.Lock()
 	defer f.access.Unlock()
 	f.update()
-	return f.byName[name]
+	return f.byName[dns.CanonicalName(name)]
 }
 
 func (f *File) update() {

+ 2 - 2
dns/transport/hosts/hosts_test.go

@@ -11,6 +11,6 @@ import (
 
 func TestHosts(t *testing.T) {
 	t.Parallel()
-	require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, hosts.NewFile("testdata/hosts").Lookup("localhost."))
-	require.NotEmpty(t, hosts.NewFile(hosts.DefaultPath).Lookup("localhost."))
+	require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, hosts.NewFile("testdata/hosts").Lookup("localhost"))
+	require.NotEmpty(t, hosts.NewFile(hosts.DefaultPath).Lookup("localhost"))
 }

+ 2 - 2
option/dns.go

@@ -316,8 +316,8 @@ type LegacyDNSServerOptions struct {
 }
 
 type HostsDNSServerOptions struct {
-	Path       badoption.Listable[string]                               `json:"path,omitempty"`
-	Predefined badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
+	Path       badoption.Listable[string]                                `json:"path,omitempty"`
+	Predefined *badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
 }
 
 type LocalDNSServerOptions struct {