Files
sing-box-extended-mirror/dns/transport/hosts/hosts.go
T

85 lines
2.2 KiB
Go
Raw Normal View History

2025-03-16 14:50:44 +08:00
package hosts
import (
"context"
2025-03-10 13:57:59 +08:00
"net/netip"
2025-02-24 18:17:11 +08:00
"os"
2025-03-16 14:50:44 +08:00
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
2025-02-24 18:17:11 +08:00
"github.com/sagernet/sing/service/filemanager"
2025-03-16 14:50:44 +08:00
mDNS "github.com/miekg/dns"
)
func RegisterTransport(registry *dns.TransportRegistry) {
dns.RegisterTransport[option.HostsDNSServerOptions](registry, C.DNSTypeHosts, NewTransport)
}
var _ adapter.DNSTransport = (*Transport)(nil)
type Transport struct {
dns.TransportAdapter
2025-03-10 13:57:59 +08:00
files []*File
predefined map[string][]netip.Addr
2025-03-16 14:50:44 +08:00
}
func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.HostsDNSServerOptions) (adapter.DNSTransport, error) {
2025-03-10 13:57:59 +08:00
var (
files []*File
predefined = make(map[string][]netip.Addr)
)
2025-03-16 14:50:44 +08:00
if len(options.Path) == 0 {
files = append(files, NewFile(DefaultPath))
} else {
for _, path := range options.Path {
2025-02-24 18:17:11 +08:00
files = append(files, NewFile(filemanager.BasePath(ctx, os.ExpandEnv(path))))
2025-03-16 14:50:44 +08:00
}
}
2025-03-10 13:57:59 +08:00
if options.Predefined != nil {
for _, entry := range options.Predefined.Entries() {
predefined[mDNS.CanonicalName(entry.Key)] = entry.Value
}
}
2025-03-16 14:50:44 +08:00
return &Transport{
TransportAdapter: dns.NewTransportAdapter(C.DNSTypeHosts, tag, nil),
files: files,
2025-03-10 13:57:59 +08:00
predefined: predefined,
2025-03-16 14:50:44 +08:00
}, nil
}
func (t *Transport) Start(stage adapter.StartStage) error {
return nil
}
func (t *Transport) Close() error {
return nil
2025-03-16 14:50:44 +08:00
}
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
question := message.Question[0]
2025-03-10 13:57:59 +08:00
domain := mDNS.CanonicalName(question.Name)
2025-03-16 14:50:44 +08:00
if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
2025-03-10 13:57:59 +08:00
if addresses, ok := t.predefined[domain]; ok {
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
2025-03-16 14:50:44 +08:00
for _, file := range t.files {
addresses := file.Lookup(domain)
if len(addresses) > 0 {
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
}
}
return &mDNS.Msg{
MsgHdr: mDNS.MsgHdr{
Id: message.Id,
Rcode: mDNS.RcodeNameError,
Response: true,
},
Question: []mDNS.Question{question},
}, nil
}