mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	middleware/kubernetes: autopath in sub package (#848)
Put the autopath stuff in a separate sub package. Tests are still included in the main kubernetes directory. Next steps (after this is merged), is pulling the autopath handling into the subpackage and fixing the tests.
This commit is contained in:
		
							
								
								
									
										85
									
								
								middleware/kubernetes/autopath/autopath.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								middleware/kubernetes/autopath/autopath.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| package autopath | ||||
|  | ||||
| import "github.com/miekg/dns" | ||||
|  | ||||
| // Writer implements a ResponseWriter that also does the following: | ||||
| // * reverts question section of a packet to its original state. | ||||
| //   This is done to avoid the 'Question section mismatch:' error in client. | ||||
| // * Defers write to the client if the response code is NXDOMAIN.  This is needed | ||||
| //   to enable further search path probing if a search was not successful. | ||||
| // * Allow forced write to client regardless of response code.  This is needed to | ||||
| //   write the packet to the client if the final search in the path fails to | ||||
| //   produce results. | ||||
| // * Overwrites response code with Writer.Rcode if the response code | ||||
| //   is NXDOMAIN (NameError).  This is needed to support the AutoPath.OnNXDOMAIN | ||||
| //   function, which returns a NOERROR to client instead of NXDOMAIN if the final | ||||
| //   search in the path fails to produce results. | ||||
| type Writer struct { | ||||
| 	dns.ResponseWriter | ||||
| 	original dns.Question | ||||
| 	Rcode    int | ||||
| 	Sent     bool | ||||
| } | ||||
|  | ||||
| // AutoPath enables server side search path lookups for pods. | ||||
| type AutoPath struct { | ||||
| 	NDots          int | ||||
| 	ResolvConfFile string | ||||
| 	HostSearchPath []string | ||||
| 	OnNXDOMAIN     int | ||||
| } | ||||
|  | ||||
| // NewWriter returns a pointer to a new Writer | ||||
| func NewWriter(w dns.ResponseWriter, r *dns.Msg) *Writer { | ||||
| 	return &Writer{ | ||||
| 		ResponseWriter: w, | ||||
| 		original:       r.Question[0], | ||||
| 		Rcode:          dns.RcodeSuccess, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // WriteMsg writes to client, unless response will be NXDOMAIN. | ||||
| func (apw *Writer) WriteMsg(res *dns.Msg) error { | ||||
| 	return apw.overrideMsg(res, false) | ||||
| } | ||||
|  | ||||
| // ForceWriteMsg forces the write to client regardless of response code. | ||||
| func (apw *Writer) ForceWriteMsg(res *dns.Msg) error { | ||||
| 	return apw.overrideMsg(res, true) | ||||
| } | ||||
|  | ||||
| // overrideMsg overrides rcode, reverts question, adds CNAME, and calls the | ||||
| // underlying ResponseWriter's WriteMsg method unless the write is deferred, | ||||
| // or force = true. | ||||
| func (apw *Writer) overrideMsg(res *dns.Msg, force bool) error { | ||||
| 	if res.Rcode == dns.RcodeNameError { | ||||
| 		res.Rcode = apw.Rcode | ||||
| 	} | ||||
| 	if res.Rcode != dns.RcodeSuccess && !force { | ||||
| 		return nil | ||||
| 	} | ||||
| 	for _, a := range res.Answer { | ||||
| 		if apw.original.Name == a.Header().Name { | ||||
| 			continue | ||||
| 		} | ||||
| 		res.Answer = append(res.Answer, nil) | ||||
| 		copy(res.Answer[1:], res.Answer) | ||||
| 		res.Answer[0] = CNAME(apw.original.Name, a.Header().Name, a.Header().Ttl) | ||||
| 	} | ||||
| 	res.Question[0] = apw.original | ||||
| 	apw.Sent = true | ||||
| 	return apw.ResponseWriter.WriteMsg(res) | ||||
| } | ||||
|  | ||||
| // Write is a wrapper that records the size of the message that gets written. | ||||
| func (apw *Writer) Write(buf []byte) (int, error) { | ||||
| 	n, err := apw.ResponseWriter.Write(buf) | ||||
| 	return n, err | ||||
| } | ||||
|  | ||||
| // Hijack implements dns.Hijacker. It simply wraps the underlying | ||||
| // ResponseWriter's Hijack method if there is one, or returns an error. | ||||
| func (apw *Writer) Hijack() { | ||||
| 	apw.ResponseWriter.Hijack() | ||||
| 	return | ||||
| } | ||||
		Reference in New Issue
	
	Block a user