@@ -41,11 +41,20 @@ func (q *Question) String() string {
4141// DNSHandler type
4242type DNSHandler struct {
4343 requestChannel chan DNSOperationData
44- resolver * Resolver
44+ resolver dnsResolver
4545 active bool
4646 muActive sync.RWMutex
4747}
4848
49+ type dnsResolver interface {
50+ Lookup (net string , req * dns.Msg , timeout int , interval int , nameServers []string ) (* dns.Msg , error )
51+ }
52+
53+ type questionNameRewrite struct {
54+ original string
55+ forwarded string
56+ }
57+
4958// DNSOperationData type
5059type DNSOperationData struct {
5160 Net string
@@ -55,13 +64,10 @@ type DNSOperationData struct {
5564
5665// NewHandler returns a new DNSHandler
5766func NewHandler (config * Config ) * DNSHandler {
58- var (
59- clientConfig * dns.ClientConfig
60- resolver * Resolver
61- )
62-
63- resolver = & Resolver {clientConfig }
67+ return newHandler (config , & Resolver {})
68+ }
6469
70+ func newHandler (config * Config , resolver dnsResolver ) * DNSHandler {
6571 handler := & DNSHandler {
6672 requestChannel : make (chan DNSOperationData ),
6773 resolver : resolver ,
@@ -92,28 +98,39 @@ func (h *DNSHandler) getTrustDomainSearches(trustDomain, namespace string) []str
9298 return searches
9399}
94100
95- func (h * DNSHandler ) getRawQName (qname , trustDomain string ) (string , string ) {
101+ func (h * DNSHandler ) isClusterServiceQName (qname , trustDomain string ) bool {
102+ prefix , found := strings .CutSuffix (qname , fmt .Sprintf (`.svc.%s.` , trustDomain ))
103+ if ! found {
104+ return false
105+ }
106+ sections := strings .Split (prefix , `.` )
107+ return len (sections ) == 2 && k8sClient .GetK8sNamespace (sections [1 ]) != nil
108+ }
109+
110+ func (h * DNSHandler ) getRawQName (qname , trustDomain string ) (string , string , bool ) {
96111 fromNamespace := `default`
112+ hadSearchSuffix := false
97113 suffixDomains := h .getSuffixDomains (trustDomain )
98114 for _ , suffixDomain := range suffixDomains {
99- if strings .HasSuffix (qname , suffixDomain ) {
100- qname = strings .TrimSuffix (qname , suffixDomain )
115+ if trimmedQName , found := strings .CutSuffix (qname , suffixDomain ); found {
116+ hadSearchSuffix = true
117+ qname = trimmedQName
101118 sections := strings .Split (qname , `.` )
102119 ndots := len (sections )
103120 if ndots > 1 {
104121 fromNamespace = sections [len (sections )- 1 ]
105122 searches := h .getTrustDomainSearches (trustDomain , fromNamespace )
106123 for _ , search := range searches {
107- if strings .HasSuffix (qname , search ) {
108- qname = strings . TrimSuffix ( qname , search )
124+ if trimmedQName , found := strings .CutSuffix (qname , search ); found {
125+ qname = trimmedQName
109126 break
110127 }
111128 }
112129 }
113130 break
114131 }
115132 }
116- return strings .TrimSuffix (qname , `.` ), fromNamespace
133+ return strings .TrimSuffix (qname , `.` ), fromNamespace , hadSearchSuffix
117134}
118135
119136func (h * DNSHandler ) do (cfg * Config ) {
@@ -135,11 +152,15 @@ func (h *DNSHandler) do(cfg *Config) {
135152 remote = w .RemoteAddr ().(* net.UDPAddr ).IP
136153 }
137154
138- var origQuestions []dns.Question
155+ var (
156+ origQuestions []dns.Question
157+ nameRewrites []questionNameRewrite
158+ continueDNSSearch bool
159+ )
139160
140161 for index , q := range req .Question {
141162 origQuestions = append (origQuestions , q )
142- qname , fromNamespace := h .getRawQName (q .Name , trustDomain )
163+ qname , fromNamespace , hadSearchSuffix := h .getRawQName (q .Name , trustDomain )
143164 log .Debug ().Msgf ("%s lookup q.Name:%s qname:%s namespace:%s trustDomain:%s" , remote , q .Name , qname , fromNamespace , trustDomain )
144165
145166 segs := strings .Split (qname , `.` )
@@ -155,6 +176,21 @@ func (h *DNSHandler) do(cfg *Config) {
155176 req .Question [index ].Name = fmt .Sprintf (`%s.` , qname )
156177 }
157178 }
179+ nameRewrites = append (nameRewrites , questionNameRewrite {
180+ original : q .Name ,
181+ forwarded : req .Question [index ].Name ,
182+ })
183+ if hadSearchSuffix && ! h .isClusterServiceQName (q .Name , trustDomain ) {
184+ continueDNSSearch = true
185+ }
186+ }
187+
188+ if continueDNSSearch {
189+ m := new (dns.Msg )
190+ m .SetRcode (req , dns .RcodeNameError )
191+ m .Question = origQuestions
192+ h .WriteReplyMsg (w , m )
193+ return
158194 }
159195
160196 q := req .Question [0 ]
@@ -179,8 +215,6 @@ func (h *DNSHandler) do(cfg *Config) {
179215 h .HandleFailed (w , req )
180216 return
181217 }
182- resp .Question = origQuestions
183-
184218 if resp .Truncated && Net == "udp" {
185219 resp , err = h .resolver .Lookup ("tcp" , req , cfg .GetTimeout (), cfg .GetInterval (), cfg .GetNameservers ())
186220 if err != nil {
@@ -194,25 +228,12 @@ func (h *DNSHandler) do(cfg *Config) {
194228
195229 if resp .Rcode == dns .RcodeNameError && cfg .IsWildcard () {
196230 req .Question = origQuestions
197- h .HandleWildcard (req , cfg , ipQuery , & q , w )
231+ h .HandleWildcard (req , cfg , ipQuery , w )
198232 return
199233 }
200234
201- if len (origQuestions ) > 0 && len (origQuestions ) >= len (resp .Answer ) {
202- for idx , rr := range resp .Answer {
203- header := rr .Header ()
204- switch header .Rrtype {
205- case dns .TypeA :
206- a := rr .(* dns.A )
207- a .Hdr .Name = origQuestions [idx ].Name
208- resp .Answer [idx ] = a
209- case dns .TypeAAAA :
210- aaaa := rr .(* dns.AAAA )
211- aaaa .Hdr .Name = origQuestions [idx ].Name
212- resp .Answer [idx ] = aaaa
213- }
214- }
215- }
235+ resp .Question = origQuestions
236+ restoreAnswerNames (resp .Answer , nameRewrites )
216237
217238 if dbs := cfg .GetWildcardResolveDB (); cfg .IsWildcard () && len (dbs ) > 0 {
218239 los := cfg .GetLoopbackResolveDB ()
@@ -282,9 +303,10 @@ func (h *DNSHandler) HandleFailed(w dns.ResponseWriter, req *dns.Msg) {
282303 h .WriteReplyMsg (w , m )
283304}
284305
285- func (h * DNSHandler ) HandleWildcard (req * dns.Msg , cfg * Config , ipQuery int , q * dns. Question , w dns.ResponseWriter ) {
306+ func (h * DNSHandler ) HandleWildcard (req * dns.Msg , cfg * Config , ipQuery int , w dns.ResponseWriter ) {
286307 m := new (dns.Msg )
287308 m .SetReply (req )
309+ q := req .Question [0 ]
288310
289311 if cfg .GetNXDomain () {
290312 m .SetRcode (req , dns .RcodeNameError )
@@ -326,6 +348,17 @@ func (h *DNSHandler) HandleWildcard(req *dns.Msg, cfg *Config, ipQuery int, q *d
326348 h .WriteReplyMsg (w , m )
327349}
328350
351+ func restoreAnswerNames (answers []dns.RR , rewrites []questionNameRewrite ) {
352+ for _ , rr := range answers {
353+ for _ , rewrite := range rewrites {
354+ if strings .EqualFold (rr .Header ().Name , rewrite .forwarded ) {
355+ rr .Header ().Name = rewrite .original
356+ break
357+ }
358+ }
359+ }
360+ }
361+
329362// WriteReplyMsg writes the dns reply
330363func (h * DNSHandler ) WriteReplyMsg (w dns.ResponseWriter , message * dns.Msg ) {
331364 defer func () {
0 commit comments