| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- //go:build !darwin
- package local
- import (
- "context"
- "github.com/sagernet/sing-box/adapter"
- C "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/dns"
- "github.com/sagernet/sing-box/dns/transport/hosts"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing-box/option"
- E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/logger"
- N "github.com/sagernet/sing/common/network"
- mDNS "github.com/miekg/dns"
- )
- func RegisterTransport(registry *dns.TransportRegistry) {
- dns.RegisterTransport[option.LocalDNSServerOptions](registry, C.DNSTypeLocal, NewTransport)
- }
- var _ adapter.DNSTransport = (*Transport)(nil)
- type Transport struct {
- dns.TransportAdapter
- ctx context.Context
- logger logger.ContextLogger
- hosts *hosts.File
- dialer N.Dialer
- preferGo bool
- resolved ResolvedResolver
- }
- func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.LocalDNSServerOptions) (adapter.DNSTransport, error) {
- transportDialer, err := dns.NewLocalDialer(ctx, options)
- if err != nil {
- return nil, err
- }
- return &Transport{
- TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeLocal, tag, options),
- ctx: ctx,
- logger: logger,
- hosts: hosts.NewFile(hosts.DefaultPath),
- dialer: transportDialer,
- preferGo: options.PreferGo,
- }, nil
- }
- func (t *Transport) Start(stage adapter.StartStage) error {
- switch stage {
- case adapter.StartStateInitialize:
- if !t.preferGo {
- resolvedResolver, err := NewResolvedResolver(t.ctx, t.logger)
- if err == nil {
- err = resolvedResolver.Start()
- if err == nil {
- t.resolved = resolvedResolver
- } else {
- t.logger.Warn(E.Cause(err, "initialize resolved resolver"))
- }
- }
- }
- }
- return nil
- }
- func (t *Transport) Close() error {
- if t.resolved != nil {
- return t.resolved.Close()
- }
- return nil
- }
- func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
- if t.resolved != nil {
- resolverObject := t.resolved.Object()
- if resolverObject != nil {
- return t.resolved.Exchange(resolverObject, ctx, message)
- }
- }
- question := message.Question[0]
- domain := dns.FqdnToDomain(question.Name)
- if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
- addresses := t.hosts.Lookup(domain)
- if len(addresses) > 0 {
- return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
- }
- }
- return t.exchange(ctx, message, domain)
- }
|