diff --git a/dns/router.go b/dns/router.go index bd4eb3f1..42cebd23 100644 --- a/dns/router.go +++ b/dns/router.go @@ -263,20 +263,7 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte return nil, tun.ErrDrop } case *R.RuleActionPredefined: - return &mDNS.Msg{ - MsgHdr: mDNS.MsgHdr{ - Id: message.Id, - Response: true, - Authoritative: true, - RecursionDesired: true, - RecursionAvailable: true, - Rcode: action.Rcode, - }, - Question: message.Question, - Answer: action.Answer, - Ns: action.Ns, - Extra: action.Extra, - }, nil + return action.Response(message), nil } } var responseCheck func(responseAddrs []netip.Addr) bool diff --git a/route/rule/rule_action.go b/route/rule/rule_action.go index fa8594a0..f49baca6 100644 --- a/route/rule/rule_action.go +++ b/route/rule/rule_action.go @@ -444,3 +444,32 @@ func (r *RuleActionPredefined) String() string { options = append(options, common.Map(r.Extra, dns.RR.String)...) return F.ToString("predefined(", strings.Join(options, ","), ")") } + +func (r *RuleActionPredefined) Response(request *dns.Msg) *dns.Msg { + return &dns.Msg{ + MsgHdr: dns.MsgHdr{ + Id: request.Id, + Response: true, + Authoritative: true, + RecursionDesired: true, + RecursionAvailable: true, + Rcode: r.Rcode, + }, + Question: request.Question, + Answer: rewriteRecords(r.Answer, request.Question[0]), + Ns: rewriteRecords(r.Ns, request.Question[0]), + Extra: rewriteRecords(r.Extra, request.Question[0]), + } +} + +func rewriteRecords(records []dns.RR, question dns.Question) []dns.RR { + return common.Map(records, func(it dns.RR) dns.RR { + if strings.HasPrefix(it.Header().Name, "*") { + if strings.HasSuffix(question.Name, it.Header().Name[1:]) { + it = dns.Copy(it) + it.Header().Name = question.Name + } + } + return it + }) +}