func isCacheable(m *dns.Msg) bool {
	// truncated messages aren't valid
	if m.Truncated {
		log.Printf("Refusing to cache truncated message")
		return false
	}

	// if has wrong number of questions, also don't cache
	if len(m.Question) != 1 {
		log.Printf("Refusing to cache message with wrong number of questions")
		return false
	}

	qName := m.Question[0].Name
	qType := m.Question[0].Qtype

	ttl := findLowestTTL(m)
	if ttl == 0 {
		return false
	}

	if m.Rcode != dns.RcodeSuccess && m.Rcode != dns.RcodeNameError {
		log.Printf("%s: refusing to cache message with response type %s", qName, dns.RcodeToString[m.Rcode])
		return false
	}

	if m.Rcode == dns.RcodeSuccess && (qType == dns.TypeA || qType == dns.TypeAAAA) {
		// Now verify that it contains at least one A or AAAA record
		if len(m.Answer) == 0 {
			log.Printf("%s: refusing to cache a NOERROR response with no answers", qName)
			return false
		}

		found := false
		for _, rr := range m.Answer {
			if rr.Header().Rrtype == dns.TypeA || rr.Header().Rrtype == dns.TypeAAAA {
				found = true
				break
			}
		}

		if !found {
			log.Printf("%s: refusing to cache a response with no A and AAAA answers", qName)
			return false
		}
	}

	return true
}
// check if message is cacheable
check if message is cacheable
// check if message is cacheable
func isCacheable(m *dns.Msg) bool {
	if m.Truncated {
		log.Printf("Refusing to cache truncated message")
		return false
	}
	if len(m.Question) != 1 {
		log.Printf("Refusing to cache message with wrong number of questions")
		return false
	}
	qName := m.Question[0].Name
	qType := m.Question[0].Qtype
	ttl := findLowestTTL(m)
	if ttl == 0 {
		return false
	}
	if m.Rcode != dns.RcodeSuccess && m.Rcode != dns.RcodeNameError {
		log.Printf("%s: refusing to cache message with response type %s", qName, dns.RcodeToString[m.Rcode])
		return false
	}
	if m.Rcode == dns.RcodeSuccess && (qType == dns.TypeA || qType == dns.TypeAAAA) {
		if len(m.Answer) == 0 {
			log.Printf("%s: refusing to cache a NOERROR response with no answers", qName)
			return false
		}
		found := false
		for _, rr := range m.Answer {
			if rr.Header().Rrtype == dns.TypeA || rr.Header().Rrtype == dns.TypeAAAA {
				found = true
				break
			}
		}
		if !found {
			log.Printf("%s: refusing to cache a response with no A and AAAA answers", qName)
			return false
		}
	}
	return true
}
func isCacheable ( m * dns . Msg ) bool { if m . Truncated { log . Printf ( " " ) return false } if len ( m . Question ) != 1 { log . Printf ( " " ) return false } qName := m . Question [ 0 ] . Name qType := m . Question [ 0 ] . Qtype ttl := findLowestTTL ( m ) if ttl == 0 { return false } if m . Rcode != dns . RcodeSuccess && m . Rcode != dns . RcodeNameError { log . Printf ( " " , qName , dns . RcodeToString [ m . Rcode ] ) return false } if m . Rcode == dns . RcodeSuccess && ( qType == dns . TypeA || qType == dns . TypeAAAA ) { if len ( m . Answer ) == 0 { log . Printf ( " " , qName ) return false } found := false for _ , rr := range m . Answer { if rr . Header ( ) . Rrtype == dns . TypeA || rr . Header ( ) . Rrtype == dns . TypeAAAA { found = true break } } if ! found { log . Printf ( " " , qName ) return false } } return true }
check if message is cacheable
check if message is cacheable
// truncated messages aren't valid // if has wrong number of questions, also don't cache // Now verify that it contains at least one A or AAAA record