| 
									
										
										
										
											2016-09-07 11:10:16 +01:00
										 |  |  | package response
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import "github.com/miekg/dns"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-21 17:01:19 +01:00
										 |  |  | // Type is the type of the message
 | 
					
						
							| 
									
										
										
										
											2016-09-07 11:10:16 +01:00
										 |  |  | type Type int
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | const (
 | 
					
						
							| 
									
										
										
										
											2016-09-21 17:01:19 +01:00
										 |  |  | 	// Success indicates a positive reply
 | 
					
						
							|  |  |  | 	Success Type = iota
 | 
					
						
							|  |  |  | 	// NameError is a NXDOMAIN in header, SOA in auth.
 | 
					
						
							|  |  |  | 	NameError
 | 
					
						
							|  |  |  | 	// NoData indicated name found, but not the type: NOERROR in header, SOA in auth.
 | 
					
						
							|  |  |  | 	NoData
 | 
					
						
							|  |  |  | 	// Delegation is a msg with a pointer to another nameserver: NOERROR in header, NS in auth, optionally fluff in additional (not checked).
 | 
					
						
							|  |  |  | 	Delegation
 | 
					
						
							|  |  |  | 	// OtherError indicated any other error: don't cache these.
 | 
					
						
							|  |  |  | 	OtherError
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 08:31:44 +01:00
										 |  |  | func (t Type) String() string {
 | 
					
						
							|  |  |  | 	switch t {
 | 
					
						
							|  |  |  | 	case Success:
 | 
					
						
							|  |  |  | 		return "NOERROR"
 | 
					
						
							|  |  |  | 	case NameError:
 | 
					
						
							|  |  |  | 		return "NXDOMAIN"
 | 
					
						
							|  |  |  | 	case NoData:
 | 
					
						
							|  |  |  | 		return "NODATA"
 | 
					
						
							|  |  |  | 	case Delegation:
 | 
					
						
							|  |  |  | 		return "DELEGATION"
 | 
					
						
							|  |  |  | 	case OtherError:
 | 
					
						
							|  |  |  | 		return "OTHERERROR"
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	return ""
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-07 11:10:16 +01:00
										 |  |  | // Classify classifies a message, it returns the Type.
 | 
					
						
							|  |  |  | func Classify(m *dns.Msg) (Type, *dns.OPT) {
 | 
					
						
							| 
									
										
										
										
											2016-04-26 17:57:11 +01:00
										 |  |  | 	opt := m.IsEdns0()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess {
 | 
					
						
							|  |  |  | 		return Success, opt
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	soa := false
 | 
					
						
							|  |  |  | 	ns := 0
 | 
					
						
							|  |  |  | 	for _, r := range m.Ns {
 | 
					
						
							|  |  |  | 		if r.Header().Rrtype == dns.TypeSOA {
 | 
					
						
							|  |  |  | 			soa = true
 | 
					
						
							|  |  |  | 			continue
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 		if r.Header().Rrtype == dns.TypeNS {
 | 
					
						
							|  |  |  | 			ns++
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check length of different sections, and drop stuff that is just to large? TODO(miek).
 | 
					
						
							|  |  |  | 	if soa && m.Rcode == dns.RcodeSuccess {
 | 
					
						
							|  |  |  | 		return NoData, opt
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	if soa && m.Rcode == dns.RcodeNameError {
 | 
					
						
							|  |  |  | 		return NameError, opt
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ns > 0 && ns == len(m.Ns) && m.Rcode == dns.RcodeSuccess {
 | 
					
						
							|  |  |  | 		return Delegation, opt
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.Rcode == dns.RcodeSuccess {
 | 
					
						
							|  |  |  | 		return Success, opt
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OtherError, opt
 | 
					
						
							|  |  |  | }
 |