mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-06-05 18:57:30 +03:00
refactor: DNS
This commit is contained in:
83
dns/transport/predefined.go
Normal file
83
dns/transport/predefined.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package transport
|
||||
|
||||
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/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
mDNS "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var _ adapter.DNSTransport = (*PredefinedTransport)(nil)
|
||||
|
||||
func RegisterPredefined(registry *dns.TransportRegistry) {
|
||||
dns.RegisterTransport[option.PredefinedDNSServerOptions](registry, C.DNSTypePreDefined, NewPredefined)
|
||||
}
|
||||
|
||||
type PredefinedTransport struct {
|
||||
dns.TransportAdapter
|
||||
responses []*predefinedResponse
|
||||
}
|
||||
|
||||
type predefinedResponse struct {
|
||||
questions []mDNS.Question
|
||||
answer *mDNS.Msg
|
||||
}
|
||||
|
||||
func NewPredefined(ctx context.Context, logger log.ContextLogger, tag string, options option.PredefinedDNSServerOptions) (adapter.DNSTransport, error) {
|
||||
var responses []*predefinedResponse
|
||||
for _, response := range options.Responses {
|
||||
questions, msg, err := response.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
responses = append(responses, &predefinedResponse{
|
||||
questions: questions,
|
||||
answer: msg,
|
||||
})
|
||||
}
|
||||
if len(responses) == 0 {
|
||||
return nil, E.New("empty predefined responses")
|
||||
}
|
||||
return &PredefinedTransport{
|
||||
TransportAdapter: dns.NewTransportAdapter(C.DNSTypePreDefined, tag, nil),
|
||||
responses: responses,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *PredefinedTransport) Reset() {
|
||||
}
|
||||
|
||||
func (t *PredefinedTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||
for _, response := range t.responses {
|
||||
for _, question := range response.questions {
|
||||
if func() bool {
|
||||
if question.Name == "" && question.Qtype == mDNS.TypeNone {
|
||||
return true
|
||||
} else if question.Name == "" {
|
||||
return common.Any(message.Question, func(it mDNS.Question) bool {
|
||||
return it.Qtype == question.Qtype
|
||||
})
|
||||
} else if question.Qtype == mDNS.TypeNone {
|
||||
return common.Any(message.Question, func(it mDNS.Question) bool {
|
||||
return it.Name == question.Name
|
||||
})
|
||||
} else {
|
||||
return common.Contains(message.Question, question)
|
||||
}
|
||||
}() {
|
||||
copyAnswer := *response.answer
|
||||
copyAnswer.Id = message.Id
|
||||
copyAnswer.Question = message.Question
|
||||
return ©Answer, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, dns.RCodeNameError
|
||||
}
|
||||
Reference in New Issue
Block a user